diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java index b06b5b9eba..a521f2b116 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java @@ -3,34 +3,44 @@ package sonia.scm.api.v2.resources; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; +import sonia.scm.PageResult; import sonia.scm.repository.Branches; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryNotFoundException; +import sonia.scm.repository.RepositoryPermissions; import sonia.scm.repository.api.CommandNotSupportedException; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.web.VndMediaType; import javax.inject.Inject; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import java.io.IOException; public class BranchRootResource { - private final RepositoryServiceFactory servicefactory; + private final RepositoryServiceFactory serviceFactory; private final BranchToBranchDtoMapper branchToDtoMapper; private final BranchCollectionToDtoMapper branchCollectionToDtoMapper; + private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + @Inject - public BranchRootResource(RepositoryServiceFactory servicefactory, BranchToBranchDtoMapper branchToDtoMapper, BranchCollectionToDtoMapper branchCollectionToDtoMapper) { - this.servicefactory = servicefactory; + public BranchRootResource(RepositoryServiceFactory serviceFactory, BranchToBranchDtoMapper branchToDtoMapper, BranchCollectionToDtoMapper branchCollectionToDtoMapper, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) { + this.serviceFactory = serviceFactory; this.branchToDtoMapper = branchToDtoMapper; this.branchCollectionToDtoMapper = branchCollectionToDtoMapper; + this.changesetCollectionToDtoMapper = changesetCollectionToDtoMapper; } /** @@ -56,7 +66,7 @@ public class BranchRootResource { @ResponseCode(code = 500, condition = "internal server error") }) public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("branch") String branchName) throws IOException, RepositoryException { - try (RepositoryService repositoryService = servicefactory.create(new NamespaceAndName(namespace, name))) { + try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { Branches branches = repositoryService.getBranchesCommand().getBranches(); return branches.getBranches() .stream() @@ -75,8 +85,34 @@ public class BranchRootResource { @Path("{branch}/changesets/") @GET - public Response history(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("branch") String branchName) { - throw new UnsupportedOperationException(); + @StatusCodes({ + @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), + @ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the changeset"), + @ResponseCode(code = 404, condition = "not found, no changesets available in the repository"), + @ResponseCode(code = 500, condition = "internal server error") + }) + @Produces(VndMediaType.CHANGESET_COLLECTION) + @TypeHint(CollectionDto.class) + public Response history(@PathParam("namespace") String namespace, + @PathParam("name") String name, + @PathParam("branch") String branchName, + @DefaultValue("0") @QueryParam("page") int page, + @DefaultValue("10") @QueryParam("pageSize") int pageSize) throws Exception { + RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name)); + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.read(repository).check(); + ChangesetPagingResult changesets = repositoryService.getLogCommand() + .setPagingStart(page) + .setPagingLimit(pageSize) + .setBranch(branchName) + .getChangesets(); + if (changesets != null && changesets.getChangesets() != null) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); + } else { + return Response.ok().build(); + } } /** @@ -101,7 +137,7 @@ public class BranchRootResource { @ResponseCode(code = 500, condition = "internal server error") }) public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name) throws IOException, RepositoryException { - try (RepositoryService repositoryService = servicefactory.create(new NamespaceAndName(namespace, name))) { + try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { Branches branches = repositoryService.getBranchesCommand().getBranches(); return Response.ok(branchCollectionToDtoMapper.map(namespace, name, branches.getBranches())).build(); } catch (CommandNotSupportedException ex) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java index aa3aa5924b..57194d5851 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java @@ -10,7 +10,7 @@ import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryException; -import sonia.scm.repository.RepositoryNotFoundException; +import sonia.scm.repository.RepositoryPermissions; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.web.VndMediaType; @@ -33,10 +33,13 @@ public class ChangesetRootResource { private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper; + @Inject - public ChangesetRootResource(RepositoryServiceFactory serviceFactory, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) { + public ChangesetRootResource(RepositoryServiceFactory serviceFactory, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper, ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper) { this.serviceFactory = serviceFactory; this.changesetCollectionToDtoMapper = changesetCollectionToDtoMapper; + this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper; } @GET @@ -45,40 +48,52 @@ public class ChangesetRootResource { @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), @ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the changeset"), - @ResponseCode(code = 404, condition = "not found, no changeset with the specified name available in the repository"), + @ResponseCode(code = 404, condition = "not found, no changesets available in the repository"), @ResponseCode(code = 500, condition = "internal server error") }) @Produces(VndMediaType.CHANGESET_COLLECTION) @TypeHint(CollectionDto.class) public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @DefaultValue("0") @QueryParam("page") int page, - @DefaultValue("10") @QueryParam("pageSize") int pageSize) { - try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { - ChangesetPagingResult changesets; - Repository repository = repositoryService.getRepository(); - changesets = repositoryService.getLogCommand() - .setPagingStart(page) - .setPagingLimit(pageSize) - .getChangesets(); - if (changesets != null) { - PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); - return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); - } else { - return Response.ok().build(); - } - } catch (RepositoryNotFoundException e) { - log.debug("Not found in repository {}/{}", namespace, name, e); - return Response.status(Response.Status.NOT_FOUND).build(); - } catch (RepositoryException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + @DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException, RepositoryException { + RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name)); + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.read(repository).check(); + ChangesetPagingResult changesets = repositoryService.getLogCommand() + .setPagingStart(page) + .setPagingLimit(pageSize) + .getChangesets(); + if (changesets != null && changesets.getChangesets() != null) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); + } else { + return Response.ok().build(); } - return Response.ok().build(); } @GET + @StatusCodes({ + @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), + @ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the changeset"), + @ResponseCode(code = 404, condition = "not found, no changeset with the specified id is available in the repository"), + @ResponseCode(code = 500, condition = "internal server error") + }) + @Produces(VndMediaType.CHANGESET) + @TypeHint(ChangesetDto.class) @Path("{id}") - public Response get(@PathParam("id") String id) { - throw new UnsupportedOperationException(); + public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("id") String id) throws RepositoryException, IOException { + RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name)); + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.read(repository).check(); + ChangesetPagingResult changesets = repositoryService.getLogCommand() + .setStartChangeset(id) + .setEndChangeset(id) + .getChangesets(); + if (changesets != null && changesets.getChangesets() != null && changesets.getChangesets().size() == 1) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(changesetToChangesetDtoMapper.map(changesets.getChangesets().get(0), repository)).build(); + } else { + return Response.status(Response.Status.NOT_FOUND).build(); + } } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java index 6ace303b21..c7f0b128df 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java @@ -1,5 +1,11 @@ package sonia.scm.api.v2.resources; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.subject.support.SubjectThreadState; +import org.apache.shiro.util.ThreadContext; +import org.apache.shiro.util.ThreadState; +import org.assertj.core.util.Lists; import org.jboss.resteasy.core.Dispatcher; import org.jboss.resteasy.mock.MockDispatcherFactory; import org.jboss.resteasy.mock.MockHttpRequest; @@ -12,20 +18,35 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.repository.Branch; import sonia.scm.repository.Branches; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Person; +import sonia.scm.repository.Repository; import sonia.scm.repository.api.BranchesCommandBuilder; +import sonia.scm.repository.api.LogCommandBuilder; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; import java.net.URI; +import java.time.Instant; +import java.util.Date; +import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.Silent.class) +@Slf4j public class BranchRootResourceTest { + public static final String BRANCH_PATH = "space/repo/branches/master"; + public static final String BRANCH_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + BRANCH_PATH; private final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher(); private final URI baseUri = URI.create("/"); @@ -38,25 +59,57 @@ public class BranchRootResourceTest { @Mock private BranchesCommandBuilder branchesCommandBuilder; + @Mock + private LogCommandBuilder logCommandBuilder; + @InjectMocks private BranchToBranchDtoMapperImpl branchToDtoMapper; + private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + + private BranchRootResource branchRootResource; + + @Mock + private BranchCollectionToDtoMapper branchCollectionToDtoMapper; + + @Mock + private ChangesetToParentDtoMapper changesetToParentDtoMapper; + + @Mock + private TagCollectionToDtoMapper tagCollectionToDtoMapper; + + + @InjectMocks + private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper; + + private final Subject subject = mock(Subject.class); + private final ThreadState subjectThreadState = new SubjectThreadState(subject); + + @Before public void prepareEnvironment() throws Exception { + changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks); BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks); - BranchRootResource branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper); + branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper, changesetCollectionToDtoMapper); RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(new RepositoryResource(null, null, null, null, MockProvider.of(branchRootResource), null, null, null, null, null)), null); dispatcher.getRegistry().addSingletonResource(repositoryRootResource); when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service); + when(serviceFactory.create(any(Repository.class))).thenReturn(service); + when(service.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo")); + when(service.getBranchesCommand()).thenReturn(branchesCommandBuilder); + when(service.getLogCommand()).thenReturn(logCommandBuilder); + subjectThreadState.bind(); + ThreadContext.bind(subject); + when(subject.isPermitted(any(String.class))).thenReturn(true); } @Test public void shouldHandleMissingBranch() throws Exception { when(branchesCommandBuilder.getBranches()).thenReturn(new Branches()); - MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/branches/master"); + MockHttpRequest request = MockHttpRequest.get(BRANCH_URL); MockHttpResponse response = new MockHttpResponse(); dispatcher.invoke(request, response); @@ -68,13 +121,40 @@ public class BranchRootResourceTest { public void shouldFindExistingBranch() throws Exception { when(branchesCommandBuilder.getBranches()).thenReturn(new Branches(new Branch("master", "revision"))); - MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/branches/master"); + MockHttpRequest request = MockHttpRequest.get(BRANCH_URL); MockHttpResponse response = new MockHttpResponse(); dispatcher.invoke(request, response); assertEquals(200, response.getStatus()); - System.out.println(response.getContentAsString()); + log.info("Response :{}", response.getContentAsString()); assertTrue(response.getContentAsString().contains("\"revision\":\"revision\"")); } + + @Test + public void shouldFindHistory() throws Exception { + String id = "revision_123"; + Instant creationDate = Instant.now(); + String authorName = "name"; + String authorEmail = "em@i.l"; + String commit = "my branch commit"; + ChangesetPagingResult changesetPagingResult = mock(ChangesetPagingResult.class); + List changesetList = Lists.newArrayList(new Changeset(id, Date.from(creationDate).getTime(), new Person(authorName, authorEmail), commit)); + when(changesetPagingResult.getChangesets()).thenReturn(changesetList); + when(changesetPagingResult.getTotal()).thenReturn(1); + when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setBranch(anyString())).thenReturn(logCommandBuilder); + when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult); + MockHttpRequest request = MockHttpRequest.get(BRANCH_URL + "/changesets/"); + MockHttpResponse response = new MockHttpResponse(); + dispatcher.invoke(request, response); + assertEquals(200, response.getStatus()); + log.info("Response :{}", response.getContentAsString()); + assertTrue(response.getContentAsString().contains(String.format("\"id\":\"%s\"", id))); + assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName))); + assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java new file mode 100644 index 0000000000..4e7215c8eb --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java @@ -0,0 +1,165 @@ +package sonia.scm.api.v2.resources; + + +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.subject.support.SubjectThreadState; +import org.apache.shiro.util.ThreadContext; +import org.apache.shiro.util.ThreadState; +import org.assertj.core.util.Lists; +import org.jboss.resteasy.core.Dispatcher; +import org.jboss.resteasy.mock.MockDispatcherFactory; +import org.jboss.resteasy.mock.MockHttpRequest; +import org.jboss.resteasy.mock.MockHttpResponse; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import sonia.scm.api.rest.AuthorizationExceptionMapper; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Person; +import sonia.scm.repository.Repository; +import sonia.scm.repository.api.LogCommandBuilder; +import sonia.scm.repository.api.RepositoryService; +import sonia.scm.repository.api.RepositoryServiceFactory; +import sonia.scm.web.VndMediaType; + +import java.net.URI; +import java.time.Instant; +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.Silent.class) +@Slf4j +public class ChangesetRootResourceTest { + + + public static final String CHANGESET_PATH = "space/repo/changesets/"; + public static final String CHANGESET_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + CHANGESET_PATH; + private final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher(); + + private final URI baseUri = URI.create("/"); + private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri); + + @Mock + private RepositoryServiceFactory serviceFactory; + + @Mock + private RepositoryService service; + + @Mock + private LogCommandBuilder logCommandBuilder; + + private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + + @Mock + private BranchCollectionToDtoMapper branchCollectionToDtoMapper; + + @Mock + private ChangesetToParentDtoMapperImpl changesetToParentDtoMapper; + + @Mock + private TagCollectionToDtoMapper tagCollectionToDtoMapper; + + + @InjectMocks + private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper; + + private ChangesetRootResource changesetRootResource; + + + private final Subject subject = mock(Subject.class); + private final ThreadState subjectThreadState = new SubjectThreadState(subject); + + + @Before + public void prepareEnvironment() throws Exception { + changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks); + changesetRootResource = new ChangesetRootResource(serviceFactory, changesetCollectionToDtoMapper, changesetToChangesetDtoMapper); + RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider + .of(new RepositoryResource(null, null, null, null, null, + MockProvider.of(changesetRootResource), null, null, null, null)), null); + dispatcher.getRegistry().addSingletonResource(repositoryRootResource); + when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service); + when(serviceFactory.create(any(Repository.class))).thenReturn(service); + when(service.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo")); + dispatcher.getProviderFactory().registerProvider(RepositoryNotFoundExceptionMapper.class); + dispatcher.getProviderFactory().registerProvider(AuthorizationExceptionMapper.class); + when(service.getLogCommand()).thenReturn(logCommandBuilder); + subjectThreadState.bind(); + ThreadContext.bind(subject); + when(subject.isPermitted(any(String.class))).thenReturn(true); + } + + @Test + public void shouldGetChangeSets() throws Exception { + String id = "revision_123"; + Instant creationDate = Instant.now(); + String authorName = "name"; + String authorEmail = "em@i.l"; + String commit = "my branch commit"; + ChangesetPagingResult changesetPagingResult = mock(ChangesetPagingResult.class); + List changesetList = Lists.newArrayList(new Changeset(id, Date.from(creationDate).getTime(), new Person(authorName, authorEmail), commit)); + when(changesetPagingResult.getChangesets()).thenReturn(changesetList); + when(changesetPagingResult.getTotal()).thenReturn(1); + when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setBranch(anyString())).thenReturn(logCommandBuilder); + when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult); + MockHttpRequest request = MockHttpRequest + .get(CHANGESET_URL) + .accept(VndMediaType.CHANGESET_COLLECTION); + MockHttpResponse response = new MockHttpResponse(); + dispatcher.invoke(request, response); + assertEquals(200, response.getStatus()); + log.info("Response :{}", response.getContentAsString()); + assertTrue(response.getContentAsString().contains(String.format("\"id\":\"%s\"", id))); + assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName))); + assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + } + + @Test + public void shouldGetChangeSet() throws Exception { + String id = "revision_123"; + Instant creationDate = Instant.now(); + String authorName = "name"; + String authorEmail = "em@i.l"; + String commit = "my branch commit"; + ChangesetPagingResult changesetPagingResult = mock(ChangesetPagingResult.class); + List changesetList = Lists.newArrayList(new Changeset(id, Date.from(creationDate).getTime(), new Person(authorName, authorEmail), commit)); + when(changesetPagingResult.getChangesets()).thenReturn(changesetList); + when(changesetPagingResult.getTotal()).thenReturn(1); + when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setEndChangeset(anyString())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setStartChangeset(anyString())).thenReturn(logCommandBuilder); + when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult); + MockHttpRequest request = MockHttpRequest + .get(CHANGESET_URL + "id") + .accept(VndMediaType.CHANGESET); + MockHttpResponse response = new MockHttpResponse(); + dispatcher.invoke(request, response); + assertEquals(200, response.getStatus()); + log.info("Response :{}", response.getContentAsString()); + assertTrue(response.getContentAsString().contains(String.format("\"id\":\"%s\"", id))); + assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName))); + assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + } + +} diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java index 6be360c585..ff729a6478 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java @@ -26,6 +26,7 @@ public class ResourceLinksMock { when(resourceLinks.permission()).thenReturn(new ResourceLinks.PermissionLinks(uriInfo)); when(resourceLinks.config()).thenReturn(new ResourceLinks.ConfigLinks(uriInfo)); when(resourceLinks.branch()).thenReturn(new ResourceLinks.BranchLinks(uriInfo)); + when(resourceLinks.diff()).thenReturn(new ResourceLinks.DiffLinks(uriInfo)); when(resourceLinks.repositoryType()).thenReturn(new ResourceLinks.RepositoryTypeLinks(uriInfo)); when(resourceLinks.repositoryTypeCollection()).thenReturn(new ResourceLinks.RepositoryTypeCollectionLinks(uriInfo));