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 e8d834618a56d3efd308efa231d6ca5c13cc13ef..b5d79fcc0ab64557b88236b0903d0aafc14e125f 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/RootViewLinkHandler.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/RootViewLinkHandler.java @@ -38,6 +38,10 @@ class RootViewLinkHandler { static final String SEARCH_MY_VORGEANGE_REL = "search_my"; static final String SEARCH_UNASSIGNED_VORGEANGE_REL = "search_unassigned"; + static final String ALL_UNGELESENE_NACHRICHTEN_REL = "vorgaenge_ungelesene_nachrichten_all"; + static final String MY_UNGELESENE_NACHRICHTEN_REL = "vorgaenge_ungelesene_nachrichten_my"; + static final String UNASSIGNED_UNGELESENE_NACHRICHTEN_REL = "vorgaenge_ungelesene_nachrichten_unassigned"; + static final int PAGE_SIZE = 100; @Autowired @@ -100,6 +104,8 @@ class RootViewLinkHandler { modelBuilder .addLink(buildGetAllByAssignedToAndHasNextWiedervorlageFristLink(UserId.empty(), UNASSIGNED_WIEDERVORLAGEN_REL)); userId.map(id -> buildGetAllByAssignedToAndHasNextWiedervorlageFristLink(id, MY_WIEDERVORLAGEN_REL)).ifPresent(modelBuilder::addLink); + + addGetByUngeleseneNachrichtenLinks(modelBuilder, userId); } Link buildGetAllUnassignedVorgaengeLink() { @@ -169,4 +175,22 @@ class RootViewLinkHandler { return linkTo(methodOn(VorgangController.class).getAllByAssignedToAndHasNextWiedervorlageFrist(0, PAGE_SIZE, userId, VorgangController.PARAM_NEXT_WIEDERVORLAGE_FRIST_EXISTS)).withRel(linkRel); } + + void addGetByUngeleseneNachrichtenLinks(ModelBuilder<Root> modelBuilder, Optional<UserId> userId) { + modelBuilder.addLink(buildGelAllByUngeleseneNachrichtenLink()); + modelBuilder.addLink(buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(), UNASSIGNED_UNGELESENE_NACHRICHTEN_REL)); + userId.map(id -> buildGetAllByAssignedToAndUngeleseneNachrichten(id, MY_UNGELESENE_NACHRICHTEN_REL)).ifPresent(modelBuilder::addLink); + } + + Link buildGelAllByUngeleseneNachrichtenLink() { + return linkTo(methodOn(VorgangController.class) + .getAllByUngeleseneNachrichten(0, PAGE_SIZE, VorgangController.PARAM_NACHRICHTEN_UNGELESENE)) + .withRel(ALL_UNGELESENE_NACHRICHTEN_REL); + } + + Link buildGetAllByAssignedToAndUngeleseneNachrichten(@NonNull UserId userId, String linkRel) { + return linkTo(methodOn(VorgangController.class) + .getAllByAssignedToAndUngeleseneNachrichten(0, PAGE_SIZE, userId, VorgangController.PARAM_NACHRICHTEN_UNGELESENE)) + .withRel(linkRel); + } } \ No newline at end of file diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangController.java index 35062413fb4a816eaf0263aa284d2bc5b32b4e6a..0bbd400966bc4a8ee9ae29beb72ba6fc158e9a48 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangController.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangController.java @@ -58,8 +58,10 @@ public class VorgangController { static final String PARAM_ASSIGNED_TO = "assignedTo"; static final String PARAM_STATUS = "status"; static final String PARAM_NEXT_WIEDERVORLAGE_FRIST = "nextFrist"; + static final String PARAM_NACHRICHTEN = "nachrichten"; public static final String PARAM_NEXT_WIEDERVORLAGE_FRIST_EXISTS = "exists"; + public static final String PARAM_NACHRICHTEN_UNGELESENE = "ungelesene"; @Autowired private VorgangService vorgangService; @@ -189,4 +191,16 @@ public class VorgangController { clientAttributeService.resetPostfachNachricht(vorgangId); response.setStatus(HttpStatus.NO_CONTENT.value()); } + + @GetMapping(params = { PARAM_PAGE, PARAM_LIMIT, PARAM_NACHRICHTEN }) + public RepresentationModel<EntityModel<EnhancedVorgang>> getAllByUngeleseneNachrichten(@RequestParam int page, @RequestParam Integer limit, + @RequestParam String nachrichten) { + return EntityModel.of(EnhancedVorgang.builder().build()); + } + + @GetMapping(params = { PARAM_PAGE, PARAM_LIMIT, PARAM_ASSIGNED_TO, PARAM_NACHRICHTEN }) + public RepresentationModel<EntityModel<EnhancedVorgang>> getAllByAssignedToAndUngeleseneNachrichten(@RequestParam int page, + @RequestParam Integer limit, @RequestParam UserId assignedTo, @RequestParam String nachrichten) { + return EntityModel.of(EnhancedVorgang.builder().build()); + } } \ 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 64f4aadcf97daf229570e1affc1273dc9423da7a..84733b060eff9e273ab5bb84f97ccd00588bf73e 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/RootViewLinkHandlerTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/RootViewLinkHandlerTest.java @@ -6,6 +6,7 @@ import static org.mockito.Mockito.*; import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -18,6 +19,8 @@ import org.mockito.Spy; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; +import com.thedeanda.lorem.LoremIpsum; + import de.ozgcloud.alfa.common.ModelBuilder; import de.ozgcloud.alfa.common.user.CurrentUserService; import de.ozgcloud.alfa.common.user.UserId; @@ -282,6 +285,13 @@ class RootViewLinkHandlerTest { .get().extracting(Link::getHref).isEqualTo("/api/vorgangs?page=0&limit=100&assignedTo=&nextFrist=exists"); } } + + @Test + void shouldAddLinksForUngeleseneNachrichten() { + viewLinkHandler.addViewLinksForVerwaltungUser(modelBuilder, Optional.of(UserProfileTestFactory.ID)); + + verify(viewLinkHandler).addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.of(UserProfileTestFactory.ID)); + } } @DisplayName("search all vorgaenge") @@ -318,7 +328,7 @@ class RootViewLinkHandlerTest { void shouldBeAddedIfUserIsPresent() { var link = viewLinkHandler.buildMyVorgaengeLink(UserProfileTestFactory.ID); - assertThat(link.getHref()).isEqualTo("/api/vorgangs?page=0&limit=100&assignedTo=" + UserProfileTestFactory.ID.toString()); + assertThat(link.getHref()).isEqualTo("/api/vorgangs?page=0&limit=100&assignedTo=" + UserProfileTestFactory.ID); } } @@ -504,6 +514,176 @@ class RootViewLinkHandlerTest { } } + @Nested + class TestBuildGelAllByUngeleseneNachrichtenLink { + + @Test + void shouldHaveLinkHref() { + var link = viewLinkHandler.buildGelAllByUngeleseneNachrichtenLink(); + + assertThat(link) + .extracting(Link::getHref) + .isEqualTo("/api/vorgangs?page=0&limit=100&nachrichten=ungelesene"); + } + + @Test + void shouldHaveLinkRel() { + var link = viewLinkHandler.buildGelAllByUngeleseneNachrichtenLink(); + + assertThat(link) + .extracting(Link::getRel) + .extracting(LinkRelation::value) + .isEqualTo(RootViewLinkHandler.ALL_UNGELESENE_NACHRICHTEN_REL); + } + } + + @Nested + class TestBuildGetAllByAssignedToAndUngeleseneNachrichten { + + @Nested + class AssignTo { + + @Test + void shouldHaveLink() { + var link = viewLinkHandler.buildGetAllByAssignedToAndUngeleseneNachrichten(UserProfileTestFactory.ID, + RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL); + + assertThat(link) + .extracting(Link::getHref) + .isEqualTo("/api/vorgangs?page=0&limit=100&assignedTo=" + UserProfileTestFactory.ID + "&nachrichten=ungelesene"); + } + + @Test + void shouldHaveLinkRel() { + var link = viewLinkHandler.buildGetAllByAssignedToAndUngeleseneNachrichten(UserProfileTestFactory.ID, + RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL); + + assertThat(link) + .extracting(Link::getRel) + .extracting(LinkRelation::value) + .isEqualTo(RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL); + } + } + + @Nested + class Unassigned { + + @Test + void shouldHaveLink() { + var link = viewLinkHandler.buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(), + RootViewLinkHandler.UNASSIGNED_UNGELESENE_NACHRICHTEN_REL); + + assertThat(link) + .extracting(Link::getHref) + .isEqualTo("/api/vorgangs?page=0&limit=100&assignedTo=&nachrichten=ungelesene"); + } + + @Test + void shouldHaveLinkRel() { + var link = viewLinkHandler.buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(), + RootViewLinkHandler.UNASSIGNED_UNGELESENE_NACHRICHTEN_REL); + + assertThat(link) + .extracting(Link::getRel) + .extracting(LinkRelation::value) + .isEqualTo(RootViewLinkHandler.UNASSIGNED_UNGELESENE_NACHRICHTEN_REL); + } + + } + + } + + @Nested + class TestAddGetByUngeleseneNachrichtenLinks { + + @Mock + private Root rootResource; + private final ModelBuilder<Root> modelBuilder = ModelBuilder.fromEntity(rootResource); + private final Link linkAllUngeleseneNachrichten = Link.of(LoremIpsum.getInstance().getUrl()); + private final Link linkMyUngeleseneNachrichten = Link.of(LoremIpsum.getInstance().getUrl()); + private final Link linkUnassignedUngeleseneNachrichten = Link.of(LoremIpsum.getInstance().getUrl()); + + @BeforeEach + void setUp() { + doReturn(linkAllUngeleseneNachrichten).when(viewLinkHandler).buildGelAllByUngeleseneNachrichtenLink(); + doReturn(linkUnassignedUngeleseneNachrichten).when(viewLinkHandler) + .buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(), RootViewLinkHandler.UNASSIGNED_UNGELESENE_NACHRICHTEN_REL); + } + + @Test + void shouldBuildLinkForUngeleseneNachrichten() { + viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.of(UserProfileTestFactory.ID)); + + verify(viewLinkHandler).buildGelAllByUngeleseneNachrichtenLink(); + } + + @Test + void shouldAddLinkForUngeleseneNachrichten() { + var modelBuilder = ModelBuilder.fromEntity(rootResource); + + viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.of(UserProfileTestFactory.ID)); + + assertThat(modelBuilder.buildModel().getLinks()).contains(linkAllUngeleseneNachrichten); + } + + @Test + void shouldBuildLinkForUnassignedUngeleseneNachrichten() { + viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.empty()); + + verify(viewLinkHandler).buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(), + RootViewLinkHandler.UNASSIGNED_UNGELESENE_NACHRICHTEN_REL); + } + + @Test + void shouldAddLinkForUnassignedUngeleseneNachrichten() { + var modelBuilder = ModelBuilder.fromEntity(rootResource); + + viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.empty()); + + assertThat(modelBuilder.buildModel().getLinks()).contains(linkUnassignedUngeleseneNachrichten); + } + + @Nested + class UsedIdExists { + + @BeforeEach + void setUp() { + doReturn(linkMyUngeleseneNachrichten).when(viewLinkHandler).buildGetAllByAssignedToAndUngeleseneNachrichten(UserProfileTestFactory.ID, + RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL); + } + + @Test + void shouldBuildLinkForMyUngeleseneNachrichten() { + viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.of(UserProfileTestFactory.ID)); + + verify(viewLinkHandler).buildGetAllByAssignedToAndUngeleseneNachrichten(UserProfileTestFactory.ID, + RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL); + } + + @Test + void shouldAddLinkForMyUngeleseneNachrichten() { + var modelBuilder = ModelBuilder.fromEntity(rootResource); + + viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.of(UserProfileTestFactory.ID)); + + assertThat(modelBuilder.buildModel().getLinks()).contains(linkMyUngeleseneNachrichten); + } + } + + @Nested + class UserIdEmpty { + + @Test + void shouldNotBuildLinkForMyUngeleseneNachrichten() { + viewLinkHandler.addGetByUngeleseneNachrichtenLinks(modelBuilder, Optional.empty()); + + verify(viewLinkHandler, never()).buildGetAllByAssignedToAndUngeleseneNachrichten(UserProfileTestFactory.ID, + RootViewLinkHandler.MY_UNGELESENE_NACHRICHTEN_REL); + } + } + + } + // @DisplayName("Test user assistance documentation link") // @Nested // class TestDocumentationLink {