diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumGrpcService.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumGrpcService.java index fc8b30283be549db5c634fdc032b169cd3017348..116ae08168d70b8c5eae218c4af91abcbccea2bf 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumGrpcService.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumGrpcService.java @@ -24,6 +24,7 @@ package de.ozgcloud.nachrichten.antragraum; import java.time.ZonedDateTime; +import java.util.List; import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; @@ -44,26 +45,41 @@ class AntragraumGrpcService extends AntragraumServiceGrpc.AntragraumServiceImplB @Override public void findRueckfragen(GrpcFindRueckfragenRequest request, StreamObserver<GrpcFindRueckfragenResponse> streamObserver) { var rueckfragen = buildGrpcRueckfrage(request.getSamlToken()); - var response = GrpcFindRueckfragenResponse.newBuilder().addAllRueckfrage(rueckfragen.toList()).build(); - streamObserver.onNext(response); + streamObserver.onNext(buildFindRueckfragenResponse(rueckfragen)); streamObserver.onCompleted(); } - Stream<GrpcRueckfrage> buildGrpcRueckfrage(String samlToken) { - return antragraumService.findRueckfragen(samlToken).map(mapper::toGrpc) + private Stream<GrpcRueckfrage> buildGrpcRueckfrage(String samlToken) { + return antragraumService.findRueckfragen(samlToken) + .map(mapper::toGrpc) .map(rueckfrage -> addAnswers(samlToken, rueckfrage)); } - private GrpcRueckfrage addAnswers(String samlToken, GrpcRueckfrage rueckfrage) { + GrpcRueckfrage addAnswers(String samlToken, GrpcRueckfrage rueckfrage) { + var rueckfrageAnswer = buildGrpcRueckfrageAnswer(samlToken, rueckfrage.getId()); return rueckfrage.toBuilder() - .addAllAnswers(buildGrpcRueckfrageAnswer(samlToken, rueckfrage.getId()).toList()) + .addAllAnswers(rueckfrageAnswer) + .setAnsweredAt(getAnsweredAt(rueckfrageAnswer)) .build(); } - Stream<GrpcRueckfrageAnswer> buildGrpcRueckfrageAnswer(String samlToken, String rueckfrageId) { - return antragraumService.findAnswers(samlToken, rueckfrageId).map(mapper::toRueckfrageAnswer); + List<GrpcRueckfrageAnswer> buildGrpcRueckfrageAnswer(String samlToken, String rueckfrageId) { + return antragraumService.findAnswers(samlToken, rueckfrageId).map(mapper::toRueckfrageAnswer).toList(); + } + + String getAnsweredAt(List<GrpcRueckfrageAnswer> rueckfrageAnswers) { + return rueckfrageAnswers.stream().map(GrpcRueckfrageAnswer::getSentAt) + .sorted(new ZonedDateTimeStringComparator()) + .findFirst() + .orElseGet(() -> StringUtils.EMPTY); + + } + + private GrpcFindRueckfragenResponse buildFindRueckfragenResponse(Stream<GrpcRueckfrage> rueckfragen) { + return GrpcFindRueckfragenResponse.newBuilder().addAllRueckfrage(rueckfragen.toList()).build(); + } @Override diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/ZonedDateTimeStringComparator.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/ZonedDateTimeStringComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..027423f71250a830a552eccc37a0756d489fa682 --- /dev/null +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/ZonedDateTimeStringComparator.java @@ -0,0 +1,12 @@ +package de.ozgcloud.nachrichten.antragraum; + +import java.time.ZonedDateTime; +import java.util.Comparator; + +class ZonedDateTimeStringComparator implements Comparator<String> { + + @Override + public int compare(String object1, String object2) { + return ZonedDateTime.parse(object1).compareTo(ZonedDateTime.parse(object2)); + } +} diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumGrpcServiceTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumGrpcServiceTest.java index e14177a773180e00b35acb87b676af648a5eb2e2..bb4cb7b49e49718fce1fc129c888e5a237521f0f 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumGrpcServiceTest.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumGrpcServiceTest.java @@ -26,9 +26,11 @@ import static org.mockito.Mockito.*; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; +import java.util.List; import java.util.UUID; import java.util.stream.Stream; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -44,53 +46,92 @@ import io.grpc.stub.StreamObserver; class AntragraumGrpcServiceTest { @Spy @InjectMocks - private AntragraumGrpcService antragsraumGrpcService; + private AntragraumGrpcService grpcService; @Mock - private AntragraumService antragraumService; + private AntragraumService service; @Mock - private AntragraumNachrichtMapper mapper; + private AntragraumNachrichtMapper nachrichtMapper; @Nested class TestFindRueckfragen { - @Nested - class TestFindRueckfrageGrpc { - @Mock - private StreamObserver<GrpcFindRueckfragenResponse> streamObserver; + @Mock + private StreamObserver<GrpcFindRueckfragenResponse> streamObserver; - @BeforeEach - void setup() { - when(antragraumService.findRueckfragen(any())).thenReturn(Stream.of(PostfachNachrichtTestFactory.create())); - when(mapper.toGrpc(any(PostfachNachricht.class))).thenReturn(GrpcRueckfrageTestFactory.create()); - } + @BeforeEach + void setup() { + when(service.findRueckfragen(any())).thenReturn(Stream.of(PostfachNachrichtTestFactory.create())); + when(nachrichtMapper.toGrpc(any(PostfachNachricht.class))).thenReturn(GrpcRueckfrageTestFactory.create()); + } - @Test - void shouldCallMapper() { - antragsraumGrpcService.findRueckfragen(GrpcFindRueckfrageRequestTestFactory.create(), streamObserver); + @Test + void shouldCallMapper() { + grpcService.findRueckfragen(GrpcFindRueckfrageRequestTestFactory.create(), streamObserver); - verify(mapper).toGrpc(any(PostfachNachricht.class)); - } + verify(nachrichtMapper).toGrpc(any(PostfachNachricht.class)); + } - @Test - void shouldCallOnNext() { - antragsraumGrpcService.findRueckfragen(GrpcFindRueckfrageRequestTestFactory.create(), streamObserver); + @Test + void shouldCallOnNext() { + grpcService.findRueckfragen(GrpcFindRueckfrageRequestTestFactory.create(), streamObserver); - verify(streamObserver).onNext(any(GrpcFindRueckfragenResponse.class)); - } + verify(streamObserver).onNext(any(GrpcFindRueckfragenResponse.class)); + } - @Test - void shouldCallOnCompleted() { - antragsraumGrpcService.findRueckfragen(GrpcFindRueckfrageRequestTestFactory.create(), streamObserver); + @Test + void shouldCallOnCompleted() { + grpcService.findRueckfragen(GrpcFindRueckfrageRequestTestFactory.create(), streamObserver); + + verify(streamObserver).onCompleted(); + } - verify(streamObserver).onCompleted(); - } + @Test + void shouldLoadAnswers() { + grpcService.findRueckfragen(GrpcFindRueckfrageRequestTestFactory.create(), streamObserver); + + verify(service).findAnswers(GrpcFindRueckfrageRequestTestFactory.SAML_TOKEN, GrpcRueckfrageTestFactory.ID); + } + } - @Test - void shouldLoadAnswers() { - antragsraumGrpcService.findRueckfragen(GrpcFindRueckfrageRequestTestFactory.create(), streamObserver); + @DisplayName("Add answer") + @Nested + class TestAddAnswer { + + private static final String SAML_TOKEN = ""; + private static final String LATEST_SENT_AT = "2024-01-01T10:00:10Z"; + + private final GrpcRueckfrage rueckfrage = GrpcRueckfrageTestFactory.createBuilder().setAnsweredAt(StringUtils.EMPTY).build(); + + private final GrpcRueckfrageAnswer rueckfrageAnswer = GrpcRueckfrageAnswerTestFactory.create(); + private final List<GrpcRueckfrageAnswer> rueckfrageAnswers = List.of(rueckfrageAnswer); + + @BeforeEach + void mock() { + doReturn(List.of(rueckfrageAnswer)).when(grpcService).buildGrpcRueckfrageAnswer(any(), any()); + doReturn(LATEST_SENT_AT).when(grpcService).getAnsweredAt(any()); + } + + @Test + void shouldCallGetAnsweredAt() { + grpcService.addAnswers(SAML_TOKEN, rueckfrage); + + verify(grpcService).getAnsweredAt(rueckfrageAnswers); + } + } + + @DisplayName("Get answeredAt") + @Nested + class TestGetAnsweredAt { + private GrpcRueckfrageAnswer rueckfrageAnswer = GrpcRueckfrageAnswerTestFactory.create(); + private GrpcRueckfrageAnswer rueckfrageAnswer2 = GrpcRueckfrageAnswerTestFactory.createBuilder() + .setSentAt("2024-01-01T10:00:10Z") + .build(); + + @Test + void shouldSetAnsweredAt() { + var answeredAt = grpcService.getAnsweredAt(List.of(rueckfrageAnswer, rueckfrageAnswer2)); - verify(antragraumService).findAnswers(GrpcFindRueckfrageRequestTestFactory.SAML_TOKEN, GrpcRueckfrageTestFactory.ID); - } + assertThat(answeredAt).isEqualTo(PostfachNachrichtTestFactory.SENT_AT_STR); } } @@ -103,25 +144,25 @@ class AntragraumGrpcServiceTest { @BeforeEach void setup() { - when(mapper.fromRueckfrageAnswer(any(GrpcRueckfrageAnswer.class))).thenReturn(postfachNachricht); - when(antragraumService.sendRueckfrageAnswer(anyString(), anyString(), any(PostfachNachricht.class))) + when(nachrichtMapper.fromRueckfrageAnswer(any(GrpcRueckfrageAnswer.class))).thenReturn(postfachNachricht); + when(service.sendRueckfrageAnswer(anyString(), anyString(), any(PostfachNachricht.class))) .thenReturn(UUID.randomUUID().toString()); - doReturn(postfachNachricht).when(antragsraumGrpcService).enrichRueckfrageAnswer(any(), any()); - doReturn(postfachNachricht).when(antragsraumGrpcService).getRueckfrage(any(), any()); + doReturn(postfachNachricht).when(grpcService).enrichRueckfrageAnswer(any(), any()); + doReturn(postfachNachricht).when(grpcService).getRueckfrage(any(), any()); } @Test void shouldCallMapper() { - antragsraumGrpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); + grpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); - verify(mapper).fromRueckfrageAnswer(any(GrpcRueckfrageAnswer.class)); + verify(nachrichtMapper).fromRueckfrageAnswer(any(GrpcRueckfrageAnswer.class)); } @Test void shouldGetRueckfrage() { sendRueckfrageAnswer(); - verify(antragsraumGrpcService).getRueckfrage(GrpcSendRueckfrageAnswerRequestTestFactory.SAML_TOKEN, + verify(grpcService).getRueckfrage(GrpcSendRueckfrageAnswerRequestTestFactory.SAML_TOKEN, GrpcRueckfrageAnswerTestFactory.RUECKFRAGE_ID); } @@ -129,32 +170,32 @@ class AntragraumGrpcServiceTest { void shouldEnrichPostfachNachricht() { sendRueckfrageAnswer(); - verify(antragsraumGrpcService).enrichRueckfrageAnswer(postfachNachricht, postfachNachricht); + verify(grpcService).enrichRueckfrageAnswer(postfachNachricht, postfachNachricht); } @Test void shouldCallAntragraumService() { - antragsraumGrpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); + grpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); - verify(antragraumService).sendRueckfrageAnswer(anyString(), anyString(), any(PostfachNachricht.class)); + verify(service).sendRueckfrageAnswer(anyString(), anyString(), any(PostfachNachricht.class)); } @Test void shouldCallOnNext() { - antragsraumGrpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); + grpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); verify(streamObserver).onNext(any(GrpcSendRueckfrageAnswerResponse.class)); } @Test void shouldCallOnCompleted() { - antragsraumGrpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); + grpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); verify(streamObserver).onCompleted(); } private void sendRueckfrageAnswer() { - antragsraumGrpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); + grpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); } } @@ -169,14 +210,14 @@ class AntragraumGrpcServiceTest { @BeforeEach void mock() { - when(antragraumService.findRueckfragen(any())).thenReturn(Stream.of(postfachNachricht, matchingPostfachNachricht)); + when(service.findRueckfragen(any())).thenReturn(Stream.of(postfachNachricht, matchingPostfachNachricht)); } @Test void shouldCallService() { getRueckfrage(); - verify(antragraumService).findRueckfragen(GrpcSendRueckfrageAnswerRequestTestFactory.SAML_TOKEN); + verify(service).findRueckfragen(GrpcSendRueckfrageAnswerRequestTestFactory.SAML_TOKEN); } @Test @@ -187,7 +228,7 @@ class AntragraumGrpcServiceTest { } private PostfachNachricht getRueckfrage() { - return antragsraumGrpcService.getRueckfrage(GrpcSendRueckfrageAnswerRequestTestFactory.SAML_TOKEN, + return grpcService.getRueckfrage(GrpcSendRueckfrageAnswerRequestTestFactory.SAML_TOKEN, GrpcRueckfrageAnswerTestFactory.RUECKFRAGE_ID); } } @@ -206,21 +247,21 @@ class AntragraumGrpcServiceTest { @Test void shouldSetVorgangId() { - var enrichedPostfachNachricht = antragsraumGrpcService.enrichRueckfrageAnswer(postfachNachrichtToEnrich, postfachNachrichtRueckfrage); + var enrichedPostfachNachricht = grpcService.enrichRueckfrageAnswer(postfachNachrichtToEnrich, postfachNachrichtRueckfrage); assertThat(enrichedPostfachNachricht.getVorgangId()).isEqualTo(postfachNachrichtRueckfrage.getVorgangId()); } @Test void shouldSetPostfachAddresses() { - var enrichedPostfachNachricht = antragsraumGrpcService.enrichRueckfrageAnswer(postfachNachrichtToEnrich, postfachNachrichtRueckfrage); + var enrichedPostfachNachricht = grpcService.enrichRueckfrageAnswer(postfachNachrichtToEnrich, postfachNachrichtRueckfrage); assertThat(enrichedPostfachNachricht.getPostfachAddress()).isEqualTo(postfachNachrichtRueckfrage.getPostfachAddress()); } @Test void shouldSetSentAt() { - var enrichedPostfachNachricht = antragsraumGrpcService.enrichRueckfrageAnswer(postfachNachrichtToEnrich, postfachNachrichtRueckfrage); + var enrichedPostfachNachricht = grpcService.enrichRueckfrageAnswer(postfachNachrichtToEnrich, postfachNachrichtRueckfrage); assertThat(enrichedPostfachNachricht.getSentAt()).isCloseTo(ZonedDateTime.now(), within(2, ChronoUnit.SECONDS)); } diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/ZonedDateTimeStringComparatorTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/ZonedDateTimeStringComparatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4a3dbadb286c1aa848999ae6d53375c8729064ea --- /dev/null +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/ZonedDateTimeStringComparatorTest.java @@ -0,0 +1,38 @@ +package de.ozgcloud.nachrichten.antragraum; + +import static org.assertj.core.api.Assertions.*; + +import java.util.stream.Stream; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class ZonedDateTimeStringComparatorTest { + + private final ZonedDateTimeStringComparator comparator = new ZonedDateTimeStringComparator(); + + private static final String earlyZonedDateTime = "2020-01-01T10:00:10Z"; + private static final String lateZonedDateTime = "2021-01-01T10:00:10Z"; + + @Nested + class TestCompare { + + @Test + void testIt() { + var sorted = Stream.of(earlyZonedDateTime, lateZonedDateTime).sorted(comparator); + + assertThat(sorted).containsExactly(earlyZonedDateTime, lateZonedDateTime); + } + } + + @Nested + class TestCompareReverse { + @Test + void testIt() { + var sorted = Stream.of(earlyZonedDateTime, lateZonedDateTime).sorted(comparator.reversed()); + + assertThat(sorted).containsExactly(lateZonedDateTime, earlyZonedDateTime); + } + } + +}