From 308edc89e0015cdfdd52f555dedc8dc36b5844f4 Mon Sep 17 00:00:00 2001 From: Lukas Malte Monnerjahn <lukasmalte.monnerjahn@dataport.de> Date: Mon, 9 Sep 2024 15:45:29 +0200 Subject: [PATCH] OZG-6240 TransportReport Tests --- .../xta/test/app/config/XTAServer.java | 7 ++ .../data/XtaTransportReportRepository.java | 32 +++++++ .../xta/test/app/model/XtaCloseRequest.java | 1 - .../test/app/model/XtaGetMessageRequest.java | 1 - .../model/XtaGetTransportReportRequest.java | 16 ++++ .../XtaMessageMetaDataListingRequest.java | 1 - .../test/app/model/XtaTransportReport.java | 21 +++++ .../test/app/service/XtaMessageService.java | 27 ++++-- .../XtaTransportReportRepositoryTest.java | 90 +++++++++++++++++++ .../app/service/XtaMessageServiceTest.java | 83 ++++++++++++++--- 10 files changed, 258 insertions(+), 21 deletions(-) create mode 100644 src/main/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepository.java create mode 100644 src/main/java/de/ozgcloud/xta/test/app/model/XtaGetTransportReportRequest.java create mode 100644 src/main/java/de/ozgcloud/xta/test/app/model/XtaTransportReport.java create mode 100644 src/test/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepositoryTest.java diff --git a/src/main/java/de/ozgcloud/xta/test/app/config/XTAServer.java b/src/main/java/de/ozgcloud/xta/test/app/config/XTAServer.java index f5fd91b..dbd817b 100644 --- a/src/main/java/de/ozgcloud/xta/test/app/config/XTAServer.java +++ b/src/main/java/de/ozgcloud/xta/test/app/config/XTAServer.java @@ -1,5 +1,7 @@ package de.ozgcloud.xta.test.app.config; +import java.time.Clock; + import jakarta.xml.ws.Endpoint; import jakarta.xml.ws.soap.SOAPBinding; @@ -50,4 +52,9 @@ public class XTAServer { SOAPBinding binding = (SOAPBinding) endpoint.getBinding(); binding.setMTOMEnabled(true); } + + @Bean + Clock clock() { + return Clock.systemDefaultZone(); + } } diff --git a/src/main/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepository.java b/src/main/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepository.java new file mode 100644 index 0000000..4c05cb5 --- /dev/null +++ b/src/main/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepository.java @@ -0,0 +1,32 @@ +package de.ozgcloud.xta.test.app.data; + +import java.time.Clock; +import java.util.HashMap; +import java.util.Optional; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import de.ozgcloud.xta.test.app.model.XtaMessageMetaData; +import de.ozgcloud.xta.test.app.model.XtaTransportReport; + +@Component +@RequiredArgsConstructor +public class XtaTransportReportRepository { + private final HashMap<String, XtaTransportReport> transportReports = new HashMap<>(); + private final Clock clock; + + public void add(XtaMessageMetaData messageMetaData) { + // TODO Auto-generated method stub + + } + + public void setClosedStatus(String messageId) { + // TODO Auto-generated method stub + } + + public Optional<XtaTransportReport> get(String messageId) { + // TODO Auto-generated method stub + return Optional.empty(); + } +} diff --git a/src/main/java/de/ozgcloud/xta/test/app/model/XtaCloseRequest.java b/src/main/java/de/ozgcloud/xta/test/app/model/XtaCloseRequest.java index d6d2ac2..53a9727 100644 --- a/src/main/java/de/ozgcloud/xta/test/app/model/XtaCloseRequest.java +++ b/src/main/java/de/ozgcloud/xta/test/app/model/XtaCloseRequest.java @@ -3,7 +3,6 @@ package de.ozgcloud.xta.test.app.model; import static de.ozgcloud.xta.test.app.validation.ValidXtaId.*; import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import de.ozgcloud.xta.test.app.validation.ValidXtaId; diff --git a/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetMessageRequest.java b/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetMessageRequest.java index 443a9c6..8367465 100644 --- a/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetMessageRequest.java +++ b/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetMessageRequest.java @@ -3,7 +3,6 @@ package de.ozgcloud.xta.test.app.model; import static de.ozgcloud.xta.test.app.validation.ValidXtaId.*; import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import de.ozgcloud.xta.test.app.validation.ValidXtaId; diff --git a/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetTransportReportRequest.java b/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetTransportReportRequest.java new file mode 100644 index 0000000..0e0a5f1 --- /dev/null +++ b/src/main/java/de/ozgcloud/xta/test/app/model/XtaGetTransportReportRequest.java @@ -0,0 +1,16 @@ +package de.ozgcloud.xta.test.app.model; + +import static de.ozgcloud.xta.test.app.validation.ValidXtaId.*; + + import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +import de.ozgcloud.xta.test.app.validation.ValidXtaId; +import lombok.Builder; + +@Builder +public record XtaGetTransportReportRequest ( + @ValidXtaId(namespace = MESSAGE_ID_NAMESPACE) String messageId, + @NotNull @Valid XtaIdentifier clientIdentifier +) { +} diff --git a/src/main/java/de/ozgcloud/xta/test/app/model/XtaMessageMetaDataListingRequest.java b/src/main/java/de/ozgcloud/xta/test/app/model/XtaMessageMetaDataListingRequest.java index c19441d..d505196 100644 --- a/src/main/java/de/ozgcloud/xta/test/app/model/XtaMessageMetaDataListingRequest.java +++ b/src/main/java/de/ozgcloud/xta/test/app/model/XtaMessageMetaDataListingRequest.java @@ -1,7 +1,6 @@ package de.ozgcloud.xta.test.app.model; import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Positive; diff --git a/src/main/java/de/ozgcloud/xta/test/app/model/XtaTransportReport.java b/src/main/java/de/ozgcloud/xta/test/app/model/XtaTransportReport.java new file mode 100644 index 0000000..2c5fe2b --- /dev/null +++ b/src/main/java/de/ozgcloud/xta/test/app/model/XtaTransportReport.java @@ -0,0 +1,21 @@ +package de.ozgcloud.xta.test.app.model; + +import java.time.LocalDateTime; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; + +@Builder +public record XtaTransportReport( + @Valid XtaMessageMetaData messageMetaData, + @NotNull LocalDateTime reportTime, + @NotNull MessageStatus status) { + + public enum MessageStatus { + OFFEN, + GRUEN, + GELB, + ROT + } +} diff --git a/src/main/java/de/ozgcloud/xta/test/app/service/XtaMessageService.java b/src/main/java/de/ozgcloud/xta/test/app/service/XtaMessageService.java index 79864e4..8e4a953 100644 --- a/src/main/java/de/ozgcloud/xta/test/app/service/XtaMessageService.java +++ b/src/main/java/de/ozgcloud/xta/test/app/service/XtaMessageService.java @@ -9,18 +9,16 @@ import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; import de.ozgcloud.xta.test.app.data.XtaMessageRepository; -import de.ozgcloud.xta.test.app.model.XtaCloseRequest; -import de.ozgcloud.xta.test.app.model.XtaGetMessageRequest; -import de.ozgcloud.xta.test.app.model.XtaMessage; -import de.ozgcloud.xta.test.app.model.XtaMessageMetaData; -import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListing; -import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListingRequest; +import de.ozgcloud.xta.test.app.data.XtaTransportReportRepository; +import de.ozgcloud.xta.test.app.model.*; + import lombok.RequiredArgsConstructor; @Service @RequiredArgsConstructor public class XtaMessageService { private final XtaMessageRepository messageRepository; + private final XtaTransportReportRepository transportReportRepository; private final Environment environment; @@ -50,8 +48,7 @@ public class XtaMessageService { } Predicate<XtaMessage> isAuthorOrReaderOfMessage(String clientIdentifierValue) { - return m -> m.metaData().readerIdentifier().value().equals(clientIdentifierValue) - || m.metaData().authorIdentifier().value().equals(clientIdentifierValue); + return m -> isAuthorOrReaderOfMessageMetadata(clientIdentifierValue).test(m.metaData()); } public boolean closeMessage(XtaCloseRequest request) { @@ -61,6 +58,20 @@ public class XtaMessageService { ); } + public Optional<XtaTransportReport> getTransportReport(XtaGetTransportReportRequest request) { + return transportReportRepository.get(request.messageId()) + .filter(isAuthorOrReaderOfTransportReport(request.clientIdentifier().value())); + } + + Predicate<XtaTransportReport> isAuthorOrReaderOfTransportReport(String clientIdentifierValue) { + return tr -> isAuthorOrReaderOfMessageMetadata(clientIdentifierValue).test(tr.messageMetaData()); + } + + Predicate<XtaMessageMetaData> isAuthorOrReaderOfMessageMetadata(String clientIdentifierValue) { + return m -> m.readerIdentifier().value().equals(clientIdentifierValue) + || m.authorIdentifier().value().equals(clientIdentifierValue); + } + public String createMessageId() { return generateXtaIdWithNamespace("de:xta:messageid"); } diff --git a/src/test/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepositoryTest.java b/src/test/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepositoryTest.java new file mode 100644 index 0000000..51d147e --- /dev/null +++ b/src/test/java/de/ozgcloud/xta/test/app/data/XtaTransportReportRepositoryTest.java @@ -0,0 +1,90 @@ +package de.ozgcloud.xta.test.app.data; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import java.time.Clock; +import java.time.Instant; +import java.time.LocalDateTime; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import de.ozgcloud.xta.test.app.factory.XtaMessageMetaDataTestFactory; +import de.ozgcloud.xta.test.app.model.XtaMessageMetaData; +import de.ozgcloud.xta.test.app.model.XtaTransportReport; + +public class XtaTransportReportRepositoryTest { + private XtaTransportReportRepository repository; + @Mock + private Clock clock; + + private final XtaMessageMetaData messageMetaData = XtaMessageMetaDataTestFactory.create(); + + @BeforeEach + void beforeEach() { + repository = new XtaTransportReportRepository(clock); + } + + @Nested + class Add{ + @Test + void shouldAddTransportReport() { + repository.add(messageMetaData); + + var result = repository.get(messageMetaData.messageId()); + + assertThat(result).isPresent(); + assertThat(result.get().messageMetaData()).isEqualTo(messageMetaData); + } + } + + @Nested + class Get { + private final Instant instant = Instant.now(); + + @Test + void shouldReturnEmpty() { + var result = repository.get(messageMetaData.messageId()); + + assertThat(result).isEmpty(); + } + + @Test + void shouldSetStatusOffen() { + repository.add(messageMetaData); + + var result = repository.get(messageMetaData.messageId()); + + assertThat(result).isPresent(); + assertThat(result.get().status()).isEqualTo(XtaTransportReport.MessageStatus.OFFEN); + } + + @Test + void shouldSetReportTimeNow() { + when(clock.instant()).thenReturn(instant); + repository.add(messageMetaData); + + var result = repository.get(messageMetaData.messageId()); + + assertThat(result).isPresent(); + assertThat(result.get().reportTime()).isEqualTo(LocalDateTime.from(instant)); + } + } + + @Nested + class SetClosedStatus { + @Test + void shouldSetClosedStatus() { + repository.add(messageMetaData); + repository.setClosedStatus(messageMetaData.messageId()); + + var result = repository.get(messageMetaData.messageId()); + + assertThat(result).isPresent(); + assertThat(result.get().status()).isEqualTo(XtaTransportReport.MessageStatus.GRUEN); + } + } +} diff --git a/src/test/java/de/ozgcloud/xta/test/app/service/XtaMessageServiceTest.java b/src/test/java/de/ozgcloud/xta/test/app/service/XtaMessageServiceTest.java index 6723c0e..14bef27 100644 --- a/src/test/java/de/ozgcloud/xta/test/app/service/XtaMessageServiceTest.java +++ b/src/test/java/de/ozgcloud/xta/test/app/service/XtaMessageServiceTest.java @@ -23,17 +23,18 @@ import org.mockito.Spy; import org.springframework.core.env.Environment; import de.ozgcloud.xta.test.app.data.XtaMessageRepository; +import de.ozgcloud.xta.test.app.data.XtaTransportReportRepository; import de.ozgcloud.xta.test.app.factory.XtaCloseRequestTestFactory; +import de.ozgcloud.xta.test.app.factory.XtaMessageMetaDataTestFactory; import de.ozgcloud.xta.test.app.factory.XtaMessageTestFactory; -import de.ozgcloud.xta.test.app.model.XtaGetMessageRequest; -import de.ozgcloud.xta.test.app.model.XtaMessage; -import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListing; -import de.ozgcloud.xta.test.app.model.XtaMessageMetaDataListingRequest; +import de.ozgcloud.xta.test.app.model.*; public class XtaMessageServiceTest { @Mock private XtaMessageRepository messageRepository; @Mock + private XtaTransportReportRepository transportReportRepository; + @Mock private Environment environment; @Spy @@ -50,6 +51,15 @@ public class XtaMessageServiceTest { message = XtaMessageTestFactory.create(MESSAGE_ID); } + @Test + void shouldSaveTransportReport() { + message = XtaMessageTestFactory.create(MESSAGE_ID); + + service.sendMessage(message); + + verify(transportReportRepository).add(message.metaData()); + } + @Test void shouldSaveMessage() { message = XtaMessageTestFactory.create(MESSAGE_ID); @@ -157,9 +167,9 @@ public class XtaMessageServiceTest { @DisplayName("should return true if reader identifier value matches") @Test void shouldReturnTrueIfReaderIdentifierValueMatches() { - var message = XtaMessageTestFactory.create(MESSAGE_ID_1); + var messageMetaData = XtaMessageMetaDataTestFactory.create(MESSAGE_ID_1); - var result = service.isAuthorOrReaderOfMessage(READER_IDENTIFIER.value()).test(message); + var result = service.isAuthorOrReaderOfMessageMetadata(READER_IDENTIFIER.value()).test(messageMetaData); assertThat(result).isTrue(); } @@ -167,9 +177,9 @@ public class XtaMessageServiceTest { @DisplayName("should return true if author identifier value matches") @Test void shouldReturnTrueIfAuthorIdentifierValueMatches() { - var message = XtaMessageTestFactory.create(MESSAGE_ID_1); + var messageMetaData = XtaMessageMetaDataTestFactory.create(MESSAGE_ID_1); - var result = service.isAuthorOrReaderOfMessage(AUTHOR_IDENTIFIER.value()).test(message); + var result = service.isAuthorOrReaderOfMessageMetadata(AUTHOR_IDENTIFIER.value()).test(messageMetaData); assertThat(result).isTrue(); } @@ -177,9 +187,9 @@ public class XtaMessageServiceTest { @DisplayName("should return false if neither reader nor author identifier value matches") @Test void shouldReturnFalseIfNeitherReaderNorAuthorIdentifierValueMatches() { - var message = XtaMessageTestFactory.create(MESSAGE_ID_1); + var messageMetaData = XtaMessageMetaDataTestFactory.create(MESSAGE_ID_1); - var result = service.isAuthorOrReaderOfMessage("unknown").test(message); + var result = service.isAuthorOrReaderOfMessageMetadata("unknown").test(messageMetaData); assertThat(result).isFalse(); } @@ -201,7 +211,60 @@ public class XtaMessageServiceTest { boolean result = service.closeMessage(request); assertThat(result).isEqualTo(deleted); + } + + @Test + void shouldSetTransportReportClosedStatus() { + var request = XtaCloseRequestTestFactory.create(); + + service.closeMessage(request); + + verify(transportReportRepository).setClosedStatus(request.messageId()); + } + } + + @Nested + class TestGetTransportReport { + private static final XtaGetTransportReportRequest GET_TRANSPORT_REPORT_REQUEST = XtaGetTransportReportRequest.builder() + .messageId(MESSAGE_ID_1) + .clientIdentifier(READER_IDENTIFIER) + .build(); + private static final Predicate<XtaMessage> IS_AUTHOR_OR_READER = m -> true; + private static final Predicate<XtaMessage> IS_NOT_AUTHOR_OR_READER = m -> false; + + @Mock + XtaTransportReport report; + + @DisplayName("should return") + @Test + void shouldReturn() { + when(transportReportRepository.get(MESSAGE_ID_1)).thenReturn(Optional.of(report)); + doReturn(IS_AUTHOR_OR_READER).when(service).isAuthorOrReaderOfMessage(READER_IDENTIFIER.value()); + + var result = service.getTransportReport(GET_TRANSPORT_REPORT_REQUEST); + + assertThat(result).contains(report); + } + + @DisplayName("should return empty if message id not found") + @Test + void shouldReturnEmptyIfMessageIdNotFound() { + when(transportReportRepository.get(MESSAGE_ID_1)).thenReturn(Optional.empty()); + + var result = service.getTransportReport(GET_TRANSPORT_REPORT_REQUEST); + + assertThat(result).isEmpty(); + } + + @DisplayName("should return empty if not author or reader") + @Test + void shouldReturnEmptyIfNotAuthorOrReader() { + when(transportReportRepository.get(MESSAGE_ID_1)).thenReturn(Optional.of(report)); + doReturn(IS_NOT_AUTHOR_OR_READER).when(service).isAuthorOrReaderOfMessage(READER_IDENTIFIER.value()); + + var result = service.getTransportReport(GET_TRANSPORT_REPORT_REQUEST); + assertThat(result).isEmpty(); } } -- GitLab