diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/collaboration/CollaborationVorgangProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/collaboration/CollaborationVorgangProcessor.java index 2f75114f05193871bb4c78621f119d912075065f..919b64ed9a0281c46620de22ff49c1c1761de22d 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/collaboration/CollaborationVorgangProcessor.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/collaboration/CollaborationVorgangProcessor.java @@ -25,7 +25,6 @@ package de.ozgcloud.alfa.collaboration; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; -import java.util.List; import java.util.Objects; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -47,7 +46,6 @@ import lombok.RequiredArgsConstructor; class CollaborationVorgangProcessor implements RepresentationModelProcessor<EntityModel<VorgangWithEingang>> { static final LinkRelation REL_COLLABORATIONS = LinkRelation.of("collaborations"); - static final LinkRelation REL_SEARCH_ORGANISATIONS_EINHEIT = LinkRelation.of("searchOrganisationsEinheit"); static final LinkRelation REL_SEARCH_FACHSTELLE = LinkRelation.of("searchFachstelle"); private final CurrentUserService currentUserService; @@ -60,17 +58,11 @@ class CollaborationVorgangProcessor implements RepresentationModelProcessor<Enti if (Objects.isNull(vorgang) || !currentUserService.hasRole(UserRole.VERWALTUNG_USER)) { return model; } - model.addAllIf(!collaborationService.hasCollaboration(vorgang.getId()), - () -> List.of(buildSearchOrganisationsEinheitLink(), buildSearchFachstelleLink())) + model.addIf(!collaborationService.hasCollaboration(vorgang.getId()), this::buildSearchFachstelleLink) .add(linkTo(methodOn(CollaborationByVorgangController.class).getAllByVorgangId(vorgang.getId())).withRel(REL_COLLABORATIONS)); return model; } - private Link buildSearchOrganisationsEinheitLink() { - return linkTo(methodOn(OrganisationsEinheitController.class).search(null)).withRel( - REL_SEARCH_ORGANISATIONS_EINHEIT); - } - private Link buildSearchFachstelleLink() { return linkTo(methodOn(FachstelleController.class).search(null)).withRel(REL_SEARCH_FACHSTELLE); } diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/collaboration/OrganisationsEinheitVorgangWithEingangProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/collaboration/OrganisationsEinheitVorgangWithEingangProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..d5a371ede44244bef75c221ce645fd50b296b742 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/collaboration/OrganisationsEinheitVorgangWithEingangProcessor.java @@ -0,0 +1,57 @@ +package de.ozgcloud.alfa.collaboration; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; + +import java.util.Optional; + +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.LinkRelation; +import org.springframework.hateoas.server.RepresentationModelProcessor; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.FeatureToggleProperties; +import de.ozgcloud.alfa.common.user.CurrentUserService; +import de.ozgcloud.alfa.common.user.UserRole; +import de.ozgcloud.alfa.vorgang.Vorgang.VorgangStatus; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +class OrganisationsEinheitVorgangWithEingangProcessor implements RepresentationModelProcessor<EntityModel<VorgangWithEingang>> { + + static final LinkRelation REL_SEARCH_ORGANISATIONS_EINHEIT = LinkRelation.of("searchOrganisationsEinheit"); + + private final FeatureToggleProperties featureToggleProperties; + private final CurrentUserService userService; + + @Override + public EntityModel<VorgangWithEingang> process(EntityModel<VorgangWithEingang> model) { + Optional.ofNullable(model.getContent()) + .ifPresent(vorgang -> model.addIf(isSearchNeeded(vorgang), + this::buildSearchOrganisationsEinheitLink)); + return model; + } + + boolean isSearchNeeded(VorgangWithEingang vorgang) { + return this.isForwardable(vorgang) || this.isCollaborationCreateable(); + } + + boolean isForwardable(VorgangWithEingang vorgang) { + return featureToggleProperties.isForwardByOzgCloudEnabled() && isStatusNeu(vorgang); + } + + boolean isCollaborationCreateable() { + return featureToggleProperties.isCollaborationEnabled() && this.userService.hasRole(UserRole.VERWALTUNG_USER); + } + + private boolean isStatusNeu(VorgangWithEingang vorgang) { + return vorgang.getStatus() == VorgangStatus.NEU; + } + + private Link buildSearchOrganisationsEinheitLink() { + return linkTo(methodOn(OrganisationsEinheitController.class).search(null)).withRel( + REL_SEARCH_ORGANISATIONS_EINHEIT); + } +} \ No newline at end of file diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/collaboration/CollaborationVorgangProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/collaboration/CollaborationVorgangProcessorTest.java index 97079a883a639e1844028ab2356403866462f7f5..9f245c3c6a9c4b31c29e3459c148862d467bc1a7 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/collaboration/CollaborationVorgangProcessorTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/collaboration/CollaborationVorgangProcessorTest.java @@ -103,20 +103,6 @@ class CollaborationVorgangProcessorTest { when(collaborationService.hasCollaboration(VorgangHeaderTestFactory.ID)).thenReturn(true); } - @Test - void shouldHaveOneLink() { - var model = callProcessor(); - - assertThat(model.getLinks()).hasSize(1); - } - - @Test - void shouldNotAddSearchOrganisationsEinheitLink() { - var model = callProcessor(); - - assertThat(model.getLink(CollaborationVorgangProcessor.REL_SEARCH_ORGANISATIONS_EINHEIT)).isEmpty(); - } - @Test void shouldAddCollaborationsLink() { var model = callProcessor(); @@ -135,26 +121,6 @@ class CollaborationVorgangProcessorTest { when(collaborationService.hasCollaboration(VorgangHeaderTestFactory.ID)).thenReturn(false); } - @Test - void shouldHaveThreeLinks() { - var model = callProcessor(); - - assertThat(model.getLinks()).hasSize(3); - } - - @Test - void shouldAddSearchOrganisationsEinheitLink() { - var expectedHref = UriComponentsBuilder.fromUriString(OrganisationsEinheitController.PATH) - .queryParam(OrganisationsEinheitController.SEARCH_BY_PARAM, "{" + OrganisationsEinheitController.SEARCH_BY_PARAM + "}") - .build().toString(); - - var model = callProcessor(); - - assertThat(model.getLink(CollaborationVorgangProcessor.REL_SEARCH_ORGANISATIONS_EINHEIT)).get() - .extracting(Link::getHref) - .isEqualTo(expectedHref); - } - @Test void shouldAddSearchFachstelleLink() { var expectedHref = UriComponentsBuilder.fromUriString(FachstelleController.PATH) diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/collaboration/OrganisationsEinheitVorgangWithEingangProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/collaboration/OrganisationsEinheitVorgangWithEingangProcessorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b6f7a6c040ee3e0890480ac79bf403bcbc8e6032 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/collaboration/OrganisationsEinheitVorgangWithEingangProcessorTest.java @@ -0,0 +1,211 @@ +package de.ozgcloud.alfa.collaboration; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.EnumSource.Mode; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.Link; + +import de.ozgcloud.alfa.common.FeatureToggleProperties; +import de.ozgcloud.alfa.common.user.CurrentUserService; +import de.ozgcloud.alfa.common.user.UserRole; +import de.ozgcloud.alfa.vorgang.Vorgang.VorgangStatus; +import de.ozgcloud.alfa.vorgang.VorgangWithEingang; +import de.ozgcloud.alfa.vorgang.VorgangWithEingangTestFactory; + +public class OrganisationsEinheitVorgangWithEingangProcessorTest { + + @InjectMocks + @Spy + private OrganisationsEinheitVorgangWithEingangProcessor processor; + + @Mock + private CurrentUserService userService; + @Mock + private FeatureToggleProperties featureToggleProperties; + + @DisplayName("Process") + @Nested + class TestProcess { + + private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + + private final EntityModel<VorgangWithEingang> model = EntityModel.of(vorgang); + + @Test + void shouldReturnSameModel() { + var processedModel = processor.process(model); + + assertThat(processedModel).isSameAs(model); + } + + @SuppressWarnings("unchecked") + @Test + void shouldReturnSameModelOnNullContent() { + var entityModel = mock(EntityModel.class); + when(entityModel.getContent()).thenReturn(null); + + var processedModel = processor.process(entityModel); + + assertThat(processedModel).isSameAs(entityModel); + } + + @DisplayName("entity model links") + @Nested + class TestEntityModelLinks { + + @Test + void shouldContainsSearchLinkIfNeeded() { + doReturn(true).when(processor).isSearchNeeded(any()); + + var processedModel = processor.process(model); + + assertThat(processedModel.getLink(OrganisationsEinheitVorgangWithEingangProcessor.REL_SEARCH_ORGANISATIONS_EINHEIT)).get() + .extracting(Link::getHref) + .isEqualTo(OrganisationsEinheitController.PATH + "?searchBy={searchBy}"); + } + } + } + + @DisplayName("is search needed") + @Nested + class TestIsSearchNeeded { + + private VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); + + @Test + void shouldReturnTrueIfForwardable() { + doReturn(true).when(processor).isForwardable(any()); + + var isSearchNeeded = processor.isSearchNeeded(vorgang); + + assertThat(isSearchNeeded).isTrue(); + } + + @Test + void shouldReturnFalseIfCollaborationCreateable() { + doReturn(true).when(processor).isCollaborationCreateable(); + + var isSearchNeeded = processor.isSearchNeeded(vorgang); + + assertThat(isSearchNeeded).isTrue(); + } + } + + @DisplayName("is forwardable") + @Nested + class TestIsForwardable { + + @DisplayName("on feature disabled") + @Nested + class TestOnFeatureDisabled { + + @BeforeEach + void mockFeatureToggle() { + when(featureToggleProperties.isForwardByOzgCloudEnabled()).thenReturn(false); + } + + @ParameterizedTest + @EnumSource + void shouldReturnFalse(VorgangStatus status) { + var vorgang = VorgangWithEingangTestFactory.createBuilder().status(status).build(); + + var forwardableByOzgCloud = processor.isForwardable(vorgang); + + assertThat(forwardableByOzgCloud).isFalse(); + } + } + + @DisplayName("on feature enabled") + @Nested + class TestOnFeatureEnabled { + + @BeforeEach + void mockFeatureToggle() { + when(featureToggleProperties.isForwardByOzgCloudEnabled()).thenReturn(true); + } + + @ParameterizedTest(name = "{0}") + @EnumSource(mode = Mode.EXCLUDE, names = { "NEU" }) + void shouldReturnFalseOnVorgangStatus(VorgangStatus status) { + var forwardableByOzgCloud = processor.isForwardable(VorgangWithEingangTestFactory.createBuilder().status(status).build()); + + assertThat(forwardableByOzgCloud).isFalse(); + } + + @Test + void shouldReturnTrueOnVorgangStatusNeu() { + var forwardable = processor.isForwardable(VorgangWithEingangTestFactory.createBuilder().status(VorgangStatus.NEU).build()); + + assertThat(forwardable).isTrue(); + } + } + } + + @DisplayName("is collaboration createable") + @Nested + class TestIsCollaborationCreateable { + + @DisplayName("on feature disabled") + @Nested + class TestOnFeatureDisabled { + + @BeforeEach + void mockFeatureToggle() { + when(featureToggleProperties.isCollaborationEnabled()).thenReturn(false); + } + + void shouldReturnFalse() { + var isCollaborationEnabled = processor.isCollaborationCreateable(); + + assertThat(isCollaborationEnabled).isFalse(); + } + } + + @DisplayName("on feature enabled") + @Nested + class TestOnFeatureEnabled { + + @BeforeEach + void mockFeatureToggle() { + when(featureToggleProperties.isCollaborationEnabled()).thenReturn(true); + } + + @Test + void shouldVerifyRole() { + processor.isCollaborationCreateable(); + + verify(userService).hasRole(UserRole.VERWALTUNG_USER); + } + + @Test + void shouldReturnFalseMissingRole() { + when(userService.hasRole(any())).thenReturn(false); + + var isCollaborationEnabled = processor.isCollaborationCreateable(); + + assertThat(isCollaborationEnabled).isFalse(); + } + + @Test + void shouldReturnTrueOnAssignedRole() { + when(userService.hasRole(any())).thenReturn(true); + + var isCollaborationEnabled = processor.isCollaborationCreateable(); + + assertThat(isCollaborationEnabled).isTrue(); + } + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/historie/ChangeHistoryBuilderTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/historie/ChangeHistoryBuilderTest.java index 41dbd9daa892b5f82555b700afdeed0c1f8071ce..7d7e6fedf88b1ad49a771a64dbfa06936e7e09de 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/historie/ChangeHistoryBuilderTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/historie/ChangeHistoryBuilderTest.java @@ -262,7 +262,7 @@ public class ChangeHistoryBuilderTest { void shouldReturnEmptyIfPropertyIsNotPresentInBody() { var command = previousCommand.toBuilder().body(Map.of("a", "b")).build(); - var value = builder.getValueFromCommandBody(PROPERTY_NAME, command); + var value = builder.getValueFromCommandBody("notExists", command); assertThat(value).isEmpty(); }