From 1d7d4d77e28fc9d41770799a2f18830388bdaddd Mon Sep 17 00:00:00 2001
From: OZGCloud <ozgcloud@mgm-tp.com>
Date: Fri, 16 Apr 2021 10:03:38 +0200
Subject: [PATCH] OZG-530 -> OZG-555 impl Attachment/Represenation Controller;
 put links on Vorgang

---
 .../attachment/AttachmentController.java      |  24 ++++
 .../RepresentationController.java             |  24 ++++
 .../goofy/vorgang/VorgangModelAssembler.java  |  23 ++++
 .../attachment/AttachmentControllerTest.java  |  39 +++++++
 .../RepresentationControllerTest.java         |  39 +++++++
 .../goofy/vorgang/EingangTestFactory.java     |   2 +-
 .../vorgang/VorgangModelAssemblerTest.java    | 103 ++++++++++++------
 7 files changed, 221 insertions(+), 33 deletions(-)
 create mode 100644 goofy-server/src/main/java/de/itvsh/goofy/attachment/AttachmentController.java
 create mode 100644 goofy-server/src/main/java/de/itvsh/goofy/representation/RepresentationController.java
 create mode 100644 goofy-server/src/test/java/de/itvsh/goofy/attachment/AttachmentControllerTest.java
 create mode 100644 goofy-server/src/test/java/de/itvsh/goofy/representation/RepresentationControllerTest.java

diff --git a/goofy-server/src/main/java/de/itvsh/goofy/attachment/AttachmentController.java b/goofy-server/src/main/java/de/itvsh/goofy/attachment/AttachmentController.java
new file mode 100644
index 0000000000..61a2148374
--- /dev/null
+++ b/goofy-server/src/main/java/de/itvsh/goofy/attachment/AttachmentController.java
@@ -0,0 +1,24 @@
+package de.itvsh.goofy.attachment;
+
+import org.springframework.hateoas.CollectionModel;
+import org.springframework.hateoas.EntityModel;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import de.itvsh.goofy.file.File;
+
+@RestController
+@RequestMapping(AttachmentController.ATTACHMENT_PATH)
+public class AttachmentController {
+
+	static final String ATTACHMENT_PATH = "/api/attachments"; // NOSONAR
+
+	static final String PARAM_EINGANG_ID = "eingangId";
+
+	@GetMapping(params = PARAM_EINGANG_ID)
+	public CollectionModel<EntityModel<File>> getAllByEingang(@RequestParam String eingangId) {
+		return CollectionModel.empty();
+	}
+}
\ No newline at end of file
diff --git a/goofy-server/src/main/java/de/itvsh/goofy/representation/RepresentationController.java b/goofy-server/src/main/java/de/itvsh/goofy/representation/RepresentationController.java
new file mode 100644
index 0000000000..abd2f2a68b
--- /dev/null
+++ b/goofy-server/src/main/java/de/itvsh/goofy/representation/RepresentationController.java
@@ -0,0 +1,24 @@
+package de.itvsh.goofy.representation;
+
+import org.springframework.hateoas.CollectionModel;
+import org.springframework.hateoas.EntityModel;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import de.itvsh.goofy.file.File;
+
+@RestController
+@RequestMapping(RepresentationController.REPRESENTATIONS_PATH)
+public class RepresentationController {
+
+	static final String REPRESENTATIONS_PATH = "/api/representations"; // NOSONAR
+
+	static final String PARAM_EINGANG_ID = "eingangId";
+
+	@GetMapping(params = PARAM_EINGANG_ID)
+	public CollectionModel<EntityModel<File>> getAllByEingang(@RequestParam String eingangId) {
+		return CollectionModel.empty();
+	}
+}
diff --git a/goofy-server/src/main/java/de/itvsh/goofy/vorgang/VorgangModelAssembler.java b/goofy-server/src/main/java/de/itvsh/goofy/vorgang/VorgangModelAssembler.java
index 7282865f80..910d304d01 100644
--- a/goofy-server/src/main/java/de/itvsh/goofy/vorgang/VorgangModelAssembler.java
+++ b/goofy-server/src/main/java/de/itvsh/goofy/vorgang/VorgangModelAssembler.java
@@ -2,6 +2,7 @@ package de.itvsh.goofy.vorgang;
 
 import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
 
+import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -12,8 +13,10 @@ import org.springframework.hateoas.EntityModel;
 import org.springframework.hateoas.server.RepresentationModelAssembler;
 import org.springframework.stereotype.Component;
 
+import de.itvsh.goofy.attachment.AttachmentController;
 import de.itvsh.goofy.common.ResourceBuilder;
 import de.itvsh.goofy.common.command.CommandController;
+import de.itvsh.goofy.representation.RepresentationController;
 import de.itvsh.goofy.wiedervorlage.WiedervorlageCommandController.WiedervorlageCommandByVorgangController;
 import de.itvsh.goofy.wiedervorlage.WiedervorlageController.WiedervorlageByVorgangController;
 
@@ -30,6 +33,8 @@ class VorgangModelAssembler implements RepresentationModelAssembler<Vorgang, Ent
 	public static final String REL_CREATE_WIEDERVORLAGE = "create-wiedervorlage";
 
 	public static final String REL_PENDING_COMMANDS = "pending-commands";
+	public static final String REL_ATTACHMENTS = "attachments";
+	public static final String REL_REPRESENTATIONS = "representations";
 
 	@Override
 	public EntityModel<Vorgang> toModel(Vorgang vorgang) {
@@ -42,9 +47,18 @@ class VorgangModelAssembler implements RepresentationModelAssembler<Vorgang, Ent
 						.withRel(REL_CREATE_WIEDERVORLAGE))
 				.ifMatch(this::existsPendingCommands)
 				.addLink(() -> linkTo(methodOn(CommandController.class).getPendingCommands(true, vorgang.getId())).withRel(REL_PENDING_COMMANDS))
+				.ifMatch(this::existsEingang)
+				.addLinks(
+						() -> linkTo(methodOn(AttachmentController.class).getAllByEingang(getEingangId(vorgang))).withRel(REL_ATTACHMENTS),
+						() -> linkTo(methodOn(RepresentationController.class).getAllByEingang(getEingangId(vorgang)))
+								.withRel(REL_REPRESENTATIONS))
 				.buildResource();
 	}
 
+	private String getEingangId(Vorgang vorgang) {
+		return ((VorgangWithEingang) vorgang).getEingang().getId();
+	}
+
 	public CollectionModel<EntityModel<Vorgang>> toCollectionModel(Stream<Vorgang> entities, Optional<Integer> prevPage,
 			Optional<Integer> nextPage) {
 		var model = CollectionModel.of(entities.map(this::toModel).collect(Collectors.toList()),
@@ -59,4 +73,13 @@ class VorgangModelAssembler implements RepresentationModelAssembler<Vorgang, Ent
 	private boolean existsPendingCommands(Vorgang vorgang) {
 		return commandController.existsPendingCommands(vorgang.getId());
 	}
+
+	private boolean existsEingang(Vorgang vorgang) {
+		if (vorgang instanceof VorgangWithEingang) {
+			var withEingang = (VorgangWithEingang) vorgang;
+
+			return !Objects.isNull(withEingang.getEingang());
+		}
+		return false;
+	}
 }
diff --git a/goofy-server/src/test/java/de/itvsh/goofy/attachment/AttachmentControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/attachment/AttachmentControllerTest.java
new file mode 100644
index 0000000000..fec2cbc008
--- /dev/null
+++ b/goofy-server/src/test/java/de/itvsh/goofy/attachment/AttachmentControllerTest.java
@@ -0,0 +1,39 @@
+package de.itvsh.goofy.attachment;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+class AttachmentControllerTest {
+
+	private final String PATH = AttachmentController.ATTACHMENT_PATH;
+
+	@InjectMocks
+	private AttachmentController controller;
+
+	private MockMvc mockMvc;
+
+	@BeforeEach
+	void initTest() {
+		mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
+	}
+
+	@Nested
+	class TestGetAttachmentsByEingang {
+
+		@Test
+		void shouldCallEndpoint() throws Exception {
+			callEndpoint();
+		}
+
+		private void callEndpoint() throws Exception {
+			mockMvc.perform(get(PATH).param(AttachmentController.PARAM_EINGANG_ID, "1")).andExpect(status().isOk());
+		}
+	}
+}
\ No newline at end of file
diff --git a/goofy-server/src/test/java/de/itvsh/goofy/representation/RepresentationControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/representation/RepresentationControllerTest.java
new file mode 100644
index 0000000000..fd3761252d
--- /dev/null
+++ b/goofy-server/src/test/java/de/itvsh/goofy/representation/RepresentationControllerTest.java
@@ -0,0 +1,39 @@
+package de.itvsh.goofy.representation;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+class RepresentationControllerTest {
+
+	private final String PATH = RepresentationController.REPRESENTATIONS_PATH;
+
+	@InjectMocks
+	private RepresentationController controller;
+
+	private MockMvc mockMvc;
+
+	@BeforeEach
+	void init() {
+		mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
+	}
+
+	@Nested
+	class TestGetRepresentationsByEingang {
+
+		@Test
+		void shouldCallEndpoint() throws Exception {
+			callEndpoint();
+		}
+
+		private void callEndpoint() throws Exception {
+			mockMvc.perform(get(PATH).param(RepresentationController.PARAM_EINGANG_ID, "1")).andExpect(status().isOk());
+		}
+	}
+}
\ No newline at end of file
diff --git a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/EingangTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/EingangTestFactory.java
index d1d852caa9..d37066f692 100644
--- a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/EingangTestFactory.java
+++ b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/EingangTestFactory.java
@@ -5,7 +5,7 @@ import java.util.UUID;
 
 public class EingangTestFactory {
 
-	private static final String ID = UUID.randomUUID().toString();
+	public static final String ID = UUID.randomUUID().toString();
 
 	public static final String SINGLE_FIELD_NAME = "name";
 	public static final String SINGLE_FIELD_VALUE = "Thea";
diff --git a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/VorgangModelAssemblerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/VorgangModelAssemblerTest.java
index ef8da589c8..e2eec46936 100644
--- a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/VorgangModelAssemblerTest.java
+++ b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/VorgangModelAssemblerTest.java
@@ -7,16 +7,18 @@ import static org.mockito.Mockito.*;
 import java.util.Optional;
 import java.util.stream.Stream;
 
+import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.springframework.hateoas.CollectionModel;
 import org.springframework.hateoas.EntityModel;
-import org.springframework.hateoas.IanaLinkRelations;
+import org.springframework.hateoas.Link;
 import org.springframework.hateoas.server.EntityLinks;
 
 import de.itvsh.goofy.common.command.CommandController;
+import io.grpc.netty.shaded.io.netty.util.internal.StringUtil;
 
 class VorgangModelAssemblerTest {
 
@@ -43,43 +45,34 @@ class VorgangModelAssemblerTest {
 
 		@Test
 		void shouldHaveSelfLink() {
-			EntityModel<Vorgang> entityModel = modelAssembler.toModel(VorgangHeaderTestFactory.create());
-
-			var link = entityModel.getLink(IanaLinkRelations.SELF);
-
-			assertThat(link).isPresent();
-			assertThat(link.get().getHref()).isEqualTo(BASE_PATH + VorgangHeaderTestFactory.ID);
+			verifyModelLinkRelation(VorgangModelAssembler.REL_VORGANG_MIT_EINGANG);
 		}
 
 		@Test
 		void shouldHaveVorgangMitEingangLink() {
-			EntityModel<Vorgang> entityModel = modelAssembler.toModel(VorgangHeaderTestFactory.create());
-
-			var link = entityModel.getLink(VorgangModelAssembler.REL_VORGANG_MIT_EINGANG);
-
-			assertThat(link).isPresent();
-			assertThat(link.get().getHref()).isEqualTo(BASE_PATH + VorgangHeaderTestFactory.ID);
+			verifyModelLinkRelation(VorgangModelAssembler.REL_VORGANG_MIT_EINGANG);
 		}
 
 		@Test
 		void shouldHaveWiedervorlagenLink() {
-			EntityModel<Vorgang> entityModel = modelAssembler.toModel(VorgangHeaderTestFactory.create());
-
-			var link = entityModel.getLink(VorgangModelAssembler.REL_WIEDERVORLAGEN);
-
-			assertThat(link).isPresent();
-			assertThat(link.get().getHref()).isEqualTo(BASE_PATH + VorgangHeaderTestFactory.ID + "/wiedervorlages");
+			verifyModelLinkRelation(VorgangModelAssembler.REL_WIEDERVORLAGEN, "/wiedervorlages");
 		}
 
 		@Test
 		void shouldHaveCreateWiedervorlageLink() {
-			EntityModel<Vorgang> entityModel = modelAssembler.toModel(VorgangHeaderTestFactory.create());
+			verifyModelLinkRelation(VorgangModelAssembler.REL_CREATE_WIEDERVORLAGE, "/wiedervorlageCommands");
+		}
 
-			var link = entityModel.getLink(VorgangModelAssembler.REL_CREATE_WIEDERVORLAGE);
+		private void verifyModelLinkRelation(String linkRel) {
+			verifyModelLinkRelation(linkRel, StringUtil.EMPTY_STRING);
+		}
+
+		private void verifyModelLinkRelation(String linkRel, String additionalPathValue) {
+			verifyLinkExistOnModel(VorgangHeaderTestFactory.create(), linkRel, buildLinkPath(additionalPathValue));
+		}
 
-			assertThat(link).isPresent();
-			assertThat(link.get().getHref())
-					.isEqualTo("/api/vorgangs/" + VorgangHeaderTestFactory.ID + "/wiedervorlageCommands");
+		private String buildLinkPath(String additionalPathValue) {
+			return BASE_PATH + VorgangHeaderTestFactory.ID + additionalPathValue;
 		}
 	}
 
@@ -90,23 +83,69 @@ class VorgangModelAssemblerTest {
 		void shouldExists() {
 			when(commandController.existsPendingCommands(any())).thenReturn(true);
 
-			EntityModel<Vorgang> entityModel = modelAssembler.toModel(VorgangHeaderTestFactory.create());
+			String expectedHref = "/api/commands?pending=true&vorgangId=" + VorgangHeaderTestFactory.ID;
 
-			var link = entityModel.getLink(VorgangModelAssembler.REL_PENDING_COMMANDS);
-
-			assertThat(link).isPresent();
-			assertThat(link.get().getHref()).isEqualTo("/api/commands?pending=true&vorgangId=" + VorgangHeaderTestFactory.ID);
+			verifyLinkExistOnModel(VorgangMitEingangTestFactory.create(), VorgangModelAssembler.REL_PENDING_COMMANDS, expectedHref);
 		}
 
 		@Test
 		void shouldNotExists() {
 			when(commandController.existsPendingCommands(any())).thenReturn(false);
 
-			EntityModel<Vorgang> entityModel = modelAssembler.toModel(VorgangHeaderTestFactory.create());
+			verifyLinkNotExistsOnModel(VorgangHeaderTestFactory.create(), VorgangModelAssembler.REL_PENDING_COMMANDS);
+		}
+	}
+
+	@Nested
+	class TestAttachmentLink {
+
+		@DisplayName("Attachment Link should exists if vorgang has an eingang")
+		@Test
+		void shouldExistsAttachmentLinks() {
+			String expectedHref = "/api/attachments?eingangId=" + EingangTestFactory.ID;
 
-			var link = entityModel.getLink(VorgangModelAssembler.REL_PENDING_COMMANDS);
+			verifyLinkExistOnModel(VorgangMitEingangTestFactory.create(), VorgangModelAssembler.REL_ATTACHMENTS, expectedHref);
+		}
 
-			assertThat(link).isNotPresent();
+		@DisplayName("Attachment Link should NOT exists if vorgang has no eingang")
+		@Test
+		void shouldNotExists() {
+			verifyLinkNotExistsOnModel(VorgangHeaderTestFactory.create(), VorgangModelAssembler.REL_ATTACHMENTS);
 		}
 	}
+
+	@Nested
+	class TestRepresentationLink {
+
+		@DisplayName("Representation Link should exists if vorgang has an eingang")
+		@Test
+		void shouldExistsAttachmentLinks() {
+			String expectedHref = "/api/representations?eingangId=" + EingangTestFactory.ID;
+
+			verifyLinkExistOnModel(VorgangMitEingangTestFactory.create(), VorgangModelAssembler.REL_REPRESENTATIONS, expectedHref);
+		}
+
+		@DisplayName("Attachment Link should NOT exists if vorgang has no eingang")
+		@Test
+		void shouldNotExists() {
+			verifyLinkNotExistsOnModel(VorgangHeaderTestFactory.create(), VorgangModelAssembler.REL_REPRESENTATIONS);
+		}
+	}
+
+	private void verifyLinkExistOnModel(Vorgang vorgang, String linkRel, String expectedLinkHref) {
+		var link = getLinkFromModel(vorgang, linkRel);
+
+		assertThat(link).isPresent();
+		assertThat(link.get().getHref()).isEqualTo(expectedLinkHref);
+	}
+
+	private void verifyLinkNotExistsOnModel(Vorgang vorgang, String linkRel) {
+		var link = getLinkFromModel(vorgang, linkRel);
+
+		assertThat(link).isNotPresent();
+	}
+
+	private Optional<Link> getLinkFromModel(Vorgang vorgang, String linkRel) {
+		return modelAssembler.toModel(vorgang).getLink(linkRel);
+	}
 }
\ No newline at end of file
-- 
GitLab