mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 23:15:43 +01:00
add hook events to tag command and update unit tests
This commit is contained in:
@@ -27,8 +27,10 @@ package sonia.scm.repository.spi;
|
|||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
import sonia.scm.event.ScmEventBus;
|
||||||
import sonia.scm.repository.Feature;
|
import sonia.scm.repository.Feature;
|
||||||
import sonia.scm.repository.api.Command;
|
import sonia.scm.repository.api.Command;
|
||||||
|
import sonia.scm.repository.api.HookContextFactory;
|
||||||
import sonia.scm.security.GPG;
|
import sonia.scm.security.GPG;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
@@ -63,13 +65,17 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider
|
|||||||
|
|
||||||
private final GitContext context;
|
private final GitContext context;
|
||||||
private final GPG gpg;
|
private final GPG gpg;
|
||||||
|
private final HookContextFactory hookContextFactory;
|
||||||
|
private final ScmEventBus eventBus;
|
||||||
private final Injector commandInjector;
|
private final Injector commandInjector;
|
||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
//~--- constructors ---------------------------------------------------------
|
||||||
|
|
||||||
GitRepositoryServiceProvider(Injector injector, GitContext context, GPG gpg) {
|
GitRepositoryServiceProvider(Injector injector, GitContext context, GPG gpg, HookContextFactory hookContextFactory, ScmEventBus eventBus) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.gpg = gpg;
|
this.gpg = gpg;
|
||||||
|
this.hookContextFactory = hookContextFactory;
|
||||||
|
this.eventBus = eventBus;
|
||||||
commandInjector = injector.createChildInjector(new AbstractModule() {
|
commandInjector = injector.createChildInjector(new AbstractModule() {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
@@ -150,7 +156,7 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TagCommand getTagCommand() {
|
public TagCommand getTagCommand() {
|
||||||
return new GitTagCommand(context, gpg);
|
return new GitTagCommand(context, gpg, hookContextFactory, eventBus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -28,9 +28,11 @@ package sonia.scm.repository.spi;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
import sonia.scm.event.ScmEventBus;
|
||||||
import sonia.scm.plugin.Extension;
|
import sonia.scm.plugin.Extension;
|
||||||
import sonia.scm.repository.GitRepositoryHandler;
|
import sonia.scm.repository.GitRepositoryHandler;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
|
import sonia.scm.repository.api.HookContextFactory;
|
||||||
import sonia.scm.security.GPG;
|
import sonia.scm.security.GPG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,18 +45,22 @@ public class GitRepositoryServiceResolver implements RepositoryServiceResolver {
|
|||||||
private final Injector injector;
|
private final Injector injector;
|
||||||
private final GitContextFactory contextFactory;
|
private final GitContextFactory contextFactory;
|
||||||
private final GPG gpg;
|
private final GPG gpg;
|
||||||
|
private final HookContextFactory hookContextFactory;
|
||||||
|
private final ScmEventBus scmEventBus;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GitRepositoryServiceResolver(Injector injector, GitContextFactory contextFactory, GPG gpg) {
|
public GitRepositoryServiceResolver(Injector injector, GitContextFactory contextFactory, GPG gpg, HookContextFactory hookContextFactory) {
|
||||||
this.injector = injector;
|
this.injector = injector;
|
||||||
this.contextFactory = contextFactory;
|
this.contextFactory = contextFactory;
|
||||||
this.gpg = gpg;
|
this.gpg = gpg;
|
||||||
|
this.hookContextFactory = hookContextFactory;
|
||||||
|
this.scmEventBus = ScmEventBus.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GitRepositoryServiceProvider resolve(Repository repository) {
|
public GitRepositoryServiceProvider resolve(Repository repository) {
|
||||||
if (GitRepositoryHandler.TYPE_NAME.equalsIgnoreCase(repository.getType())) {
|
if (GitRepositoryHandler.TYPE_NAME.equalsIgnoreCase(repository.getType())) {
|
||||||
return new GitRepositoryServiceProvider(injector, contextFactory.create(repository), gpg);
|
return new GitRepositoryServiceProvider(injector, contextFactory.create(repository), gpg, hookContextFactory, scmEventBus);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,78 +30,93 @@ import org.eclipse.jgit.api.errors.GitAPIException;
|
|||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.PersonIdent;
|
import org.eclipse.jgit.lib.PersonIdent;
|
||||||
import org.eclipse.jgit.lib.Ref;
|
import org.eclipse.jgit.lib.Ref;
|
||||||
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.revwalk.RevObject;
|
import org.eclipse.jgit.revwalk.RevObject;
|
||||||
import org.eclipse.jgit.revwalk.RevTag;
|
|
||||||
import org.eclipse.jgit.revwalk.RevWalk;
|
import org.eclipse.jgit.revwalk.RevWalk;
|
||||||
import org.eclipse.jgit.util.RawParseUtils;
|
import sonia.scm.event.ScmEventBus;
|
||||||
import sonia.scm.repository.GitUtil;
|
import sonia.scm.repository.GitUtil;
|
||||||
import sonia.scm.repository.InternalRepositoryException;
|
import sonia.scm.repository.InternalRepositoryException;
|
||||||
|
import sonia.scm.repository.PostReceiveRepositoryHookEvent;
|
||||||
|
import sonia.scm.repository.PreReceiveRepositoryHookEvent;
|
||||||
|
import sonia.scm.repository.RepositoryHookEvent;
|
||||||
|
import sonia.scm.repository.RepositoryHookType;
|
||||||
import sonia.scm.repository.Signature;
|
import sonia.scm.repository.Signature;
|
||||||
import sonia.scm.repository.SignatureStatus;
|
|
||||||
import sonia.scm.repository.Tag;
|
import sonia.scm.repository.Tag;
|
||||||
import sonia.scm.repository.api.TagDeleteRequest;
|
import sonia.scm.repository.api.HookContext;
|
||||||
|
import sonia.scm.repository.api.HookContextFactory;
|
||||||
|
import sonia.scm.repository.api.HookFeature;
|
||||||
|
import sonia.scm.repository.api.HookTagProvider;
|
||||||
import sonia.scm.repository.api.TagCreateRequest;
|
import sonia.scm.repository.api.TagCreateRequest;
|
||||||
|
import sonia.scm.repository.api.TagDeleteRequest;
|
||||||
import sonia.scm.security.GPG;
|
import sonia.scm.security.GPG;
|
||||||
import sonia.scm.security.PublicKey;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import javax.inject.Inject;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.List;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.singleton;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
|
||||||
public class GitTagCommand extends AbstractGitCommand implements TagCommand {
|
public class GitTagCommand extends AbstractGitCommand implements TagCommand {
|
||||||
private final GPG gpg;
|
private final GPG gpg;
|
||||||
|
private final HookContextFactory hookContextFactory;
|
||||||
|
private final ScmEventBus eventBus;
|
||||||
|
|
||||||
GitTagCommand(GitContext context, GPG gpg) {
|
@Inject
|
||||||
|
GitTagCommand(GitContext context, GPG gpg, HookContextFactory hookContextFactory, ScmEventBus eventBus) {
|
||||||
super(context);
|
super(context);
|
||||||
this.gpg = gpg;
|
this.gpg = gpg;
|
||||||
|
this.hookContextFactory = hookContextFactory;
|
||||||
|
this.eventBus = eventBus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag create(TagCreateRequest request) {
|
public Tag create(TagCreateRequest request) {
|
||||||
try (Git git = new Git(context.open())) {
|
try (Git git = new Git(context.open())) {
|
||||||
Tag tag;
|
|
||||||
String revision = request.getRevision();
|
String revision = request.getRevision();
|
||||||
|
|
||||||
RevObject revObject = null;
|
RevObject revObject;
|
||||||
Long tagTime = null;
|
Long tagTime;
|
||||||
|
|
||||||
if (!Strings.isNullOrEmpty(revision)) {
|
if (Strings.isNullOrEmpty(revision)) {
|
||||||
ObjectId id = git.getRepository().resolve(revision);
|
throw new IllegalArgumentException("Revision is required");
|
||||||
|
|
||||||
try (RevWalk walk = new RevWalk(git.getRepository())) {
|
|
||||||
revObject = walk.parseAny(id);
|
|
||||||
tagTime = GitUtil.getTagTime(walk, id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref ref;
|
ObjectId taggedCommitObjectId = git.getRepository().resolve(revision);
|
||||||
|
|
||||||
if (revObject != null) {
|
try (RevWalk walk = new RevWalk(git.getRepository())) {
|
||||||
ref =
|
revObject = walk.parseAny(taggedCommitObjectId);
|
||||||
git.tag()
|
tagTime = GitUtil.getTagTime(walk, taggedCommitObjectId);
|
||||||
.setObjectId(revObject)
|
}
|
||||||
.setTagger(new PersonIdent("SCM-Manager", "noreply@scm-manager.org"))
|
|
||||||
.setName(request.getName())
|
Tag tag = new Tag(request.getName(), revision, tagTime);
|
||||||
.call();
|
|
||||||
} else {
|
if (revObject == null) {
|
||||||
throw new InternalRepositoryException(repository, "could not create tag because revision does not exist");
|
throw new InternalRepositoryException(repository, "could not create tag because revision does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectId objectId;
|
RepositoryHookEvent hookEvent = createTagHookEvent(TagHookContextProvider.createHookEvent(tag));
|
||||||
if (ref.isPeeled()) {
|
eventBus.post(new PreReceiveRepositoryHookEvent(hookEvent));
|
||||||
objectId = ref.getPeeledObjectId();
|
|
||||||
} else {
|
Ref ref =
|
||||||
objectId = ref.getObjectId();
|
git.tag()
|
||||||
}
|
.setObjectId(revObject)
|
||||||
tag = new Tag(request.getName(), objectId.toString(), tagTime);
|
.setTagger(new PersonIdent("SCM-Manager", "noreply@scm-manager.org"))
|
||||||
|
.setName(request.getName())
|
||||||
|
.call();
|
||||||
|
|
||||||
try (RevWalk walk = new RevWalk(git.getRepository())) {
|
try (RevWalk walk = new RevWalk(git.getRepository())) {
|
||||||
revObject = walk.parseTag(objectId);
|
revObject = walk.parseTag(ref.getObjectId());
|
||||||
tag.addSignature(getTagSignature((RevTag) revObject));
|
final Optional<Signature> tagSignature = GitUtil.getTagSignature(revObject, gpg);
|
||||||
|
tagSignature.ifPresent(tag::addSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventBus.post(new PostReceiveRepositoryHookEvent(hookEvent));
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
} catch (IOException | GitAPIException ex) {
|
} catch (IOException | GitAPIException ex) {
|
||||||
throw new InternalRepositoryException(repository, "could not create tag " + request.getName(), ex);
|
throw new InternalRepositoryException(repository, "could not create tag " + request.getName(), ex);
|
||||||
@@ -111,58 +126,76 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void delete(TagDeleteRequest request) {
|
public void delete(TagDeleteRequest request) {
|
||||||
try (Git git = new Git(context.open())) {
|
try (Git git = new Git(context.open())) {
|
||||||
git.tagDelete().setTags(request.getName()).call();
|
String name = request.getName();
|
||||||
|
final Repository repository = git.getRepository();
|
||||||
|
Ref tagRef = findTagRef(git, name);
|
||||||
|
Tag tag;
|
||||||
|
|
||||||
|
try (RevWalk walk = new RevWalk(repository)) {
|
||||||
|
final RevCommit commit = GitUtil.getCommit(repository, walk, tagRef);
|
||||||
|
Long tagTime = GitUtil.getTagTime(walk, commit.toObjectId());
|
||||||
|
tag = new Tag(name, commit.name(), tagTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
RepositoryHookEvent hookEvent = createTagHookEvent(TagHookContextProvider.deleteHookEvent(tag));
|
||||||
|
eventBus.post(new PreReceiveRepositoryHookEvent(hookEvent));
|
||||||
|
git.tagDelete().setTags(name).call();
|
||||||
|
eventBus.post(new PostReceiveRepositoryHookEvent(hookEvent));
|
||||||
} catch (GitAPIException | IOException e) {
|
} catch (GitAPIException | IOException e) {
|
||||||
throw new InternalRepositoryException(repository, "could not delete tag", e);
|
throw new InternalRepositoryException(repository, "could not delete tag", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final byte[] GPG_HEADER = {'g', 'p', 'g', 's', 'i', 'g'};
|
private Ref findTagRef(Git git, String name) throws GitAPIException {
|
||||||
|
final String tagRef = "refs/tags/" + name;
|
||||||
|
return git.tagList().call().stream().filter(it -> it.getName().equals(tagRef)).findAny().get();
|
||||||
|
}
|
||||||
|
|
||||||
private Signature getTagSignature(RevTag tag) {
|
private RepositoryHookEvent createTagHookEvent(TagHookContextProvider hookEvent) {
|
||||||
byte[] raw = tag.getFullMessage().getBytes();
|
HookContext context = hookContextFactory.createContext(hookEvent, this.context.getRepository());
|
||||||
|
return new RepositoryHookEvent(context, this.context.getRepository(), RepositoryHookType.PRE_RECEIVE);
|
||||||
|
}
|
||||||
|
|
||||||
int start = RawParseUtils.headerStart(GPG_HEADER, raw, 0);
|
private static class TagHookContextProvider extends HookContextProvider {
|
||||||
if (start < 0) {
|
private final List<Tag> newTags;
|
||||||
return null;
|
private final List<Tag> deletedTags;
|
||||||
|
|
||||||
|
private TagHookContextProvider(List<Tag> newTags, List<Tag> deletedTags) {
|
||||||
|
this.newTags = newTags;
|
||||||
|
this.deletedTags = deletedTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
int end = RawParseUtils.headerEnd(raw, start);
|
static TagHookContextProvider createHookEvent(Tag newTag) {
|
||||||
byte[] signature = Arrays.copyOfRange(raw, start, end);
|
return new TagHookContextProvider(singletonList(newTag), emptyList());
|
||||||
|
|
||||||
String publicKeyId = gpg.findPublicKeyId(signature);
|
|
||||||
if (Strings.isNullOrEmpty(publicKeyId)) {
|
|
||||||
// key not found
|
|
||||||
return new Signature(publicKeyId, "gpg", SignatureStatus.NOT_FOUND, null, Collections.emptySet());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<PublicKey> publicKeyById = gpg.findPublicKey(publicKeyId);
|
static TagHookContextProvider deleteHookEvent(Tag deletedTag) {
|
||||||
if (!publicKeyById.isPresent()) {
|
return new TagHookContextProvider(emptyList(), singletonList(deletedTag));
|
||||||
// key not found
|
|
||||||
return new Signature(publicKeyId, "gpg", SignatureStatus.NOT_FOUND, null, Collections.emptySet());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PublicKey publicKey = publicKeyById.get();
|
@Override
|
||||||
|
public Set<HookFeature> getSupportedFeatures() {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
return singleton(HookFeature.BRANCH_PROVIDER);
|
||||||
try {
|
|
||||||
byte[] headerPrefix = Arrays.copyOfRange(raw, 0, start - GPG_HEADER.length - 1);
|
|
||||||
baos.write(headerPrefix);
|
|
||||||
|
|
||||||
byte[] headerSuffix = Arrays.copyOfRange(raw, end + 1, raw.length);
|
|
||||||
baos.write(headerSuffix);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
// this will never happen, because we are writing into memory
|
|
||||||
throw new IllegalStateException("failed to write into memory", ex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean verified = publicKey.verify(baos.toByteArray(), signature);
|
@Override
|
||||||
return new Signature(
|
public HookTagProvider getTagProvider() {
|
||||||
publicKeyId,
|
return new HookTagProvider() {
|
||||||
"gpg",
|
@Override
|
||||||
verified ? SignatureStatus.VERIFIED : SignatureStatus.INVALID,
|
public List<Tag> getCreatedTags() {
|
||||||
publicKey.getOwner().orElse(null),
|
return newTags;
|
||||||
publicKey.getContacts()
|
}
|
||||||
);
|
|
||||||
|
@Override
|
||||||
|
public List<Tag> getDeletedTags() {
|
||||||
|
return deletedTags;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HookChangesetProvider getChangesetProvider() {
|
||||||
|
return r -> new HookChangesetResponse(emptyList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import sonia.scm.event.ScmEventBus;
|
||||||
import sonia.scm.repository.GitRepositoryHandler;
|
import sonia.scm.repository.GitRepositoryHandler;
|
||||||
|
import sonia.scm.repository.api.HookContextFactory;
|
||||||
import sonia.scm.security.GPG;
|
import sonia.scm.security.GPG;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -49,6 +51,12 @@ class GitRepositoryServiceProviderTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private GPG gpg;
|
private GPG gpg;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HookContextFactory hookContextFactory;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ScmEventBus eventBus;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldCreatePushCommand() {
|
void shouldCreatePushCommand() {
|
||||||
GitRepositoryServiceProvider provider = createProvider();
|
GitRepositoryServiceProvider provider = createProvider();
|
||||||
@@ -63,7 +71,7 @@ class GitRepositoryServiceProviderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private GitRepositoryServiceProvider createProvider() {
|
private GitRepositoryServiceProvider createProvider() {
|
||||||
return new GitRepositoryServiceProvider(createParentInjector(), context, gpg);
|
return new GitRepositoryServiceProvider(createParentInjector(), context, gpg, hookContextFactory, eventBus);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Injector createParentInjector() {
|
private Injector createParentInjector() {
|
||||||
|
|||||||
@@ -28,10 +28,17 @@ import org.eclipse.jgit.lib.GpgSigner;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import sonia.scm.event.ScmEventBus;
|
||||||
import sonia.scm.repository.GitTestHelper;
|
import sonia.scm.repository.GitTestHelper;
|
||||||
|
import sonia.scm.repository.PostReceiveRepositoryHookEvent;
|
||||||
|
import sonia.scm.repository.PreReceiveRepositoryHookEvent;
|
||||||
import sonia.scm.repository.Tag;
|
import sonia.scm.repository.Tag;
|
||||||
|
import sonia.scm.repository.api.HookContext;
|
||||||
|
import sonia.scm.repository.api.HookContextFactory;
|
||||||
import sonia.scm.repository.api.TagDeleteRequest;
|
import sonia.scm.repository.api.TagDeleteRequest;
|
||||||
import sonia.scm.repository.api.TagCreateRequest;
|
import sonia.scm.repository.api.TagCreateRequest;
|
||||||
import sonia.scm.security.GPG;
|
import sonia.scm.security.GPG;
|
||||||
@@ -41,6 +48,10 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class GitTagCommandTest extends AbstractGitCommandTestBase {
|
public class GitTagCommandTest extends AbstractGitCommandTestBase {
|
||||||
@@ -48,6 +59,12 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase {
|
|||||||
@Mock
|
@Mock
|
||||||
private GPG gpg;
|
private GPG gpg;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HookContextFactory hookContextFactory;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ScmEventBus eventBus;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setSigner() {
|
public void setSigner() {
|
||||||
GpgSigner.setDefault(new GitTestHelper.SimpleGpgSigner());
|
GpgSigner.setDefault(new GitTestHelper.SimpleGpgSigner());
|
||||||
@@ -60,6 +77,23 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase {
|
|||||||
assertThat(tag).isNotEmpty();
|
assertThat(tag).isNotEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPostCreateEvent() {
|
||||||
|
ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class);
|
||||||
|
doNothing().when(eventBus).post(captor.capture());
|
||||||
|
when(hookContextFactory.createContext(any(), any())).thenAnswer(this::createMockedContext);
|
||||||
|
|
||||||
|
createCommand().create(new TagCreateRequest("592d797cd36432e591416e8b2b98154f4f163411", "newtag"));
|
||||||
|
|
||||||
|
List<Object> events = captor.getAllValues();
|
||||||
|
assertThat(events.get(0)).isInstanceOf(PreReceiveRepositoryHookEvent.class);
|
||||||
|
assertThat(events.get(1)).isInstanceOf(PostReceiveRepositoryHookEvent.class);
|
||||||
|
|
||||||
|
PreReceiveRepositoryHookEvent event = (PreReceiveRepositoryHookEvent) events.get(0);
|
||||||
|
assertThat(event.getContext().getTagProvider().getCreatedTags().get(0).getName()).isEqualTo("newtag");
|
||||||
|
assertThat(event.getContext().getTagProvider().getDeletedTags()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldDeleteATag() throws IOException {
|
public void shouldDeleteATag() throws IOException {
|
||||||
final GitContext context = createContext();
|
final GitContext context = createContext();
|
||||||
@@ -72,8 +106,27 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase {
|
|||||||
assertThat(tag).isEmpty();
|
assertThat(tag).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPostDeleteEvent() {
|
||||||
|
ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class);
|
||||||
|
doNothing().when(eventBus).post(captor.capture());
|
||||||
|
when(hookContextFactory.createContext(any(), any())).thenAnswer(this::createMockedContext);
|
||||||
|
|
||||||
|
createCommand().delete(new TagDeleteRequest("test-tag"));
|
||||||
|
|
||||||
|
List<Object> events = captor.getAllValues();
|
||||||
|
assertThat(events.get(0)).isInstanceOf(PreReceiveRepositoryHookEvent.class);
|
||||||
|
assertThat(events.get(1)).isInstanceOf(PostReceiveRepositoryHookEvent.class);
|
||||||
|
|
||||||
|
PreReceiveRepositoryHookEvent event = (PreReceiveRepositoryHookEvent) events.get(0);
|
||||||
|
assertThat(event.getContext().getTagProvider().getCreatedTags()).isEmpty();
|
||||||
|
final Tag deletedTag = event.getContext().getTagProvider().getDeletedTags().get(0);
|
||||||
|
assertThat(deletedTag.getName()).isEqualTo("test-tag");
|
||||||
|
assertThat(deletedTag.getRevision()).isEqualTo("86a6645eceefe8b9a247db5eb16e3d89a7e6e6d1");
|
||||||
|
}
|
||||||
|
|
||||||
private GitTagCommand createCommand() {
|
private GitTagCommand createCommand() {
|
||||||
return new GitTagCommand(createContext(), gpg);
|
return new GitTagCommand(createContext(), gpg, hookContextFactory, eventBus);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Tag> readTags(GitContext context) throws IOException {
|
private List<Tag> readTags(GitContext context) throws IOException {
|
||||||
@@ -84,4 +137,10 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase {
|
|||||||
List<Tag> branches = readTags(context);
|
List<Tag> branches = readTags(context);
|
||||||
return branches.stream().filter(b -> name.equals(b.getName())).findFirst();
|
return branches.stream().filter(b -> name.equals(b.getName())).findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HookContext createMockedContext(InvocationOnMock invocation) {
|
||||||
|
HookContext mock = mock(HookContext.class);
|
||||||
|
when(mock.getTagProvider()).thenReturn(((HookContextProvider) invocation.getArgument(0)).getTagProvider());
|
||||||
|
return mock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user