diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/RootViewLinkHandler.java b/alfa-service/src/main/java/de/ozgcloud/alfa/RootViewLinkHandler.java index 6a832f1fd28a98913c5d632926df270dbf9c69de..99d9c9dffd8948c4cfaafd1ecbe678fcdc6318ed 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/RootViewLinkHandler.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/RootViewLinkHandler.java @@ -27,12 +27,14 @@ import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; import java.util.List; import java.util.Optional; +import java.util.stream.Stream; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; import org.springframework.hateoas.server.LinkBuilder; import org.springframework.stereotype.Component; +import de.ozgcloud.alfa.common.FeatureToggleProperties; import de.ozgcloud.alfa.common.user.CurrentUserService; import de.ozgcloud.alfa.common.user.UserId; import de.ozgcloud.alfa.common.user.UserRole; @@ -70,9 +72,7 @@ class RootViewLinkHandler { private final CurrentUserService currentUserService; private final SystemStatusService systemStatusService; - - private final List<VorgangStatus> statusList = List.of(VorgangStatus.NEU, VorgangStatus.ANGENOMMEN, VorgangStatus.IN_BEARBEITUNG, - VorgangStatus.BESCHIEDEN, VorgangStatus.ABGESCHLOSSEN, VorgangStatus.VERWORFEN, VorgangStatus.ZU_LOESCHEN, VorgangStatus.WEITERGELEITET); + private final FeatureToggleProperties featureToggleProperties; public void addViewLinks(EntityModel<Root> model, Optional<UserId> userId) { model.add(buildGetAllVorgaengeLink()); @@ -158,7 +158,7 @@ class RootViewLinkHandler { } void addVorgangStatusLinks(EntityModel<Root> model, String linkRelTemplate) { - statusList.forEach(status -> model.add(buildGetAllVorgaengeByStatus(status, linkRelTemplate))); + getVorgangStatusStream().forEach(status -> model.add(buildGetAllVorgaengeByStatus(status, linkRelTemplate))); } Link buildGetAllVorgaengeByStatus(VorgangStatus status, String linkRelTemplate) { @@ -175,7 +175,14 @@ class RootViewLinkHandler { } List<Link> buildVorgangStatusLinks(String linkRelTemplate, UserId userId) { - return statusList.stream().map(status -> buildGetAllVorgaengeByAssignedToAndStatus(status, linkRelTemplate, userId)).toList(); + return getVorgangStatusStream().map(status -> buildGetAllVorgaengeByAssignedToAndStatus(status, linkRelTemplate, userId)).toList(); + } + + Stream<VorgangStatus> getVorgangStatusStream() { + return Stream + .of(VorgangStatus.NEU, VorgangStatus.ANGENOMMEN, VorgangStatus.IN_BEARBEITUNG, VorgangStatus.BESCHIEDEN, VorgangStatus.ABGESCHLOSSEN, + VorgangStatus.VERWORFEN, VorgangStatus.ZU_LOESCHEN, VorgangStatus.WEITERGELEITET) + .filter(status -> status != VorgangStatus.WEITERGELEITET || featureToggleProperties.isForwardByOzgCloudEnabled()); } Link buildGetAllVorgaengeByAssignedToAndStatus(VorgangStatus status, String linkRelTemplate, UserId userId) { @@ -214,4 +221,5 @@ class RootViewLinkHandler { .getAllByAssignedToAndUngeleseneNachrichten(0, PAGE_SIZE, userId, VorgangController.PARAM_NACHRICHTEN_UNGELESENE)) .withRel(linkRel); } + } \ No newline at end of file diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/RootViewLinkHandlerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/RootViewLinkHandlerTest.java index 0b8fd47ccba6b395fc4df64c34026035646620d8..6a1550ae2552d036331a2ecfcb8ab42bed4cf84e 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/RootViewLinkHandlerTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/RootViewLinkHandlerTest.java @@ -47,6 +47,7 @@ import org.springframework.hateoas.LinkRelation; import com.thedeanda.lorem.LoremIpsum; +import de.ozgcloud.alfa.common.FeatureToggleProperties; import de.ozgcloud.alfa.common.user.CurrentUserService; import de.ozgcloud.alfa.common.user.UserId; import de.ozgcloud.alfa.common.user.UserProfileTestFactory; @@ -63,6 +64,8 @@ class RootViewLinkHandlerTest { private CurrentUserService currentUserService; @Mock private SystemStatusService systemStatusService; + @Mock + private FeatureToggleProperties featureToggleProperties; @DisplayName("Add view links") @Nested @@ -213,7 +216,7 @@ class RootViewLinkHandlerTest { } @Test - void shouldCallAddVorgangStatusLinks() { + void shouldCallAddAllVorgangStatusLinks() { viewLinkHandler.addViewLinksForVerwaltungUser(model, Optional.of(UserProfileTestFactory.ID)); verify(viewLinkHandler).addAllVorgangStatusLinks(model); @@ -435,9 +438,19 @@ class RootViewLinkHandlerTest { class TestBuildVorgangStatusLinks { private final UserId userId = UserProfileTestFactory.ID; - private final List<VorgangStatus> statuses = List.of(VorgangStatus.NEU, VorgangStatus.ANGENOMMEN, VorgangStatus.IN_BEARBEITUNG, - VorgangStatus.BESCHIEDEN, - VorgangStatus.ABGESCHLOSSEN, VorgangStatus.VERWORFEN, VorgangStatus.ZU_LOESCHEN, VorgangStatus.WEITERGELEITET); + private final List<VorgangStatus> statuses = List.of(VorgangStatus.NEU, VorgangStatus.ANGENOMMEN); + + @BeforeEach + void mock() { + doReturn(statuses.stream()).when(viewLinkHandler).getVorgangStatusStream(); + } + + @Test + void shouldCallGetVorgangStatusStream() { + viewLinkHandler.buildVorgangStatusLinks(RootViewLinkHandler.VORGAENGE_ALL_REL_TEMPLATE, UserProfileTestFactory.ID); + + verify(viewLinkHandler).getVorgangStatusStream(); + } @Test void shouldCallBuildVorgangListByPageLink() { @@ -449,7 +462,7 @@ class RootViewLinkHandlerTest { @Test void shouldReturnLinks() { - var expectedLinks = LinkTestFactory.createList(8); + var expectedLinks = LinkTestFactory.createList(statuses.size()); doAnswer(AdditionalAnswers.returnsElementsOf(expectedLinks)).when(viewLinkHandler).buildGetAllVorgaengeByAssignedToAndStatus(any(), any(), any()); @@ -532,7 +545,7 @@ class RootViewLinkHandlerTest { @DisplayName("build get all vorgaenge by status") @Nested - class TestBuildGetAllByStatus { + class TestBuildGetAllVorgaengeByStatus { @ParameterizedTest @EnumSource(mode = Mode.INCLUDE, names = { "NEU", "ANGENOMMEN", "IN_BEARBEITUNG", "BESCHIEDEN", "ABGESCHLOSSEN", "VERWORFEN", @@ -543,6 +556,27 @@ class RootViewLinkHandlerTest { assertThat(link.getHref()).isEqualTo("/api/vorgangs?page=0&limit=100&status=" + status.toString()); } + @ParameterizedTest + @EnumSource(mode = Mode.INCLUDE, names = { "NEU", "ANGENOMMEN", "IN_BEARBEITUNG", "BESCHIEDEN", "ABGESCHLOSSEN", "VERWORFEN", + "ZU_LOESCHEN", "WEITERGELEITET" }) + void shouldCallFormatLinkRelTemplate(VorgangStatus status) { + viewLinkHandler.buildGetAllVorgaengeByStatus(status, RootViewLinkHandler.VORGAENGE_MY_REL_TEMPLATE); + + verify(viewLinkHandler).formatLinkRelTemplate(RootViewLinkHandler.VORGAENGE_MY_REL_TEMPLATE, status); + } + + @ParameterizedTest + @EnumSource(mode = Mode.INCLUDE, names = { "NEU", "ANGENOMMEN", "IN_BEARBEITUNG", "BESCHIEDEN", "ABGESCHLOSSEN", "VERWORFEN", + "ZU_LOESCHEN", "WEITERGELEITET" }) + void shouldHaveFormattedRelation(VorgangStatus status) { + var expectedRelation = LoremIpsum.getInstance().getWords(1); + doReturn(expectedRelation).when(viewLinkHandler).formatLinkRelTemplate(any(), any()); + + var link = viewLinkHandler.buildGetAllVorgaengeByStatus(status, RootViewLinkHandler.VORGAENGE_MY_REL_TEMPLATE); + + assertThat(link.getRel()).isEqualTo(LinkRelation.of(expectedRelation)); + } + } @DisplayName("build get all unassigned vorgaenge by status") @@ -729,4 +763,90 @@ class RootViewLinkHandlerTest { } } + + @Nested + class TestAddVorgangStatusLinks { + + private final EntityModel<Root> model = EntityModel.of(RootTestFactory.create()); + private final List<VorgangStatus> vorgangStatuses = List.of(VorgangStatus.NEU, VorgangStatus.BESCHIEDEN); + private final List<Link> links = LinkTestFactory.createList(vorgangStatuses.size()); + + @BeforeEach + void mock() { + doReturn(vorgangStatuses.stream()).when(viewLinkHandler).getVorgangStatusStream(); + doAnswer(AdditionalAnswers.returnsElementsOf(links)).when(viewLinkHandler).buildGetAllVorgaengeByStatus(any(), any()); + } + + @Test + void shouldCallGetVorgangStatusStream() { + viewLinkHandler.addVorgangStatusLinks(model, RootViewLinkHandler.VORGAENGE_ALL_REL_TEMPLATE); + + verify(viewLinkHandler).getVorgangStatusStream(); + } + + @Test + void shouldCallBuildGetAllVorgaengeByStatus() { + viewLinkHandler.addVorgangStatusLinks(model, RootViewLinkHandler.VORGAENGE_ALL_REL_TEMPLATE); + + vorgangStatuses + .forEach(status -> verify(viewLinkHandler).buildGetAllVorgaengeByStatus(status, RootViewLinkHandler.VORGAENGE_ALL_REL_TEMPLATE)); + } + + @Test + void shouldAddLinksToModel() { + viewLinkHandler.addVorgangStatusLinks(model, RootViewLinkHandler.VORGAENGE_ALL_REL_TEMPLATE); + + assertThat(model.getLinks()).containsExactlyInAnyOrderElementsOf(links); + } + } + + @Nested + class TestGetVorgangStatusStream { + + @Test + void shouldCallFeatureToggleProperties() { + viewLinkHandler.getVorgangStatusStream(); + + verify(featureToggleProperties).isForwardByOzgCloudEnabled(); + } + + @Nested + class TestOnIsForwardByOzgCloudEnabled { + + @BeforeEach + void mock() { + when(featureToggleProperties.isForwardByOzgCloudEnabled()).thenReturn(true); + } + + @Test + void shouldReturnStream() { + var expectedStatuses = List.of(VorgangStatus.NEU, VorgangStatus.ANGENOMMEN, VorgangStatus.IN_BEARBEITUNG, + VorgangStatus.BESCHIEDEN, VorgangStatus.ABGESCHLOSSEN, VorgangStatus.VERWORFEN, VorgangStatus.ZU_LOESCHEN, + VorgangStatus.WEITERGELEITET); + + var stream = viewLinkHandler.getVorgangStatusStream(); + + assertThat(stream).containsExactlyInAnyOrderElementsOf(expectedStatuses); + } + } + + @Nested + class TestOnIsNotForwardByOzgCloudEnabled { + + @BeforeEach + void mock() { + when(featureToggleProperties.isForwardByOzgCloudEnabled()).thenReturn(false); + } + + @Test + void shouldReturnStream() { + var expectedStatuses = List.of(VorgangStatus.NEU, VorgangStatus.ANGENOMMEN, VorgangStatus.IN_BEARBEITUNG, + VorgangStatus.BESCHIEDEN, VorgangStatus.ABGESCHLOSSEN, VorgangStatus.VERWORFEN, VorgangStatus.ZU_LOESCHEN); + + var stream = viewLinkHandler.getVorgangStatusStream(); + + assertThat(stream).containsExactlyInAnyOrderElementsOf(expectedStatuses); + } + } + } }