diff --git a/spec/postfach-api-facade.yaml b/spec/postfach-api-facade.yaml index f9730377d06df25d100193431405c9ab1ab5031a..0414d95e73a7a704396be50ed764b23684c96efe 100644 --- a/spec/postfach-api-facade.yaml +++ b/spec/postfach-api-facade.yaml @@ -1264,6 +1264,7 @@ paths: detail: Der Dienst ist zurzeit nicht verfügbar. /MessageExchange/v1/Delete/{messageId}: delete: + operationId: deleteMessage tags: - MessageExchange summary: Löscht eine Nachricht. diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteService.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteService.java index b3625b4713d2cddf4aa1e484cbe57eb13e15199f..6559227d384fd2af43f561149553e38c91029b82 100644 --- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteService.java +++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteService.java @@ -16,7 +16,7 @@ import lombok.extern.log4j.Log4j2; public record OsiPostfachRemoteService( PostfachApiFacadeService postfachApiFacadeService ) implements PostfachRemoteService { - public static final String POSTFACH_TYPE_OSI = "OSI"; + public static final String POSTFACH_TYPE_OSI = "OSIV2"; @Override public void sendMessage(PostfachNachricht nachricht) { @@ -29,13 +29,20 @@ public record OsiPostfachRemoteService( @Override public Stream<PostfachNachricht> getAllMessages() { - // TODO handle exceptions? - return postfachApiFacadeService.receiveMessages(); + try { + return postfachApiFacadeService.receiveMessages(); + }catch (RuntimeException e) { + throw new OsiPostfachException("Failed to get messages", e); + } } @Override public void deleteMessage(String messageId) { - // TODO + try { + postfachApiFacadeService.deleteMessage(messageId); + } catch (RuntimeException e) { + throw new OsiPostfachException("Failed to delete messages", e); + } } @Override diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java index b48e8cb7e5569003e37d0586bbc3b12388a5b6ad..246a12108b9fdc919df2bd87b11aa93219f71d8a 100644 --- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java +++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java @@ -1,5 +1,6 @@ package de.ozgcloud.nachrichten.postfach.osiv2.transfer; +import java.util.UUID; import java.util.stream.Stream; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -7,16 +8,15 @@ import org.springframework.stereotype.Service; import de.ozgcloud.nachrichten.postfach.PostfachNachricht; import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MessageExchangeApi; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeReceiveMessage; import lombok.extern.log4j.Log4j2; @Log4j2 @Service @ConditionalOnProperty("ozgcloud.osiv2-postfach.enabled") -public record PostfachApiFacadeService( - MessageExchangeApi messageExchangeApi, - RequestMapper requestMapper, - ResponseMapper responseMapper -) { +public record PostfachApiFacadeService(MessageExchangeApi messageExchangeApi, RequestMapper requestMapper, ResponseMapper responseMapper) { + + private static int MAX_NUMBER_RECEIVED_MESSAGES = 100; public void sendMessage(PostfachNachricht nachricht) { messageExchangeApi.sendMessage( requestMapper.mapMailboxId(nachricht), @@ -25,12 +25,17 @@ public record PostfachApiFacadeService( } public Stream<PostfachNachricht> receiveMessages() { - // TODO fetch message by guid and map to PostfachNachricht - var response = messageExchangeApi.receiveMessages(100, 0) - .block(); - LOG.info("receive-message-guids: {}", String.join(", ", - response.getMessages().stream().map(message -> message.getGuid().toString()).toList())); - return Stream.empty(); + var response = messageExchangeApi.receiveMessages(MAX_NUMBER_RECEIVED_MESSAGES, 0).block(); + return response.getMessages().stream().map(this::fetchMessageByGuid); + } + + PostfachNachricht fetchMessageByGuid(final MessageExchangeReceiveMessage message) { + var messageReply = messageExchangeApi.getMessage(message.getGuid()).block(); + return responseMapper.toPostfachNachricht(messageReply); } + public void deleteMessage(final String messageId) { + messageExchangeApi.deleteMessage(UUID.fromString(messageId)).block(); + + } } diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/ResponseMapper.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/ResponseMapper.java index 41c126a15861bc5dbfa06e06f99b327ec6563979..84a1b80ce2f3ac508b39ce35bd9c52edc6f5ce4b 100644 --- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/ResponseMapper.java +++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/ResponseMapper.java @@ -1,9 +1,75 @@ package de.ozgcloud.nachrichten.postfach.osiv2.transfer; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; + import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.mapstruct.ReportingPolicy; -@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) +import de.ozgcloud.nachrichten.postfach.PostfachAddress; +import de.ozgcloud.nachrichten.postfach.PostfachAddressIdentifier; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.osiv2.OsiPostfachRemoteService; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyBehavior; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyMessage; +import lombok.Builder; +import lombok.Getter; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR, imports = ZoneOffset.class) public interface ResponseMapper { + String POSTFACH_ADDRESS_VERSION = "2.0"; + int POSTFACH_ADDRESS_TYPE = 2; + + @Mapping(target = "id", source = "guid") + @Mapping(target = "postfachAddress", expression = "java(buildPostfachAddressByPostfachId(message.getMessageBox().toString()))") + @Mapping(target = "messageId", ignore = true) + @Mapping(target = "createdAt", expression = "java(java.time.ZonedDateTime.now())") + @Mapping(target = "createdBy", source = "displayName") + @Mapping(target = "sentAt", expression = "java(message.getResponseTime().toZonedDateTime())") + @Mapping(target = "sentSuccessful", ignore = true) + @Mapping(target = "messageCode", ignore = true) + @Mapping(target = "direction", constant = "IN") + @Mapping(target = "vorgangId", source = "sequencenumber") + @Mapping(target = "referencedNachricht", ignore = true) + @Mapping(target = "mailBody", source = "body") + @Mapping(target = "replyOption", source = "replyAction") + @Mapping(target = "attachments", ignore = true) + PostfachNachricht toPostfachNachricht(V1ReplyMessage message); + + default PostfachAddress buildPostfachAddressByPostfachId(String postfachId) { + return PostfachAddress.builder() + .type(POSTFACH_ADDRESS_TYPE) + .version(POSTFACH_ADDRESS_VERSION) + .identifier(StringBasedIdentifier.builder().mailboxId(postfachId).build()) + .serviceKontoType(OsiPostfachRemoteService.POSTFACH_TYPE_OSI) + .build(); + + } + + default PostfachNachricht.ReplyOption mapReplyAction(V1ReplyBehavior replyOption) { + return switch (replyOption) { + case REPLYFORBIDDEN -> PostfachNachricht.ReplyOption.FORBIDDEN; + case REPLYPOSSIBLE -> PostfachNachricht.ReplyOption.POSSIBLE; + case REPLYMANDATORY -> PostfachNachricht.ReplyOption.MANDATORY; + }; + } + + @Builder + @Getter + class StringBasedIdentifier implements PostfachAddressIdentifier { + + private String mailboxId; + + @Override + public boolean isStringBasedIdentifier() { + return true; + } + + @Override + public String toString() { + return mailboxId; + } + } } diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java index 4032fec013c3c45adca8bdcca5291b2c483f917c..2c07c7829eecea5369ae091c96b892161fe2095d 100644 --- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java +++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java @@ -2,19 +2,26 @@ package de.ozgcloud.nachrichten.postfach.osiv2; import static de.ozgcloud.nachrichten.postfach.osiv2.factory.JwtFactory.*; import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; import static org.mockserver.mock.OpenAPIExpectation.*; import static org.mockserver.model.HttpRequest.*; +import static org.mockserver.model.HttpResponse.*; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.time.OffsetDateTime; +import java.util.Arrays; import java.util.Map; +import java.util.Objects; +import java.util.UUID; 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.api.extension.RegisterExtension; import org.mockserver.client.MockServerClient; +import org.mockserver.model.OpenAPIDefinition; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; @@ -22,10 +29,18 @@ import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.TestPropertySource; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + import de.ozgcloud.nachrichten.postfach.PostfachNachricht; import de.ozgcloud.nachrichten.postfach.osiv2.extension.Jwt; import de.ozgcloud.nachrichten.postfach.osiv2.extension.OsiMockServerExtension; import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeReceiveMessage; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeReceiveMessagesResponse; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyBehavior; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyMessage; import lombok.SneakyThrows; @SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.NONE) @@ -60,32 +75,109 @@ public class OsiPostfachRemoteServiceITCase { postfachFacadeMockClient = OSI_MOCK_SERVER_EXTENSION.getPostfachFacadeMockClient(); } - @DisplayName("send message") - @Nested - class TestSendMessage { - - @DisplayName("should send dummy request with jwt") - @Test - @SneakyThrows - void shouldSendDummyRequestWithJwt() { - postfachFacadeMockClient.upsert( - openAPIExpectation() - .withSpecUrlOrPayload(Files.readString(Path.of("spec", "postfach-api-facade.yaml"))) - .withOperationsAndResponses(Map.of( - "SendMessage", "200" - )) - ); - - osiPostfachRemoteService.sendMessage(postfachNachricht); - - var requests = postfachFacadeMockClient.retrieveRecordedRequests(request()); - assertThat(requests).hasSize(1); - var jwt = Jwt.parseAuthHeaderValue( - requests[0].getHeader("Authorization").getFirst() - ); - assertThat(jwt.body().read("$.client_id", String.class)).isEqualTo(CLIENT_ID); - assertThat(jwt.body().read("$.aud", String.class)).isEqualTo(RESOURCE_URN); - } + @DisplayName("should send dummy request with jwt") + @Test + @SneakyThrows + void shouldSendDummyRequestWithJwt() { + postfachFacadeMockClient.upsert( + openAPIExpectation() + .withSpecUrlOrPayload(Files.readString(Path.of("spec", "postfach-api-facade.yaml"))) + .withOperationsAndResponses(Map.of( + "SendMessage", "200" + )) + ); + + osiPostfachRemoteService.sendMessage(postfachNachricht); + + var requests = postfachFacadeMockClient.retrieveRecordedRequests(request()); + assertThat(requests).hasSize(1); + var jwt = Jwt.parseAuthHeaderValue( + requests[0].getHeader("Authorization").getFirst() + ); + assertThat(jwt.body().read("$.client_id", String.class)).isEqualTo(CLIENT_ID); + assertThat(jwt.body().read("$.aud", String.class)).isEqualTo(RESOURCE_URN); + } + + ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); + + @DisplayName("should receive one messages") + @Test + @SneakyThrows + void shouldReceiveMessages() { + var uuid = UUID.fromString("00000000-0000-0000-0000-000000000000"); + + createMessagesJson(uuid, null); + + createOneReplyMessageJson(uuid); + + var messageStream = osiPostfachRemoteService.getAllMessages(); + + var messageList = messageStream.toList(); + assertThat(messageList).size().isEqualTo(1); + } + + @DisplayName("should receive two messages") + @Test + @SneakyThrows + void shouldReceiveTwoMessages() { + var uuid1 = UUID.fromString("00000000-0000-0000-0000-000000000000"); + var uuid2 = UUID.fromString("00000000-0000-0000-0000-000000000001"); + + createMessagesJson(uuid1, uuid2); + + createOneReplyMessageJson(uuid1); + createOneReplyMessageJson(uuid2); + + var messageStream = osiPostfachRemoteService.getAllMessages(); + var messageList = messageStream.toList(); + assertThat(messageList).size().isEqualTo(2); } + + private void createMessagesJson(final UUID... uuids) throws IOException { + var messagesList = Arrays.stream(uuids).filter(Objects::nonNull).map(uuid -> new MessageExchangeReceiveMessage().guid(uuid)).toList(); + + var messages = new MessageExchangeReceiveMessagesResponse().messages(messagesList); + + ObjectWriter ow = objectMapper.writer().withDefaultPrettyPrinter(); + String messagesJson = ow.writeValueAsString(messages); + + createMessagesCall("receiveMessages", messagesJson); + } + + private void createMessagesCall(final String receiveMessages, final String messagesJson) throws IOException { + postfachFacadeMockClient + .when( + new OpenAPIDefinition() + .withSpecUrlOrPayload(Files.readString(Path.of("spec", "postfach-api-facade.yaml"))) + .withOperationId(receiveMessages) + ) + .respond(response().withHeader("Content-type", "application/json").withBody(messagesJson)); + } + + private void createOneReplyMessageJson(final UUID uuid) throws IOException { + ObjectWriter ow = objectMapper.writer().withDefaultPrettyPrinter(); + + var replyMessage = new V1ReplyMessage() + .body("das ist ein toller Body").replyAction(V1ReplyBehavior.REPLYPOSSIBLE).messageBox(uuid).responseTime(OffsetDateTime.now()); + String messageJson = ow.writeValueAsString(replyMessage); + + createMessagesCall("getMessage", messageJson); + } + + @DisplayName("should delete message") + @Test + @SneakyThrows + void shouldDeleteMessage() { + postfachFacadeMockClient.upsert( + openAPIExpectation() + .withSpecUrlOrPayload(Files.readString(Path.of("spec", "postfach-api-facade.yaml"))) + .withOperationsAndResponses(Map.of( + "deleteMessage", "200" + )) + ); + + assertDoesNotThrow(() -> osiPostfachRemoteService.deleteMessage("00000000-0000-0000-0000-000000000000")); + } + } diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceRemoteITCase.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceRemoteITCase.java index 5cca4d39ca591f10b9612b24ba2abc8075070e3c..344c3de7e35a2f68761a726cf963248aae4dbcf8 100644 --- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceRemoteITCase.java +++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceRemoteITCase.java @@ -4,7 +4,9 @@ import static org.assertj.core.api.Assertions.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Stream; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -29,9 +31,10 @@ public class OsiPostfachRemoteServiceRemoteITCase { private OsiPostfachRemoteService osiPostfachRemoteService; private final PostfachNachricht nachricht = PostfachNachrichtTestFactory.createBuilder() + .replyOption(PostfachNachricht.ReplyOption.POSSIBLE) .postfachAddress(PostfachAddressTestFactory.createBuilder() .identifier(DummyStringBasedIdentifier.builder() - .mailboxId("sh/sh/60e319ae-4fe7-4f47-c7c8-08dca563280a") + .mailboxId("49b5a7e2-5e60-4baf-8ccf-1f5b94b570f3") .build()) .build()) .build(); @@ -60,6 +63,7 @@ public class OsiPostfachRemoteServiceRemoteITCase { throw new IllegalArgumentException("Proxy host and port not found in '%s'".formatted(text)); } + @Disabled @DisplayName("send message") @Nested class TestSendMessage { @@ -70,6 +74,29 @@ public class OsiPostfachRemoteServiceRemoteITCase { assertThatCode(() -> osiPostfachRemoteService.sendMessage(nachricht)) .doesNotThrowAnyException(); } + } + + @DisplayName("receive all messages") + @Nested + class TestReceiveAllMessages{ + + @Test + void shouldReceiveAllMessage(){ + Stream<PostfachNachricht> allMessages = osiPostfachRemoteService.getAllMessages(); + var messages = allMessages.toList(); + assertThat(messages.size() > 0); + } + } + + @Disabled + @DisplayName("delete message") + @Nested + class TestDeleteMessageById{ + @Test + void shouldDeleteMessage(){ + assertThatCode(() -> osiPostfachRemoteService.deleteMessage("5dd65c1e-bd41-4c3d-bf98-be769ca341dc")) + .doesNotThrowAnyException(); + } } } diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceTest.java index 2759035d7ff6c1a76a7bf31ed01f9cfe12fbfbf4..a00ab88ae8b7d18aa79a228c651d55ff472a8289 100644 --- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceTest.java +++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceTest.java @@ -3,6 +3,7 @@ package de.ozgcloud.nachrichten.postfach.osiv2; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; +import java.util.UUID; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; @@ -72,7 +73,21 @@ class OsiPostfachRemoteServiceTest { @DisplayName("delete message") @Nested class TestDeleteMessage { - // TODO + + @DisplayName("should call deleteMessage") + @Test + void shouldCallDeleteMessage() { + postfachApiFacadeService.deleteMessage(UUID.randomUUID().toString()); + + verify(postfachApiFacadeService).deleteMessage(any()); + } + @DisplayName("should throw osi postfach exception on runtime exception") + @Test + void shouldThrowOsiPostfachExceptionOnRuntimeException() { + doThrow(new RuntimeException()).when(postfachApiFacadeService).deleteMessage(UUID.randomUUID().toString()); + + assertThatThrownBy(() -> osiPostfachRemoteService.deleteMessage(anyString())).isInstanceOf(OsiPostfachException.class); + } } @DisplayName("get postfach type") diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/V1ReplyMessageFactory.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/V1ReplyMessageFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..61a52ac52df930ef3568e5c60d8e1b5a2f0f81d2 --- /dev/null +++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/V1ReplyMessageFactory.java @@ -0,0 +1,42 @@ +package de.ozgcloud.nachrichten.postfach.osiv2.factory; + +import java.time.OffsetDateTime; +import java.util.UUID; + +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1EidasLevel; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyBehavior; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyMessage; + +public class V1ReplyMessageFactory { + + private static String SEQUENCE_NUMMER = "OZG-Cloud-VorgangId"; + private static String SUBJECT = "Das ist das Subject"; + private static String BODY = """ + Das ist das Multiline + Body"""; + private static String DISPLAY_NAME = "Das ist der Absender"; + private static String ORIGIN_SENDER = "das ist der original Sender"; + private static String REPLAY_ACTION = "Replypossible"; + private static String EIDAS_LEVEL = "Low"; + private static Boolean IS_OLIGATORY = Boolean.FALSE; + private static Boolean IS_HTML = Boolean.FALSE; + private static String GUID = "123-guid-456"; + private static String MESSAGE_BOX = "Mailbox-Id-Antwortender"; + private static OffsetDateTime RESPONSE_TIME = OffsetDateTime.now(); + + public static V1ReplyMessage create() { + return new V1ReplyMessage() + .sequencenumber(SEQUENCE_NUMMER) + .subject(SUBJECT) + .body(BODY) + .displayName(DISPLAY_NAME) + .originSender(ORIGIN_SENDER) + .replyAction(V1ReplyBehavior.fromValue(REPLAY_ACTION)) + .eidasLevel(V1EidasLevel.fromValue(EIDAS_LEVEL)) + .isObligatory(IS_OLIGATORY) + .isHtml(IS_HTML) + .guid(UUID.nameUUIDFromBytes(GUID.getBytes())) + .messageBox(UUID.nameUUIDFromBytes(MESSAGE_BOX.getBytes())) + .responseTime(RESPONSE_TIME); + } +} diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java index 19e9ca36386476880d6d25d956840b7263da3e88..f8a3c19c34125ece0bf242dea493888a2fd2050c 100644 --- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java +++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java @@ -1,8 +1,11 @@ package de.ozgcloud.nachrichten.postfach.osiv2.transfer; import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachAddressTestFactory.*; +import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; +import java.util.UUID; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -13,8 +16,12 @@ import org.mockito.Mock; import de.ozgcloud.nachrichten.postfach.PostfachNachricht; import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory; import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MessageExchangeApi; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeDeleteMessageResponse; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeReceiveMessage; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeReceiveMessagesResponse; import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeSendMessageResponse; import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.OutSendMessageRequestV2; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyMessage; import reactor.core.publisher.Mono; class PostfachApiFacadeServiceTest { @@ -61,4 +68,84 @@ class PostfachApiFacadeServiceTest { } } + @DisplayName("receive messages") + @Nested + class TestReceiveMessage{ + + @Mock + MessageExchangeReceiveMessagesResponse messageExchangeReceiveMessagesResponse; + + @BeforeEach + void mock(){ + var responseMono = Mono.just(messageExchangeReceiveMessagesResponse); + when(messageExchangeApi.receiveMessages(anyInt(),anyInt())).thenReturn(responseMono); + } + + @Test + void responseShouldNotBeEmpty(){ + postfachApiFacadeService.receiveMessages(); + + verify(messageExchangeApi).receiveMessages(anyInt(), anyInt()); + } + } + + @DisplayName("fetch Message by guid") + @Nested + class TestFetchMessageByGuid{ + + @Mock + V1ReplyMessage replyMessage; + @Mock + MessageExchangeReceiveMessage receiveMessage; + + @Test + void shouldCallGetMessage(){ + var replyMono = Mono.just(replyMessage); + when(messageExchangeApi.getMessage(any())).thenReturn(replyMono); + + postfachApiFacadeService.fetchMessageByGuid(receiveMessage); + + verify(messageExchangeApi).getMessage(any()); + } + + @Test + void shouldCallResponseMapper(){ + var replyMono = Mono.just(replyMessage); + when(messageExchangeApi.getMessage(any())).thenReturn(replyMono); + when(responseMapper.toPostfachNachricht(any())).thenReturn(PostfachNachrichtTestFactory.create()); + + postfachApiFacadeService.fetchMessageByGuid(receiveMessage); + + verify(responseMapper).toPostfachNachricht(any()); + } + + @Test + void shouldReturnPostfachNachricht(){ + var replyMono = Mono.just(replyMessage); + when(messageExchangeApi.getMessage(any())).thenReturn(replyMono); + when(responseMapper.toPostfachNachricht(any())).thenReturn(PostfachNachrichtTestFactory.create()); + + var postfachNachricht = postfachApiFacadeService.fetchMessageByGuid(receiveMessage); + + assertThat(postfachNachricht).isInstanceOf(PostfachNachricht.class); + } + } + + @DisplayName("Delete Message") + @Nested + class TestDeleteMessage{ + @Mock + MessageExchangeDeleteMessageResponse replyMessage; + + @Test + void shouldCallDeleteMessage(){ + var replyMono = Mono.just(replyMessage); + when(messageExchangeApi.deleteMessage(any())).thenReturn(replyMono); + + postfachApiFacadeService.deleteMessage(UUID.randomUUID().toString()); + + verify(messageExchangeApi).deleteMessage(any()); + } + } + } \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/ResponseMapperTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/ResponseMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d4c8706356d03230611e185f639484e124b2601d --- /dev/null +++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/ResponseMapperTest.java @@ -0,0 +1,103 @@ +package de.ozgcloud.nachrichten.postfach.osiv2.transfer; + +import static org.assertj.core.api.Assertions.*; + +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.UUID; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; + +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.osiv2.factory.V1ReplyMessageFactory; +import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyMessage; + +class ResponseMapperTest { + + @InjectMocks + private ResponseMapper mapper = Mappers.getMapper(ResponseMapper.class); + private V1ReplyMessage message = V1ReplyMessageFactory.create(); + + @DisplayName("map V1ReplyMessage to PostfachNachricht") + @Nested + class V1ReplyMessageToPostfachNachricht { + @Test + void shouldHaveId(){ + var postfachNachricht = mapper.toPostfachNachricht(message); + + assertThat(postfachNachricht.getId()).isEqualTo(UUID.nameUUIDFromBytes("123-guid-456".getBytes()).toString()); + } + + @Test + void shouldHaveVorgangId(){ + var postfachNachricht = mapper.toPostfachNachricht(message); + + assertThat(postfachNachricht.getVorgangId()).isEqualTo("OZG-Cloud-VorgangId"); + } + + @Test + void shouldHavePostfachAddress(){ + var postfachNachricht = mapper.toPostfachNachricht(message); + + assertThat(postfachNachricht.getPostfachAddress().getIdentifier().toString()) + .hasToString(UUID.nameUUIDFromBytes("Mailbox-Id-Antwortender".getBytes()).toString()); + } + + @Test + void shouldHaveCreatedAt(){ + var postfachNachricht = mapper.toPostfachNachricht(message); + + assertThat(postfachNachricht.getCreatedAt()).isNotNull().isCloseTo(ZonedDateTime.now(), within(5, ChronoUnit.SECONDS)); + } + + @Test + void shouldHaveCreatedBy(){ + var postfachNachricht = mapper.toPostfachNachricht(message); + + assertThat(postfachNachricht.getCreatedBy()).isEqualTo("Das ist der Absender"); + } + + @Test + void shouldHaveSentAt(){ + var postfachNachricht = mapper.toPostfachNachricht(message); + + assertThat(postfachNachricht.getSentAt()).isNotNull().isCloseTo(ZonedDateTime.now(), within(5, ChronoUnit.SECONDS)); + } + + @Test + void shouldHaveDirection(){ + var postfachNachricht = mapper.toPostfachNachricht(message); + + assertThat(postfachNachricht.getDirection()).isEqualTo(PostfachNachricht.Direction.IN); + } + + @Test + void shouldHaveSubject(){ + var postfachNachricht = mapper.toPostfachNachricht(message); + + assertThat(postfachNachricht.getSubject()).isEqualTo("Das ist das Subject"); + } + + @Test + void shouldHaveBody(){ + var postfachNachricht = mapper.toPostfachNachricht(message); + + assertThat(postfachNachricht.getMailBody()).isEqualTo(""" + Das ist das Multiline + Body"""); + } + + @Test + void shouldHaveReplyOption(){ + var postfachNachricht = mapper.toPostfachNachricht(message); + + assertThat(postfachNachricht.getReplyOption()).isEqualTo(PostfachNachricht.ReplyOption.POSSIBLE); + } + +// TODO:prüfen das Attachments in der PostfachNachricht enthalten sind + } +}