diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffResultDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffResultDto.java index 161e7d8a75..17dacdb502 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffResultDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffResultDto.java @@ -3,6 +3,7 @@ package sonia.scm.api.v2.resources; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import de.otto.edison.hal.HalRepresentation; +import de.otto.edison.hal.Links; import lombok.Data; import java.util.List; @@ -10,6 +11,10 @@ import java.util.List; @Data public class DiffResultDto extends HalRepresentation { + public DiffResultDto(Links links) { + super(links); + } + private List files; @Data diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffResultToDiffResultDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffResultToDiffResultDtoMapper.java index 63070eab89..a727134230 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffResultToDiffResultDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffResultToDiffResultDtoMapper.java @@ -3,6 +3,8 @@ package sonia.scm.api.v2.resources; import com.github.sdorra.spotter.ContentTypes; import com.github.sdorra.spotter.Language; import com.google.common.base.Strings; +import com.google.inject.Inject; +import sonia.scm.repository.Repository; import sonia.scm.repository.api.DiffFile; import sonia.scm.repository.api.DiffLine; import sonia.scm.repository.api.DiffResult; @@ -13,24 +15,38 @@ import java.util.List; import java.util.Optional; import java.util.OptionalInt; +import static de.otto.edison.hal.Links.linkingTo; + /** * TODO conflicts, copy and rename */ -final class DiffResultToDiffResultDtoMapper { +class DiffResultToDiffResultDtoMapper { - static final DiffResultToDiffResultDtoMapper INSTANCE = new DiffResultToDiffResultDtoMapper(); + private final ResourceLinks resourceLinks; - private DiffResultToDiffResultDtoMapper() { + @Inject + DiffResultToDiffResultDtoMapper(ResourceLinks resourceLinks) { + this.resourceLinks = resourceLinks; } - public DiffResultDto map(DiffResult result) { + public DiffResultDto mapForIncoming(Repository repository, DiffResult result, String source, String target) { + DiffResultDto dto = new DiffResultDto(linkingTo().self(resourceLinks.incoming().diffParsed(repository.getNamespace(), repository.getName(), source, target)).build()); + setFiles(result, dto); + return dto; + } + + public DiffResultDto mapForRevision(Repository repository, DiffResult result, String revision) { + DiffResultDto dto = new DiffResultDto(linkingTo().self(resourceLinks.diff().parsed(repository.getNamespace(), repository.getName(), revision)).build()); + setFiles(result, dto); + return dto; + } + + private void setFiles(DiffResult result, DiffResultDto dto) { List files = new ArrayList<>(); for (DiffFile file : result) { files.add(mapFile(file)); } - DiffResultDto dto = new DiffResultDto(); dto.setFiles(files); - return dto; } private DiffResultDto.FileDto mapFile(DiffFile file) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffRootResource.java index 8fee14c3f0..14cc7be63f 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffRootResource.java @@ -31,10 +31,12 @@ public class DiffRootResource { static final String DIFF_FORMAT_VALUES_REGEX = "NATIVE|GIT|UNIFIED"; private final RepositoryServiceFactory serviceFactory; + private final DiffResultToDiffResultDtoMapper parsedDiffMapper; @Inject - public DiffRootResource(RepositoryServiceFactory serviceFactory) { + public DiffRootResource(RepositoryServiceFactory serviceFactory, DiffResultToDiffResultDtoMapper parsedDiffMapper) { this.serviceFactory = serviceFactory; + this.parsedDiffMapper = parsedDiffMapper; } @@ -83,11 +85,11 @@ public class DiffRootResource { @ResponseCode(code = 404, condition = "not found, no revision with the specified param for the repository available or repository not found"), @ResponseCode(code = 500, condition = "internal server error") }) - public Response getParsed(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision) throws IOException { + public DiffResultDto getParsed(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision) throws IOException { HttpUtil.checkForCRLFInjection(revision); try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { DiffResult diffResult = repositoryService.getDiffResultCommand().setRevision(revision).getDiffResult(); - return Response.ok(DiffResultToDiffResultDtoMapper.INSTANCE.map(diffResult)).build(); + return parsedDiffMapper.mapForRevision(repositoryService.getRepository(), diffResult, revision); } } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IncomingRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IncomingRootResource.java index bb5b01dd0d..1062e60c90 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IncomingRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IncomingRootResource.java @@ -34,16 +34,16 @@ import static sonia.scm.api.v2.resources.DiffRootResource.HEADER_CONTENT_DISPOSI public class IncomingRootResource { - private final RepositoryServiceFactory serviceFactory; - private final IncomingChangesetCollectionToDtoMapper mapper; - + private final IncomingChangesetCollectionToDtoMapper changesetMapper; + private final DiffResultToDiffResultDtoMapper parsedDiffMapper; @Inject - public IncomingRootResource(RepositoryServiceFactory serviceFactory, IncomingChangesetCollectionToDtoMapper incomingChangesetCollectionToDtoMapper) { + public IncomingRootResource(RepositoryServiceFactory serviceFactory, IncomingChangesetCollectionToDtoMapper incomingChangesetCollectionToDtoMapper, DiffResultToDiffResultDtoMapper parsedDiffMapper) { this.serviceFactory = serviceFactory; - this.mapper = incomingChangesetCollectionToDtoMapper; + this.changesetMapper = incomingChangesetCollectionToDtoMapper; + this.parsedDiffMapper = parsedDiffMapper; } /** @@ -110,7 +110,7 @@ public class IncomingRootResource { .getChangesets(); if (changesets != null && changesets.getChangesets() != null) { PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); - return Response.ok(mapper.map(page, pageSize, pageResult, repository, source, target)).build(); + return Response.ok(changesetMapper.map(page, pageSize, pageResult, repository, source, target)).build(); } else { return Response.ok().build(); } @@ -160,7 +160,7 @@ public class IncomingRootResource { @ResponseCode(code = 400, condition = "Bad Request"), @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), @ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the diff"), - @ResponseCode(code = 404, condition = "not found, no revision with the specified param for the repository available or repository not found"), + @ResponseCode(code = 404, condition = "not found, source or target branch for the repository not available or repository not found"), @ResponseCode(code = 500, condition = "internal server error") }) public Response incomingDiffParsed(@PathParam("namespace") String namespace, @@ -174,7 +174,7 @@ public class IncomingRootResource { .setRevision(source) .setAncestorChangeset(target) .getDiffResult(); - return Response.ok(DiffResultToDiffResultDtoMapper.INSTANCE.map(diffResult)).build(); + return Response.ok(parsedDiffMapper.mapForIncoming(repositoryService.getRepository(), diffResult, source, target)).build(); } } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java index 2aeb5bdced..d00d11eec2 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java @@ -419,7 +419,18 @@ class ResourceLinks { } public String diffParsed(String namespace, String name) { - return toTemplateParams(incomingLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("incoming").parameters().method("incomingDiffParsed").parameters("source", "target").href()); + return toTemplateParams(diffParsed(namespace, name, "source", "target")); + } + + public String diffParsed(String namespace, String name, String source, String target) { + return incomingLinkBuilder + .method("getRepositoryResource") + .parameters(namespace, name) + .method("incoming") + .parameters() + .method("incomingDiffParsed") + .parameters(source, target) + .href(); } public String toTemplateParams(String href) { diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResourceTest.java index f01a20f6c4..e80ad4756d 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResourceTest.java @@ -2,6 +2,7 @@ package sonia.scm.api.v2.resources; import com.google.inject.util.Providers; +import de.otto.edison.hal.Links; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.support.SubjectThreadState; @@ -13,6 +14,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.NotFoundException; @@ -20,6 +22,8 @@ import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.api.DiffCommandBuilder; import sonia.scm.repository.api.DiffFormat; +import sonia.scm.repository.api.DiffResult; +import sonia.scm.repository.api.DiffResultCommandBuilder; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.util.CRLFInjectionException; @@ -34,7 +38,6 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -45,6 +48,7 @@ public class DiffResourceTest extends RepositoryTestBase { public static final String DIFF_PATH = "space/repo/diff/"; public static final String DIFF_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + DIFF_PATH; + public static final Repository REPOSITORY = new Repository("repoId", "git", "space", "repo"); private RestDispatcher dispatcher = new RestDispatcher(); @@ -54,8 +58,13 @@ public class DiffResourceTest extends RepositoryTestBase { @Mock private RepositoryService service; - @Mock + @Mock(answer = Answers.RETURNS_SELF) private DiffCommandBuilder diffCommandBuilder; + @Mock(answer = Answers.RETURNS_SELF) + private DiffResultCommandBuilder diffResultCommandBuilder; + + @Mock + private DiffResultToDiffResultDtoMapper diffResultToDiffResultDtoMapper; private DiffRootResource diffRootResource; @@ -66,15 +75,16 @@ public class DiffResourceTest extends RepositoryTestBase { @Before public void prepareEnvironment() { - diffRootResource = new DiffRootResource(serviceFactory); + diffRootResource = new DiffRootResource(serviceFactory, diffResultToDiffResultDtoMapper); super.diffRootResource = Providers.of(diffRootResource); dispatcher.addSingletonResource(getRepositoryRootResource()); 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.getRepository()).thenReturn(REPOSITORY); ExceptionWithContextToErrorDtoMapperImpl mapper = new ExceptionWithContextToErrorDtoMapperImpl(); dispatcher.registerException(CRLFInjectionException.class, Response.Status.BAD_REQUEST); when(service.getDiffCommand()).thenReturn(diffCommandBuilder); + when(service.getDiffResultCommand()).thenReturn(diffResultCommandBuilder); subjectThreadState.bind(); ThreadContext.bind(subject); when(subject.isPermitted(any(String.class))).thenReturn(true); @@ -87,8 +97,6 @@ public class DiffResourceTest extends RepositoryTestBase { @Test public void shouldGetDiffs() throws Exception { - when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder); - when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder); when(diffCommandBuilder.retrieveContent()).thenReturn(output -> {}); MockHttpRequest request = MockHttpRequest .get(DIFF_URL + "revision") @@ -106,6 +114,25 @@ public class DiffResourceTest extends RepositoryTestBase { .contains(expectedValue); } + @Test + public void shouldGetParsedDiffs() throws Exception { + DiffResult diffResult = mock(DiffResult.class); + when(diffResultCommandBuilder.getDiffResult()).thenReturn(diffResult); + when(diffResultToDiffResultDtoMapper.mapForRevision(REPOSITORY, diffResult, "revision")) + .thenReturn(new DiffResultDto(Links.linkingTo().self("http://self").build())); + MockHttpRequest request = MockHttpRequest + .get(DIFF_URL + "revision/parsed") + .accept(VndMediaType.DIFF_PARSED); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertThat(response.getStatus()) + .isEqualTo(200); + assertThat(response.getContentAsString()) + .contains("\"self\":{\"href\":\"http://self\"}"); + } + @Test public void shouldGet404OnMissingRepository() throws URISyntaxException { when(serviceFactory.create(any(NamespaceAndName.class))).thenThrow(new NotFoundException("Text", "x")); @@ -119,8 +146,6 @@ public class DiffResourceTest extends RepositoryTestBase { @Test public void shouldGet404OnMissingRevision() throws Exception { - when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder); - when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder); when(diffCommandBuilder.retrieveContent()).thenThrow(new NotFoundException("Text", "x")); MockHttpRequest request = MockHttpRequest @@ -135,8 +160,6 @@ public class DiffResourceTest extends RepositoryTestBase { @Test public void shouldGet400OnCrlfInjection() throws Exception { - when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder); - when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder); when(diffCommandBuilder.retrieveContent()).thenThrow(new NotFoundException("Text", "x")); MockHttpRequest request = MockHttpRequest @@ -149,8 +172,6 @@ public class DiffResourceTest extends RepositoryTestBase { @Test public void shouldGet400OnUnknownFormat() throws Exception { - when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder); - when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder); when(diffCommandBuilder.retrieveContent()).thenThrow(new NotFoundException("Test", "test")); MockHttpRequest request = MockHttpRequest @@ -163,8 +184,6 @@ public class DiffResourceTest extends RepositoryTestBase { @Test public void shouldAcceptDiffFormats() throws Exception { - when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder); - when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder); when(diffCommandBuilder.retrieveContent()).thenReturn(output -> {}); Arrays.stream(DiffFormat.values()).map(DiffFormat::name).forEach( diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResultToDiffResultDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResultToDiffResultDtoMapperTest.java index fcfd45dea3..da78d3b652 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResultToDiffResultDtoMapperTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DiffResultToDiffResultDtoMapperTest.java @@ -1,8 +1,10 @@ package sonia.scm.api.v2.resources; +import de.otto.edison.hal.Link; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; +import sonia.scm.repository.Repository; import sonia.scm.repository.api.DiffFile; import sonia.scm.repository.api.DiffLine; import sonia.scm.repository.api.DiffResult; @@ -10,8 +12,10 @@ import sonia.scm.repository.api.Hunk; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.OptionalInt; +import static java.net.URI.create; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -19,21 +23,14 @@ import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class DiffResultToDiffResultDtoMapperTest { + private static final Repository REPOSITORY = new Repository("1", "git", "space", "X"); + + ResourceLinks resourceLinks = ResourceLinksMock.createMock(create("/scm/api/v2")); + DiffResultToDiffResultDtoMapper mapper = new DiffResultToDiffResultDtoMapper(resourceLinks); + @Test void shouldMapDiffResult() { - DiffResult result = result( - addedFile("A.java", "abc"), - modifiedFile("B.ts", "def", "abc", - hunk("@@ -3,4 1,2 @@", 1, 2, 3, 4, - insertedLine("a", 1), - modifiedLine("b", 2), - deletedLine("c", 3) - ) - ), - deletedFile("C.go", "ghi") - ); - - DiffResultDto dto = DiffResultToDiffResultDtoMapper.INSTANCE.map(result); + DiffResultDto dto = mapper.mapForRevision(REPOSITORY, createResult(), "123"); List files = dto.getFiles(); assertAddedFile(files.get(0), "A.java", "abc", "java"); @@ -49,6 +46,44 @@ class DiffResultToDiffResultDtoMapperTest { assertDeletedLine(changes.get(2), "c", 3); } + @Test + void shouldCreateSelfLinkForRevision() { + DiffResultDto dto = mapper.mapForRevision(REPOSITORY, createResult(), "123"); + + Optional selfLink = dto.getLinks().getLinkBy("self"); + assertThat(selfLink) + .isPresent() + .get() + .extracting("href") + .contains("/scm/api/v2/repositories/space/X/diff/123/parsed"); + } + + @Test + void shouldCreateSelfLinkForIncoming() { + DiffResultDto dto = mapper.mapForIncoming(REPOSITORY, createResult(), "feature/some", "master"); + + Optional selfLink = dto.getLinks().getLinkBy("self"); + assertThat(selfLink) + .isPresent() + .get() + .extracting("href") + .contains("/scm/api/v2/repositories/space/X/incoming/feature%2Fsome/master/diff/parsed"); + } + + private DiffResult createResult() { + return result( + addedFile("A.java", "abc"), + modifiedFile("B.ts", "def", "abc", + hunk("@@ -3,4 1,2 @@", 1, 2, 3, 4, + insertedLine("a", 1), + modifiedLine("b", 2), + deletedLine("c", 3) + ) + ), + deletedFile("C.go", "ghi") + ); + } + public void assertInsertedLine(DiffResultDto.ChangeDto change, String content, int lineNumber) { assertThat(change.getContent()).isEqualTo(content); assertThat(change.getLineNumber()).isEqualTo(lineNumber); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/IncomingRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/IncomingRootResourceTest.java index 27a9f0d6a5..f6fa7a3fff 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/IncomingRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/IncomingRootResourceTest.java @@ -2,6 +2,7 @@ package sonia.scm.api.v2.resources; import com.google.inject.util.Providers; +import de.otto.edison.hal.Links; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.support.SubjectThreadState; @@ -24,6 +25,8 @@ import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Person; import sonia.scm.repository.Repository; import sonia.scm.repository.api.DiffCommandBuilder; +import sonia.scm.repository.api.DiffResult; +import sonia.scm.repository.api.DiffResultCommandBuilder; import sonia.scm.repository.api.LogCommandBuilder; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; @@ -45,6 +48,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static sonia.scm.repository.api.DiffFormat.NATIVE; @RunWith(MockitoJUnitRunner.Silent.class) @Slf4j @@ -54,6 +58,7 @@ public class IncomingRootResourceTest extends RepositoryTestBase { public static final String INCOMING_PATH = "space/repo/incoming/"; public static final String INCOMING_CHANGESETS_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + INCOMING_PATH; public static final String INCOMING_DIFF_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + INCOMING_PATH; + public static final Repository REPOSITORY = new Repository("repoId", "git", "space", "repo"); private RestDispatcher dispatcher = new RestDispatcher(); @@ -71,7 +76,11 @@ public class IncomingRootResourceTest extends RepositoryTestBase { @Mock private DiffCommandBuilder diffCommandBuilder; + @Mock + private DiffResultCommandBuilder diffResultCommandBuilder; + @Mock + private DiffResultToDiffResultDtoMapper diffResultToDiffResultDtoMapper; private IncomingChangesetCollectionToDtoMapper incomingChangesetCollectionToDtoMapper; @@ -88,14 +97,15 @@ public class IncomingRootResourceTest extends RepositoryTestBase { @Before public void prepareEnvironment() { incomingChangesetCollectionToDtoMapper = new IncomingChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks); - incomingRootResource = new IncomingRootResource(serviceFactory, incomingChangesetCollectionToDtoMapper); + incomingRootResource = new IncomingRootResource(serviceFactory, incomingChangesetCollectionToDtoMapper, diffResultToDiffResultDtoMapper); super.incomingRootResource = Providers.of(incomingRootResource); dispatcher.addSingletonResource(getRepositoryRootResource()); when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(repositoryService); - when(serviceFactory.create(any(Repository.class))).thenReturn(repositoryService); - when(repositoryService.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo")); + when(serviceFactory.create(REPOSITORY)).thenReturn(repositoryService); + when(repositoryService.getRepository()).thenReturn(REPOSITORY); when(repositoryService.getLogCommand()).thenReturn(logCommandBuilder); when(repositoryService.getDiffCommand()).thenReturn(diffCommandBuilder); + when(repositoryService.getDiffResultCommand()).thenReturn(diffResultCommandBuilder); dispatcher.registerException(CRLFInjectionException.class, Response.Status.BAD_REQUEST); subjectThreadState.bind(); ThreadContext.bind(subject); @@ -170,9 +180,9 @@ public class IncomingRootResourceTest extends RepositoryTestBase { @Test public void shouldGetDiffs() throws Exception { - when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder); - when(diffCommandBuilder.setAncestorChangeset(anyString())).thenReturn(diffCommandBuilder); - when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder); + when(diffCommandBuilder.setRevision("src_changeset_id")).thenReturn(diffCommandBuilder); + when(diffCommandBuilder.setAncestorChangeset("target_changeset_id")).thenReturn(diffCommandBuilder); + when(diffCommandBuilder.setFormat(NATIVE)).thenReturn(diffCommandBuilder); when(diffCommandBuilder.retrieveContent()).thenReturn(output -> {}); MockHttpRequest request = MockHttpRequest .get(INCOMING_DIFF_URL + "src_changeset_id/target_changeset_id/diff") @@ -190,6 +200,28 @@ public class IncomingRootResourceTest extends RepositoryTestBase { .contains(expectedValue); } + @Test + public void shouldGetParsedDiffs() throws Exception { + when(diffResultCommandBuilder.setRevision("src_changeset_id")).thenReturn(diffResultCommandBuilder); + when(diffResultCommandBuilder.setAncestorChangeset("target_changeset_id")).thenReturn(diffResultCommandBuilder); + DiffResult diffResult = mock(DiffResult.class); + when(diffResultCommandBuilder.getDiffResult()).thenReturn(diffResult); + when(diffResultToDiffResultDtoMapper.mapForIncoming(REPOSITORY, diffResult, "src_changeset_id", "target_changeset_id")) + .thenReturn(new DiffResultDto(Links.linkingTo().self("http://self").build())); + + MockHttpRequest request = MockHttpRequest + .get(INCOMING_DIFF_URL + "src_changeset_id/target_changeset_id/diff/parsed") + .accept(VndMediaType.DIFF_PARSED); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertThat(response.getStatus()) + .isEqualTo(200); + assertThat(response.getContentAsString()) + .contains("\"self\":{\"href\":\"http://self\"}"); + } + @Test public void shouldGet404OnMissingRepository() throws URISyntaxException { when(serviceFactory.create(any(NamespaceAndName.class))).thenThrow(new NotFoundException("Text", "x"));