diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachService.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachService.java index 90d28db00fc2502aa4397ce64077e7769edbcd33..73439cf67fd9959222f2e8ae78b84aa641f62a41 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachService.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachService.java @@ -1,8 +1,7 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * Copyright (c) 2024. Das Land Schleswig-Holstein + * vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung * * Lizenziert unter der EUPL, Version 1.2 oder - sobald * diese von der Europäischen Kommission genehmigt wurden - @@ -23,6 +22,8 @@ */ package de.ozgcloud.nachrichten.postfach; +import static de.ozgcloud.nachrichten.postfach.PersistPostfachNachrichtServiceImpl.*; + import java.time.ZonedDateTime; import java.util.EnumSet; import java.util.Map; @@ -40,6 +41,7 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.nachrichten.antragraum.AntragraumService; import de.ozgcloud.nachrichten.attributes.ClientAttributeService; import de.ozgcloud.nachrichten.info.InfoManagerService; @@ -56,6 +58,8 @@ import lombok.extern.log4j.Log4j2; class PostfachService { private static final Predicate<PostfachNachricht> IS_FROM_HUMAN_USER = nachricht -> !StringUtils.startsWith(nachricht.getCreatedBy(), "system"); + static final Predicate<PostfachNachricht> IS_MUK_ANTWORT = nachricht -> StringUtils.isEmpty(nachricht.getVorgangId()) && StringUtils.isNotEmpty( + nachricht.getReferencedNachricht()); private static final Set<String> POSTFACH_TYPES_WITH_ANTRAGSRAUM = Set.of("BayernId"); @Autowired(required = false) @@ -90,9 +94,9 @@ class PostfachService { public void saveDraft(String vorgangId, PostfachNachricht nachricht) { persistMail(userService.getUser().getUserId(), - nachricht.toBuilder().vorgangId(vorgangId) - .createdBy(userService.getUser().getUserId().orElse(null)) - .build()); + nachricht.toBuilder().vorgangId(vorgangId) + .createdBy(userService.getUser().getUserId().orElse(null)) + .build()); } public void sendMail(String commandId, String userId, @Valid PostfachNachricht mail) { @@ -102,15 +106,15 @@ class PostfachService { PostfachNachricht addMailSentInformation(PostfachNachricht mail, SendPostfachNachrichtResponse sendResponse) { return mail.toBuilder().sentAt(ZonedDateTime.now()).sentSuccessful(sendResponse.isSentSuccessful()) - .messageCode(sendResponse.getMessageCode().getMessageCode()) - .build(); + .messageCode(sendResponse.getMessageCode().getMessageCode()) + .build(); } void persistSentMail(@NonNull String userId, PostfachNachricht mail) { persistMail(Optional.of(userId), mail.toBuilder() - .direction(Direction.OUT) - .createdAt(ZonedDateTime.now().withNano(0)).createdBy(userId) - .build()); + .direction(Direction.OUT) + .createdAt(ZonedDateTime.now().withNano(0)).createdBy(userId) + .build()); } @@ -127,9 +131,27 @@ class PostfachService { } private void persistReceivedMail(PostfachNachricht nachricht) { - persistMail(Optional.empty(), nachricht); + Optional<PostfachNachricht> linkedNachrichtOptional = Optional.of(nachricht); + if (IS_MUK_ANTWORT.test(nachricht)) { + var vorgangMapOptional = findById(nachricht.getReferencedNachricht()); + linkedNachrichtOptional = vorgangMapOptional.map( + vorgangMap -> Optional.of(setVorgangId((String) vorgangMap.get(VORGANG_ID_FIELD), nachricht))) + .orElseThrow(); + } + + linkedNachrichtOptional.ifPresent(linkedNachricht -> { + persistMail(Optional.empty(), linkedNachricht); + + postfachRemoteService.deleteMessage(linkedNachricht.getMessageId()); + }); + } + + PostfachNachricht setVorgangId(String vorgangId, PostfachNachricht nachricht) { + if (StringUtils.isNotEmpty(vorgangId)) { + return nachricht.toBuilder().vorgangId(vorgangId).build(); + } - postfachRemoteService.deleteMessage(nachricht.getMessageId()); + throw new TechnicalException("Cannot link nachricht [" + nachricht + "] to vorgang because vorgangId is empty"); } void persistMail(Optional<String> userId, PostfachNachricht mail) { @@ -212,8 +234,8 @@ class PostfachService { Map<String, Object> createResendPatchMap(SendPostfachNachrichtResponse sendResponse) { return Map.of(PostfachNachricht.FIELD_SENT_AT, ZonedDateTime.now().withNano(0).toString(), - PostfachNachricht.FIELD_SENT_SUCCESSFUL, sendResponse.isSentSuccessful(), - PostfachNachricht.FIELD_MESSAGE_CODE, sendResponse.getMessageCode().getMessageCode()); + PostfachNachricht.FIELD_SENT_SUCCESSFUL, sendResponse.isSentSuccessful(), + PostfachNachricht.FIELD_MESSAGE_CODE, sendResponse.getMessageCode().getMessageCode()); } private void patchMail(String postfachMailId, Map<String, Object> propertyMap) { @@ -246,5 +268,4 @@ class PostfachService { } block.run(); } - } \ No newline at end of file diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachServiceTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachServiceTest.java index ac8d6773fd1e363c8d9552a3307ea4a11c3c613d..c99165fd42280a37f5ce6528d7735a2526e6cadb 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachServiceTest.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachServiceTest.java @@ -1,8 +1,7 @@ /* - * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den - * Ministerpräsidenten des Landes Schleswig-Holstein - * Staatskanzlei - * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * Copyright (c) 2024. Das Land Schleswig-Holstein + * vertreten durch den Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei Abteilung Digitalisierung und zentrales IT-Management der Landesregierung * * Lizenziert unter der EUPL, Version 1.2 oder - sobald * diese von der Europäischen Kommission genehmigt wurden - @@ -23,17 +22,20 @@ */ package de.ozgcloud.nachrichten.postfach; +import static de.ozgcloud.nachrichten.postfach.PersistPostfachNachrichtServiceImpl.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; +import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.stream.Stream; import org.apache.logging.log4j.Logger; +import org.bson.types.ObjectId; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -50,6 +52,7 @@ import org.springframework.boot.logging.LogLevel; import org.springframework.context.ApplicationEventPublisher; import org.springframework.test.util.ReflectionTestUtils; +import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.nachrichten.antragraum.AntragraumService; import de.ozgcloud.nachrichten.attributes.ClientAttributeService; import de.ozgcloud.nachrichten.info.InfoManagerService; @@ -159,7 +162,7 @@ class PostfachServiceTest { @Test void shouldAddMailSentInformation() { var postfachMail = service.addMailSentInformation(PostfachNachrichtTestFactory.createBuilder().sentAt(null).sentSuccessful(null).build(), - SendPostfachNachrichtResponseTestFactory.create()); + SendPostfachNachrichtResponseTestFactory.create()); assertThat(postfachMail.getSentAt()).isNotNull(); assertThat(postfachMail.getSentSuccessful()).isEqualTo(SendPostfachNachrichtResponseTestFactory.SENT_SUCCESSFUL); @@ -497,7 +500,7 @@ class PostfachServiceTest { assertThat(map).containsKey(PostfachNachricht.FIELD_SENT_AT); assertThat(ZonedDateTime.parse(map.get(PostfachNachricht.FIELD_SENT_AT).toString())).isCloseTo(ZonedDateTime.now(), - within(2, ChronoUnit.SECONDS)); + within(2, ChronoUnit.SECONDS)); } @Test @@ -512,7 +515,7 @@ class PostfachServiceTest { var map = service.createResendPatchMap(SendPostfachNachrichtResponseTestFactory.create()); assertThat(map).containsEntry(PostfachNachricht.FIELD_MESSAGE_CODE, - SendPostfachNachrichtResponseTestFactory.MESSAGE_CODE.getMessageCode()); + SendPostfachNachrichtResponseTestFactory.MESSAGE_CODE.getMessageCode()); } } @@ -598,7 +601,7 @@ class PostfachServiceTest { void mockService() { when(postfachRemoteService.getPostfachType()).thenReturn(PostfachTestFactory.POSTFACH_TYPE); doThrow(new PostfachException(MESSAGE, PostfachMessageCode.SEND_SUCCESSFUL_MESSAGE_CODE)).when(postfachRemoteService) - .sendMessage(any()); + .sendMessage(any()); } @Test @@ -715,7 +718,7 @@ class PostfachServiceTest { @Nested class TestGetPostfachs { - private Postfach postfach = PostfachTestFactory.create(); + private final Postfach postfach = PostfachTestFactory.create(); @Test void shouldCallBuildPostfach() { @@ -798,4 +801,62 @@ class PostfachServiceTest { } } } + + @Nested + class TestSavingMukAntwort { + private PostfachNachricht antwort; + private final String refId = ObjectId.get().toHexString(); + + @BeforeEach + void setup() { + antwort = PostfachNachrichtTestFactory.createBuilder().vorgangId(null).referencedNachricht(refId).build(); + } + + @Test + void shouldIdentifyAsAntwort() { + assertThat(PostfachService.IS_MUK_ANTWORT.test(antwort)).isTrue(); + } + + @Test + void shouldNotIdentifyAsAntwort() { + assertThat(PostfachService.IS_MUK_ANTWORT.test(PostfachNachrichtTestFactory.create())).isFalse(); + } + + @Nested + class TestLinkingMukAntwortToVorgang { + private final String vorgangId = ObjectId.get().toHexString(); + + @BeforeEach + void setup() { + antwort = PostfachNachrichtTestFactory.createBuilder().vorgangId(null).referencedNachricht(refId).build(); + when(service.isPostfachConfigured()).thenReturn(Boolean.TRUE); + when(postfachRemoteService.getAllMessages()).thenReturn(Stream.of(antwort)); + } + + @Test + void shouldLoadLinkedNachricht() { + when(service.findById(eq(refId))).thenReturn(Optional.of(Map.of(VORGANG_ID_FIELD, vorgangId))); + + service.fetchAndPersistReplies(); + + verify(service).findById(anyString()); + } + + @Test + void shouldSetVorgangId() { + when(service.findById(anyString())).thenReturn(Optional.of(Map.of(VORGANG_ID_FIELD, vorgangId))); + + service.fetchAndPersistReplies(); + + verify(service).setVorgangId(anyString(), any(PostfachNachricht.class)); + } + + @Test + void shouldThrowExceptionWhenVorgangIdEmpty() { + when(service.findById(anyString())).thenReturn(Optional.of(Map.of("otherId", ObjectId.get().toHexString()))); + + assertThatExceptionOfType(TechnicalException.class).isThrownBy(() -> service.fetchAndPersistReplies()); + } + } + } } \ No newline at end of file