From f375e076e452ca5e3231ed80f42d00fe9a28eb76 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Mon, 13 Aug 2018 17:31:45 +0200 Subject: [PATCH] Implemented BrowserResultMapper --- .../main/java/sonia/scm/web/VndMediaType.java | 1 + .../api/v2/resources/BrowserResultDto.java | 19 +++- .../api/v2/resources/BrowserResultMapper.java | 31 ++++++ ...BrowserResultToBrowserResultDtoMapper.java | 9 -- ...ctDtoMapper.java => FileObjectMapper.java} | 3 +- .../scm/api/v2/resources/MapperModule.java | 2 + .../api/v2/resources/SourceRootResource.java | 16 ++- .../v2/resources/BrowserResultMapperTest.java | 100 ++++++++++++++++++ ...perTest.java => FileObjectMapperTest.java} | 12 +-- 9 files changed, 167 insertions(+), 26 deletions(-) create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultMapper.java delete mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultToBrowserResultDtoMapper.java rename scm-webapp/src/main/java/sonia/scm/api/v2/resources/{FileObjectToFileObjectDtoMapper.java => FileObjectMapper.java} (53%) create mode 100644 scm-webapp/src/test/java/sonia/scm/api/v2/resources/BrowserResultMapperTest.java rename scm-webapp/src/test/java/sonia/scm/api/v2/resources/{FileObjectToFileObjectDtoMapperTest.java => FileObjectMapperTest.java} (85%) diff --git a/scm-core/src/main/java/sonia/scm/web/VndMediaType.java b/scm-core/src/main/java/sonia/scm/web/VndMediaType.java index 1e439a6a16..9dd6b68d36 100644 --- a/scm-core/src/main/java/sonia/scm/web/VndMediaType.java +++ b/scm-core/src/main/java/sonia/scm/web/VndMediaType.java @@ -25,6 +25,7 @@ public class VndMediaType { public static final String REPOSITORY_TYPE_COLLECTION = PREFIX + "repositoryTypeCollection" + SUFFIX; public static final String REPOSITORY_TYPE = PREFIX + "repositoryType" + SUFFIX; public static final String ME = PREFIX + "me" + SUFFIX; + public static final String SOURCE = PREFIX + "source" + SUFFIX; private VndMediaType() { } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultDto.java index b62f5fa124..fe0f98930c 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultDto.java @@ -5,14 +5,27 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import java.util.Collection; +import java.util.Iterator; +import java.util.List; @Getter @Setter @NoArgsConstructor -public class BrowserResultDto extends HalRepresentation { +public class BrowserResultDto extends HalRepresentation implements Iterable { private String revision; private String tag; private String branch; - private Collection files; + private List files; + + @Override + public Iterator iterator() { + Iterator it = null; + + if (files != null) + { + it = files.iterator(); + } + + return it; + } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultMapper.java new file mode 100644 index 0000000000..1690225a72 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultMapper.java @@ -0,0 +1,31 @@ +package sonia.scm.api.v2.resources; + +import org.mapstruct.Mapper; +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.FileObject; + +import java.util.ArrayList; +import java.util.List; + +@Mapper +public abstract class BrowserResultMapper extends BaseMapper { + + abstract FileObjectDto mapFileObject(FileObject fileObject); + + public BrowserResultDto map(BrowserResult browserResult) { + BrowserResultDto browserResultDto = new BrowserResultDto(); + + browserResultDto.setTag(browserResult.getTag()); + browserResultDto.setBranch(browserResult.getBranch()); + browserResultDto.setRevision(browserResult.getRevision()); + + List fileObjectDtoList = new ArrayList<>(); + for (FileObject fileObject : browserResult.getFiles()) { + fileObjectDtoList.add(mapFileObject(fileObject)); + } + + browserResultDto.setFiles(fileObjectDtoList); + + return browserResultDto; + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultToBrowserResultDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultToBrowserResultDtoMapper.java deleted file mode 100644 index ecc59900e5..0000000000 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultToBrowserResultDtoMapper.java +++ /dev/null @@ -1,9 +0,0 @@ -package sonia.scm.api.v2.resources; - -import org.mapstruct.Mapper; -import sonia.scm.repository.BrowserResult; - -@Mapper -public abstract class BrowserResultToBrowserResultDtoMapper extends BaseMapper { - -} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectMapper.java similarity index 53% rename from scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapper.java rename to scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectMapper.java index 86a5e5454b..87abc22380 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectMapper.java @@ -4,6 +4,5 @@ import org.mapstruct.Mapper; import sonia.scm.repository.FileObject; @Mapper -public abstract class FileObjectToFileObjectDtoMapper extends BaseMapper { - +public abstract class FileObjectMapper extends BaseMapper { } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java index 0ac6929689..5247a17ac8 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java @@ -26,6 +26,8 @@ public class MapperModule extends AbstractModule { bind(BranchToBranchDtoMapper.class).to(Mappers.getMapper(BranchToBranchDtoMapper.class).getClass()); + bind(BrowserResultMapper.class).to(Mappers.getMapper(BrowserResultMapper.class).getClass()); + bind(UriInfoStore.class).in(ServletScopes.REQUEST); } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SourceRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SourceRootResource.java index 46d8f02c91..58586768e5 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SourceRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SourceRootResource.java @@ -7,22 +7,31 @@ import sonia.scm.repository.RepositoryNotFoundException; import sonia.scm.repository.api.BrowseCommandBuilder; 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.*; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; import javax.ws.rs.core.Response; import java.io.IOException; public class SourceRootResource { private final RepositoryServiceFactory serviceFactory; + private final BrowserResultMapper browserResultMapper; + + @Inject - public SourceRootResource(RepositoryServiceFactory serviceFactory) { + public SourceRootResource(RepositoryServiceFactory serviceFactory, BrowserResultMapper browserResultMapper) { this.serviceFactory = serviceFactory; + this.browserResultMapper = browserResultMapper; } @GET + @Produces(VndMediaType.SOURCE) @Path("") public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name) { @@ -38,8 +47,7 @@ public class SourceRootResource { } catch (IOException e) { e.printStackTrace(); } - - return Response.ok(browserResult.toString()).build(); + return Response.ok(browserResultMapper.map(browserResult)).build(); } @GET diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BrowserResultMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BrowserResultMapperTest.java new file mode 100644 index 0000000000..c05f93ad7a --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BrowserResultMapperTest.java @@ -0,0 +1,100 @@ +package sonia.scm.api.v2.resources; + +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.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.junit.MockitoJUnitRunner; +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.FileObject; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.MockitoAnnotations.initMocks; + +@RunWith(MockitoJUnitRunner.class) +public class BrowserResultMapperTest { + + @InjectMocks + private BrowserResultMapperImpl mapper; + + private final Subject subject = mock(Subject.class); + private final ThreadState subjectThreadState = new SubjectThreadState(subject); + + + @Before + public void init() { + initMocks(this); + subjectThreadState.bind(); + ThreadContext.bind(subject); + } + + @Test + public void shouldMapAttributesCorrectly() { + BrowserResult browserResult = createBrowserResult(); + + BrowserResultDto dto = mapper.map(browserResult); + + assertEqualAttributes(browserResult, dto); + + assertEqualFileObjectAttributes(browserResult.getFiles().get(0), dto.getFiles().get(0)); + assertEqualFileObjectAttributes(browserResult.getFiles().get(1), dto.getFiles().get(1)); + } + + private BrowserResult createBrowserResult() { + BrowserResult browserResult = new BrowserResult(); + browserResult.setTag("Tag"); + browserResult.setRevision("Revision"); + browserResult.setBranch("Branch"); + browserResult.setFiles(createFileObjects()); + + return browserResult; + } + + private List createFileObjects() { + List fileObjects = new ArrayList<>(); + + FileObject fileObject1 = new FileObject(); + fileObject1.setName("FO 1"); + fileObject1.setLength(100); + fileObject1.setLastModified(0L); + fileObject1.setPath("/path/object/1"); + fileObject1.setDescription("description of file object 1"); + fileObject1.setDirectory(false); + + FileObject fileObject2 = new FileObject(); + fileObject2.setName("FO 2"); + fileObject2.setLength(100); + fileObject2.setLastModified(101L); + fileObject2.setPath("/path/object/2"); + fileObject2.setDescription("description of file object 2"); + fileObject2.setDirectory(true); + + fileObjects.add(fileObject1); + fileObjects.add(fileObject2); + return fileObjects; + } + + private void assertEqualAttributes(BrowserResult browserResult, BrowserResultDto dto) { + assertThat(dto.getTag()).isEqualTo(browserResult.getTag()); + assertThat(dto.getBranch()).isEqualTo(browserResult.getBranch()); + assertThat(dto.getRevision()).isEqualTo(browserResult.getRevision()); + } + + private void assertEqualFileObjectAttributes(FileObject fileObject, FileObjectDto dto) { + assertThat(dto.getName()).isEqualTo(fileObject.getName()); + assertThat(dto.getLength()).isEqualTo(fileObject.getLength()); + assertThat(dto.getLastModified()).isEqualTo(Instant.ofEpochMilli(fileObject.getLastModified())); + assertThat(dto.isDirectory()).isEqualTo(fileObject.isDirectory()); + assertThat(dto.getDescription()).isEqualTo(fileObject.getDescription()); + assertThat(dto.getPath()).isEqualTo(fileObject.getPath()); + } +} diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectMapperTest.java similarity index 85% rename from scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapperTest.java rename to scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectMapperTest.java index 7babd4b329..b06dad6fb2 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapperTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectMapperTest.java @@ -11,26 +11,22 @@ import org.mockito.InjectMocks; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.repository.FileObject; -import java.net.URI; -import java.net.URISyntaxException; - -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.MockitoAnnotations.initMocks; @RunWith(MockitoJUnitRunner.class) -public class FileObjectToFileObjectDtoMapperTest { - private final URI baseUri = URI.create("http://example.com/base/"); +public class FileObjectMapperTest { @InjectMocks - private FileObjectToFileObjectDtoMapperImpl mapper; + private FileObjectMapperImpl mapper; private final Subject subject = mock(Subject.class); private final ThreadState subjectThreadState = new SubjectThreadState(subject); @Before - public void init() throws URISyntaxException { + public void init() { initMocks(this); subjectThreadState.bind(); ThreadContext.bind(subject);