diff --git a/nachrichten-manager-interface/src/main/protobuf/postfach.model.proto b/nachrichten-manager-interface/src/main/protobuf/postfach.model.proto index e87eec8e340a95af400bcfa5692cfafd8b9e10c2..d3cfc107e10928b5897a651ae549a2dbf746072f 100644 --- a/nachrichten-manager-interface/src/main/protobuf/postfach.model.proto +++ b/nachrichten-manager-interface/src/main/protobuf/postfach.model.proto @@ -100,6 +100,7 @@ message GrpcPostfachMail { string replyOption = 12; repeated string attachment = 13; GrpcPostfachAddress address = 15; + string referencedNachricht = 16; } message GrpcPostfachAddress { diff --git a/nachrichten-manager-interface/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachMailTestFactory.java b/nachrichten-manager-interface/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachMailTestFactory.java index 1ef63b22e64243eec02001eaa6a22aaee3255360..cb6eccfb3ba9f3e01d5b6917de337b63aaed8ffe 100644 --- a/nachrichten-manager-interface/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachMailTestFactory.java +++ b/nachrichten-manager-interface/src/test/java/de/ozgcloud/nachrichten/postfach/GrpcPostfachMailTestFactory.java @@ -30,6 +30,7 @@ public class GrpcPostfachMailTestFactory { public static final String ID = UUID.randomUUID().toString(); public static final String VORGANG_ID = UUID.randomUUID().toString(); + public static final String REFERENCED_NACHRICHT_ID = UUID.randomUUID().toString(); public static final String POSTFACH_ID = UUID.randomUUID().toString(); public static final String CREATED_AT = "2020-04-01T10:30:10Z"; public static final String CREATED_BY = UUID.randomUUID().toString(); @@ -49,6 +50,7 @@ public class GrpcPostfachMailTestFactory { public static GrpcPostfachMail.Builder createBuilder() { return GrpcPostfachMail.newBuilder() .setId(ID) + .setReferencedNachricht(REFERENCED_NACHRICHT_ID) .setVorgangId(VORGANG_ID) .setPostfachId(POSTFACH_ID) .setPostfachAddress(GrpcPostfachAddressTestFactory.create()) diff --git a/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java b/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java index 5468779b919023df12dbaf2b2d7fcabebccede81..584087077f71ab050b40ded62ea45d73886d2e82 100644 --- a/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java +++ b/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java @@ -45,6 +45,7 @@ public class PostfachNachricht { public static final String FIELD_POSTFACH_ID = "postfachId"; public static final String POSTFACH_ADDRESS_FIELD = "postfachAddress"; + public static final String REFERENCED_NACHRICHT_FIELD = "referencedNachricht"; public static final String FIELD_MESSAGE_ID = "messageId"; public static final String FIELD_CREATED_AT = "createdAt"; @@ -69,6 +70,7 @@ public class PostfachNachricht { private String postfachId; private PostfachAddress postfachAddress; private String messageId; + private String referencedNachricht; @Builder.Default private ZonedDateTime createdAt = ZonedDateTime.now().withNano(0); diff --git a/nachrichten-manager-server/pom.xml b/nachrichten-manager-server/pom.xml index 48afbcd1ebc8bef5d68889bef99b22e2559b8e61..15bdc72d1c54b3f78fe1f1d347ba4c62782e0c2d 100644 --- a/nachrichten-manager-server/pom.xml +++ b/nachrichten-manager-server/pom.xml @@ -47,6 +47,7 @@ <bayernid-proxy-interface.version>0.1.0</bayernid-proxy-interface.version> <vorgang-manager.version>2.8.0</vorgang-manager.version> <muk-postfach.version>0.1.0-SNAPSHOT</muk-postfach.version> + <ozgcloud-starter.version>0.10.0-SNAPSHOT</ozgcloud-starter.version> </properties> <dependencies> @@ -85,6 +86,12 @@ <artifactId>muk-postfach</artifactId> <version>${muk-postfach.version}</version> </dependency> + + <dependency> + <groupId>de.ozgcloud.api-lib</groupId> + <artifactId>ozg-cloud-spring-boot-starter</artifactId> + <version>${ozgcloud-starter.version}</version> + </dependency> <dependency> <groupId>de.ozgcloud.info</groupId> diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerCallContextProvider.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerCallContextProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..c64af3e512b11fece4881f0875c96b738561622d --- /dev/null +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerCallContextProvider.java @@ -0,0 +1,18 @@ +package de.ozgcloud.nachrichten; + +import org.springframework.stereotype.Component; + +import de.ozgcloud.apilib.common.callcontext.CallContext; +import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider; +import de.ozgcloud.nachrichten.common.grpc.NachrichtenCallContextAttachingInterceptor; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +class NachrichtenManagerCallContextProvider implements OzgCloudCallContextProvider { + + @Override + public CallContext provideContext() { + return CallContext.builder().clientName(NachrichtenCallContextAttachingInterceptor.NACHRICHTEN_MANAGER_CLIENT_NAME).build(); + } +} \ No newline at end of file diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerConfiguration.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..6ecace8ab50e3303e56ee0f77f42d36144c9827a --- /dev/null +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerConfiguration.java @@ -0,0 +1,25 @@ +package de.ozgcloud.nachrichten; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import de.ozgcloud.apilib.common.command.OzgCloudCommandService; +import de.ozgcloud.apilib.common.command.grpc.CommandMapper; +import de.ozgcloud.apilib.common.command.grpc.GrpcOzgCloudCommandService; +import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Configuration +public class NachrichtenManagerConfiguration { + + public static final String OZG_CLOUD_COMMAND_SERVICE_NAME = "nachrichten_OzgCloudCommandService"; + + @GrpcClient("command-manager") + private CommandServiceGrpc.CommandServiceBlockingStub commandServiceStub; + + @Bean(OZG_CLOUD_COMMAND_SERVICE_NAME) + OzgCloudCommandService grpcOzgCloudCommandService(CommandMapper commandMapper, NachrichtenManagerCallContextProvider contextProvider) { + return new GrpcOzgCloudCommandService(commandServiceStub, commandMapper, contextProvider, + GrpcOzgCloudCommandService.DEFAULT_COMMAND_REQUEST_THRESHOLD_MILLIS); + } +} \ No newline at end of file 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 45f6901b9a2f7089c36d3943e013962b0a834f2f..28bc1da4fcb0c0f316144a454a2bc29b72399904 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 @@ -23,10 +23,13 @@ package de.ozgcloud.nachrichten.antragraum; +import java.util.stream.Stream; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; + import io.grpc.stub.StreamObserver; import lombok.RequiredArgsConstructor; import net.devh.boot.grpc.server.service.GrpcService; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @GrpcService @RequiredArgsConstructor @@ -37,18 +40,35 @@ class AntragraumGrpcService extends AntragraumServiceGrpc.AntragraumServiceImplB @Override public void findRueckfragen(GrpcFindRueckfragenRequest request, StreamObserver<GrpcFindRueckfragenResponse> streamObserver) { - var rueckfragen = antragraumService.findRueckfragen(request.getSamlToken()).map(mapper::toGrpc).toList(); - var response = GrpcFindRueckfragenResponse.newBuilder().addAllRueckfrage(rueckfragen).build(); + var rueckfragen = buildGrpcRueckfrage(request.getSamlToken()); + var response = GrpcFindRueckfragenResponse.newBuilder().addAllRueckfrage(rueckfragen.toList()).build(); streamObserver.onNext(response); streamObserver.onCompleted(); } + Stream<GrpcRueckfrage> buildGrpcRueckfrage(String samlToken) { + return antragraumService.findRueckfragen(samlToken).map(mapper::toGrpc) + .map(rueckfrage -> addAnswers(samlToken, rueckfrage)); + + } + + private GrpcRueckfrage addAnswers(String samlToken, GrpcRueckfrage rueckfrage) { + return rueckfrage.toBuilder() + .addAllAnswers(buildGrpcRueckfrageAnswer(samlToken, rueckfrage.getId()).toList()) + .build(); + } + + Stream<GrpcRueckfrageAnswer> buildGrpcRueckfrageAnswer(String samlToken, String rueckfrageId) { + return antragraumService.findAnswers(samlToken, rueckfrageId).map(mapper::toRueckfrageAnswer); + } + @Override public void sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequest request, StreamObserver<GrpcSendRueckfrageAnswerResponse> streamObserver) { var answer = request.getAnswer(); - var commandId = antragraumService.sendRueckfrageAnswer(request.getSamlToken(), answer.getRueckfrageId(), mapper.toPostfachNachricht(answer)); + var commandId = antragraumService.sendRueckfrageAnswer(request.getSamlToken(), answer.getRueckfrageId(), + mapper.fromRueckfrageAnswer(answer)); streamObserver.onNext(GrpcSendRueckfrageAnswerResponse.newBuilder().setCommandId(commandId).build()); streamObserver.onCompleted(); diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumNachrichtMapper.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumNachrichtMapper.java index cb54984efbb573241ed2aeca1fc2f08fc56d2e8e..3946bb3f7691e4a76d198e667ec879a2fb645ce3 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumNachrichtMapper.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumNachrichtMapper.java @@ -35,6 +35,24 @@ import de.ozgcloud.nachrichten.postfach.PostfachNachricht; interface AntragraumNachrichtMapper { String DEFAULT_STATUS = "NEU"; + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "clearField", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "removeAnswers", ignore = true) + @Mapping(target = "answeredAt", ignore = true) + @Mapping(target = "answeredAtBytes", ignore = true) + @Mapping(target = "idBytes", ignore = true) + @Mapping(target = "sentAtBytes", ignore = true) + @Mapping(target = "statusBytes", ignore = true) + @Mapping(target = "textBytes", ignore = true) + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "vorgangIdBytes", ignore = true) + @Mapping(target = "vorgangNameBytes", ignore = true) + @Mapping(target = "allFields", ignore = true) + @Mapping(target = "answersBuilderList", ignore = true) + @Mapping(target = "answersList", ignore = true) + @Mapping(target = "answersOrBuilderList", ignore = true) @Mapping(source = "sentAt", target = "sentAt", dateFormat = "yyyy-MM-dd'T'HH:mm:ss") @Mapping(source = "mailBody", target = "text") @Mapping(source = "subject", target = "vorgangName") @@ -42,20 +60,34 @@ interface AntragraumNachrichtMapper { @Mapping(target = "status", constant = DEFAULT_STATUS) GrpcRueckfrage toGrpc(PostfachNachricht postfachNachricht); + @Mapping(target = "referencedNachricht", ignore = true) @Mapping(target = "mailBody", source = "answerText") @Mapping(target = "attachments", source = "attachmentFileIdList") - @Mapping(target = "createdAt", ignore = true) - @Mapping(target = "createdBy", ignore = true) - @Mapping(target = "direction", ignore = true) + @Mapping(target = "createdAt", ignore = true) // FIXME + @Mapping(target = "createdBy", ignore = true) // FIXME + @Mapping(target = "direction", constant = "IN") @Mapping(target = "id", ignore = true) @Mapping(target = "messageCode", ignore = true) @Mapping(target = "messageId", source = "rueckfrageId") - @Mapping(target = "postfachAddress", ignore = true) + @Mapping(target = "postfachAddress", ignore = true) // FIXME rueckfrage laden, befüllen @Mapping(target = "postfachId", ignore = true) - @Mapping(target = "replyOption", ignore = true) - @Mapping(target = "sentAt", ignore = true) - @Mapping(target = "sentSuccessful", ignore = true) - @Mapping(target = "subject", ignore = true) - @Mapping(target = "vorgangId", ignore = true) - PostfachNachricht toPostfachNachricht(GrpcRueckfrageAnswer answer); + @Mapping(target = "replyOption", constant = "FORBIDDEN") + @Mapping(target = "sentAt", ignore = true) // FIXME + @Mapping(target = "sentSuccessful", constant = "true") + @Mapping(target = "subject", constant = "Antwort") // TODO klären + @Mapping(target = "vorgangId", ignore = true) // FIXME rueckfrage laden, befüllen + PostfachNachricht fromRueckfrageAnswer(GrpcRueckfrageAnswer answer); + + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "clearField", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "answerText", source = "mailBody") + @Mapping(target = "answerTextBytes", ignore = true) + @Mapping(target = "rueckfrageId", source = "id") + @Mapping(target = "rueckfrageIdBytes", ignore = true) + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "allFields", ignore = true) + @Mapping(target = "attachmentFileIdList", source = "attachments") + GrpcRueckfrageAnswer toRueckfrageAnswer(PostfachNachricht answer); } diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumService.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumService.java index b7b236b9eb9dc7489bbe0195f0f474cb6e8ea4d4..a8e360bb49179070e1878c31810a10d5f9eac6f0 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumService.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumService.java @@ -99,6 +99,13 @@ public class AntragraumService { return postfachNachrichtService.persistAnswer(rueckfrageId, nachricht); } + public Stream<PostfachNachricht> findAnswers(String samlToken, String rueckfrageId) { + verifyToken(samlToken); + var postfachId = decrypter.decryptPostfachId(parser.parse(samlToken)); + + return postfachNachrichtService.findAnswers(BAYERN_ID, postfachId, rueckfrageId); + } + void verifyToken(String token) { var errors = verifier.verify(token); if (CollectionUtils.isNotEmpty(errors)) { diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/AttachedItemRemoteService.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/AttachedItemRemoteService.java index e58d7ea789c085e33fdd534b0978aba34c8e7337..d854927466082238e4b4e09f111c53ff5cc0c453 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/AttachedItemRemoteService.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/AttachedItemRemoteService.java @@ -65,6 +65,15 @@ class AttachedItemRemoteService { return PostfachNachricht.FIELD_REPLY_OPTION.equals(property.getName()); } + public Stream<PostfachNachricht> findByVorgangId(String vorgangId) { + var response = getVorgangAttachedItemServiceStub().find(buildFindRequest(vorgangId)); + return response.getVorgangAttachedItemsList().stream().map(postfachNachrichtMapper::fromAttachedItem); + } + + VorgangAttachedItemServiceBlockingStub getVorgangAttachedItemServiceStub() { + return vorgangAttachedItemServiceStub.withInterceptors(new NachrichtenCallContextAttachingInterceptor()); + } + GrpcFindVorgangAttachedItemRequest buildFindRequest(String vorgangId) { return GrpcFindVorgangAttachedItemRequest.newBuilder() .setVorgangId(vorgangId) @@ -72,8 +81,4 @@ class AttachedItemRemoteService { .setItemName(ITEM_NAME) .build(); } - - VorgangAttachedItemServiceBlockingStub getVorgangAttachedItemServiceStub() { - return vorgangAttachedItemServiceStub.withInterceptors(new NachrichtenCallContextAttachingInterceptor()); - } } diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtService.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtService.java index e02e46a2bf98107a070736fc6b5b6b30e9ec6af4..813c1732414b2cfde6aee08b8bea55f1e4a49afe 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtService.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtService.java @@ -47,18 +47,20 @@ public interface PersistPostfachNachrichtService { /** * Persists the given answer - * + * * @param answer The given answer * @param rueckfrageId The ID of the original Rueckfrage - * @return + * @return ID of the persisted command */ String persistAnswer(String rueckfrageId, PostfachNachricht answer); /** * Returns all Answers given for the Rueckfrage identified by id - * - * @param rueckfrageId ID of the Rueckfrage to load answers for. + * + * @param serviceKontoType Type of serviceKonto + * @param postfachId ID of postfach + * @param rueckfrageId ID of the Rueckfrage to load answers for. * @return all Answers */ - Stream<PostfachNachricht> findAnswers(String rueckfrageId); + Stream<PostfachNachricht> findAnswers(String serviceKontoType, String postfachId, String rueckfrageId); } diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtServiceImpl.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtServiceImpl.java index 378725d403ee2b8514352e30e1f4c519ed107b17..a4d9682eb1ed6ea4437fabfeb3534b35e9ef2515 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtServiceImpl.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtServiceImpl.java @@ -29,23 +29,44 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Stream; +import org.apache.commons.codec.binary.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; +import de.ozgcloud.apilib.common.command.OzgCloudCommand; +import de.ozgcloud.apilib.common.command.OzgCloudCommandService; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; +import de.ozgcloud.nachrichten.NachrichtenManagerConfiguration; + @Service @Primary public class PersistPostfachNachrichtServiceImpl implements PersistPostfachNachrichtService { private static final String NOT_IMPLEMENTED_MESSAGE = "Not implemented. Use gRPC API instead."; + static final String CLIENT = "OzgCloud_NachrichtenManager"; + static final String ITEM_NAME = "PostfachMail"; + + static final String CREATE_ATTACHED_ITEM_ORDER = "CREATE_ATTACHED_ITEM"; + + static final String CLIENT_FIELD = "client"; + static final String VORGANG_ID_FIELD = "vorgangId"; + static final String ITEM_NAME_FIELD = "itemName"; + static final String ITEM_FIELD = "item"; @Autowired @Qualifier("findVorgangRemoteService") private VorgangRemoteService vorgangRemoteService; + @Autowired + @Qualifier(NachrichtenManagerConfiguration.OZG_CLOUD_COMMAND_SERVICE_NAME) + private OzgCloudCommandService commandService; + @Autowired private AttachedItemRemoteService attachedItemRemoteService; + @Autowired + private PostfachNachrichtMapper postfachNachrichtMapper; @Autowired(required = false) @Qualifier("persistPostfachNachrichtByCommandService") @@ -103,23 +124,48 @@ public class PersistPostfachNachrichtServiceImpl implements PersistPostfachNachr @Override public Stream<PostfachNachricht> findRueckfragen(String servicekontoType, String postfachId) { - return vorgangRemoteService.findVorgangIds(servicekontoType, postfachId).flatMap(attachedItemRemoteService::findReplyAllowedPostfachNachrichts); + return vorgangRemoteService.findVorgangIds(servicekontoType, postfachId) + .flatMap(attachedItemRemoteService::findReplyAllowedPostfachNachrichts); } + // TODO pruefen ob referencedNachricht existiert + // TODO pruefen ob referencedNachricht in dem postfach des anfragenden liegt @Override - public String persistAnswer(String rueckfrageId, PostfachNachricht answer) { - if (nonNull(vorgangManagerNachrichtService)) { - return vorgangManagerNachrichtService.persistAnswer(rueckfrageId, answer); - } - throw new UnsupportedOperationException(NOT_IMPLEMENTED_MESSAGE); + public String persistAnswer(String referencedNachrichtId, PostfachNachricht answer) { + return commandService.create(buildCommand(setReferencedNachricht(referencedNachrichtId, answer))).getId().toString(); + } + + private PostfachNachricht setReferencedNachricht(String referencedNachrichtId, PostfachNachricht answer) { + return answer.toBuilder().referencedNachricht(referencedNachrichtId).build(); + } + + OzgCloudCommand buildCommand(PostfachNachricht nachricht) { + return OzgCloudCommand.builder().order(CREATE_ATTACHED_ITEM_ORDER) + .vorgangId(OzgCloudVorgangId.from(nachricht.getVorgangId())) + .relationId(OzgCloudVorgangId.from(nachricht.getVorgangId())) + .bodyObject(buildCommandBody(nachricht)) + .build(); + } + + Map<String, Object> buildCommandBody(PostfachNachricht nachricht) { + return Map.of( + CLIENT_FIELD, CLIENT, + VORGANG_ID_FIELD, nachricht.getVorgangId(), + ITEM_NAME_FIELD, ITEM_NAME, + ITEM_FIELD, postfachNachrichtMapper.mapToMap(nachricht)); } @Override - public Stream<PostfachNachricht> findAnswers(String rueckfrageId) { - if (nonNull(vorgangManagerNachrichtService)) { - return vorgangManagerNachrichtService.findAnswers(rueckfrageId); - } - throw new UnsupportedOperationException(NOT_IMPLEMENTED_MESSAGE); + public Stream<PostfachNachricht> findAnswers(String serviceKontoType, String postfachId, String rueckfrageId) { + return findPostfachNachricht(serviceKontoType, postfachId, rueckfrageId) + .filter(postfachNachricht -> hasMatchingReferenceNachrichtId(postfachNachricht, rueckfrageId)); } -} + private Stream<PostfachNachricht> findPostfachNachricht(String serviceKontoType, String postfachId, String rueckfrageId) { + return vorgangRemoteService.findVorgangIds(serviceKontoType, postfachId).flatMap(attachedItemRemoteService::findByVorgangId); + } + + private boolean hasMatchingReferenceNachrichtId(PostfachNachricht postfachNachricht, String postfachNachrichtId) { + return StringUtils.equals(postfachNachricht.getReferencedNachricht(), postfachNachrichtId); + } +} \ No newline at end of file diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapper.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapper.java index 780e100abcc0d767d61445a7de5a8b600f057ed0..85b189a2d8e9369053bcacbe8c4681b136bed65a 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapper.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapper.java @@ -24,10 +24,13 @@ package de.ozgcloud.nachrichten.postfach; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import org.apache.commons.collections.MapUtils; @@ -43,7 +46,9 @@ import de.ozgcloud.nachrichten.postfach.PostfachNachricht.Direction; import de.ozgcloud.vorgang.common.GrpcObject; import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; import de.ozgcloud.vorgang.vorgangAttachedItem.GrpcVorgangAttachedItem; +import lombok.extern.log4j.Log4j2; +@Log4j2 @Mapper(unmappedTargetPolicy = ReportingPolicy.WARN) public abstract class PostfachNachrichtMapper { @@ -71,6 +76,7 @@ public abstract class PostfachNachrichtMapper { var postfachMailBuilder = GrpcPostfachMail.newBuilder() .setId(MapUtils.getString(mailMap, PostfachNachricht.FIELD_ID)) .setVorgangId(MapUtils.getString(mailMap, PostfachNachricht.FIELD_VORGANG_ID)) + .setReferencedNachricht(MapUtils.getString(mailMap, PostfachNachricht.REFERENCED_NACHRICHT_FIELD, StringUtils.EMPTY)) .setPostfachId(MapUtils.getString(mailMap, PostfachNachricht.FIELD_POSTFACH_ID, StringUtils.EMPTY)) .setCreatedAt(MapUtils.getString(mailMap, PostfachNachricht.FIELD_CREATED_AT)) .setCreatedBy(MapUtils.getString(mailMap, PostfachNachricht.FIELD_CREATED_BY, StringUtils.EMPTY)) @@ -109,6 +115,7 @@ public abstract class PostfachNachrichtMapper { var postfachMailBuilder = PostfachNachricht.builder() .id(MapUtils.getString(mailMap, PostfachNachricht.FIELD_ID)) .vorgangId(MapUtils.getString(mailMap, (PostfachNachricht.FIELD_VORGANG_ID))) + .referencedNachricht(MapUtils.getString(mailMap, PostfachNachricht.REFERENCED_NACHRICHT_FIELD, StringUtils.EMPTY)) .postfachId(MapUtils.getString(mailMap, PostfachNachricht.FIELD_POSTFACH_ID, StringUtils.EMPTY)) .messageId(MapUtils.getString(mailMap, PostfachNachricht.FIELD_MESSAGE_ID)) .createdAt(ZonedDateTime.parse(MapUtils.getString(mailMap, PostfachNachricht.FIELD_CREATED_AT))) @@ -169,4 +176,58 @@ public abstract class PostfachNachrichtMapper { Map<String, Object> getAsMap(Map<String, Object> map, String fieldName) { return MapUtils.getMap(map, fieldName, Collections.emptyMap()); } + + public Map<String, Object> mapToMap(PostfachNachricht nachricht) { + var result = new HashMap<>(Map.of( + PostfachNachricht.FIELD_VORGANG_ID, nachricht.getVorgangId(), + PostfachNachricht.FIELD_CREATED_AT, nachricht.getCreatedAt().format(DateTimeFormatter.ISO_DATE_TIME), + PostfachNachricht.FIELD_DIRECTION, nachricht.getDirection().name(), + PostfachNachricht.FIELD_REPLY_OPTION, nachricht.getReplyOption().name(), + PostfachNachricht.FIELD_SUBJECT, nachricht.getSubject(), + PostfachNachricht.FIELD_MAIL_BODY, nachricht.getMailBody(), + PostfachNachricht.FIELD_ATTACHMENTS, nachricht.getAttachments())); + + putIfNonNull(result, PostfachNachricht.FIELD_POSTFACH_ID, nachricht.getPostfachId()); + putIfNonNull(result, PostfachNachricht.FIELD_MESSAGE_ID, nachricht.getMessageId()); + putIfNonNull(result, PostfachNachricht.FIELD_CREATED_BY, nachricht.getCreatedBy()); + putIfNonNull(result, PostfachNachricht.FIELD_SENT_SUCCESSFUL, nachricht.getSentSuccessful()); + putIfNonNull(result, PostfachNachricht.FIELD_MESSAGE_CODE, nachricht.getMessageCode()); + putIfNonNull(result, PostfachNachricht.REFERENCED_NACHRICHT_FIELD, nachricht.getReferencedNachricht()); + putDateIfNonNull(result, PostfachNachricht.FIELD_SENT_AT, nachricht.getSentAt()); + + Optional.ofNullable(nachricht.getPostfachAddress()).map(this::buildPostfachAddressMap) + .ifPresent(postfachMaiMap -> result.put(PostfachNachricht.POSTFACH_ADDRESS_FIELD, postfachMaiMap)); + + return Collections.unmodifiableMap(result); + } + + private Map<String, Object> putIfNonNull(Map<String, Object> mapIn, String key, Object value) { + if (Objects.nonNull(value)) { + mapIn.put(key, value); + } + return mapIn; + } + + private Map<String, Object> putDateIfNonNull(Map<String, Object> mapIn, String key, Object value) { + if (Objects.nonNull(value)) { + mapIn.put(key, ((ZonedDateTime) value).format(DateTimeFormatter.ISO_DATE_TIME)); + } + return mapIn; + } + + private Map<String, Object> buildPostfachAddressMap(PostfachAddress postfachAddress) { + var resultMap = new HashMap<String, Object>(); + resultMap.put(PostfachAddress.IDENTIFIER_FIELD, buildPostfachAddressIdentifierMap(postfachAddress)); + resultMap.put(PostfachAddress.VERSION_FIELD, postfachAddress.getVersion()); + resultMap.put(PostfachAddress.TYPE_FIELD, postfachAddress.getType()); + Optional.ofNullable(postfachAddress.getServiceKontoType()).ifPresentOrElse( + serviceKontoType -> resultMap.put(PostfachAddress.SERVICEKONTO_TYPE_FIELD, serviceKontoType), + () -> LOG.warn("ServiceKontoType is null")); + return Collections.unmodifiableMap(resultMap); + } + + private Map<String, Object> buildPostfachAddressIdentifierMap(PostfachAddress postfachAddress) { + var identifier = (StringBasedIdentifier) postfachAddress.getIdentifier(); + return Map.of(PostfachNachricht.FIELD_POSTFACH_ID, identifier.getPostfachId()); + } } \ No newline at end of file diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java index 610b3808b14f417a0ab09edb8f0efc7c4003a2a2..9459e8535c13c063e3ea3c661a3962b77ee08c1f 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/FileSender.java @@ -101,6 +101,10 @@ class FileSender { requestObserver.onNext(chunk); } + public boolean isDone() { + return done.get(); + } + @RequiredArgsConstructor class StreamReader { diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java index 29457e1e4f1af0826f45f899cf8aedfdb289aa81..d0bb1f626fe6d6bf2f9915940c46df9e890bf6c5 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSender.java @@ -27,6 +27,7 @@ import static java.util.Objects.*; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BiFunction; @@ -62,7 +63,8 @@ public class MessageWithFilesSender { private final BiFunction<byte[], Integer, GrpcSendBayernIdMessageRequest> chunkBuilder; private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; - private List<FileSender> fileSenders; + private int currentAttachmentIndex = 0; + private FileSender currentFileSender; public MessageWithFilesSender send() { var responseStreamObserver = BinaryFileUploadStreamObserver.create(resultFuture, this::sendNext); @@ -99,18 +101,40 @@ public class MessageWithFilesSender { } void sendAttachments() { - if (isNull(fileSenders)) { - fileSenders = createFileSenders(); + if (attachmentIds.isEmpty()) { + completeRequest(); + } else { + sendData(); } - fileSenders.forEach(FileSender::send); - completeRequest(); } - List<FileSender> createFileSenders() { - return attachmentIds.stream().map(toAttachment).map(this::buildFileSender).toList(); + void sendData() { + Optional<FileSender> fileSender; + while ((fileSender = getFileSender()).isPresent() && requestObserver.isReady()) { + fileSender.get().send(); + } + if (fileSender.isEmpty()) { + completeRequest(); + } + } + + Optional<FileSender> getFileSender() { + if (isNull(currentFileSender)) { + currentFileSender = buildNextFileSender(); + return Optional.of(currentFileSender); + } + if (!currentFileSender.isDone()) { + return Optional.of(currentFileSender); + } + if (currentAttachmentIndex < attachmentIds.size()) { + currentFileSender = buildNextFileSender(); + return Optional.of(currentFileSender); + } + return Optional.empty(); } - FileSender buildFileSender(BayernIdAttachment attachment) { + FileSender buildNextFileSender() { + var attachment = toAttachment.apply(attachmentIds.get(currentAttachmentIndex++)); return new FileSender(chunkBuilder, requestObserver, attachmentMetadataMapper.apply(attachment), attachment.getContent()); } 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 e5ab9a259721945777073af44b7a539ad2d2a2e3..6a05e36e48e391f304ff207f337f8316c72d5537 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 @@ -20,9 +20,12 @@ package de.ozgcloud.nachrichten.antragraum; -import de.ozgcloud.nachrichten.postfach.PostfachNachricht; -import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; -import io.grpc.stub.StreamObserver; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.UUID; +import java.util.stream.Stream; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -30,11 +33,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; -import java.util.UUID; -import java.util.stream.Stream; - -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import io.grpc.stub.StreamObserver; class AntragraumGrpcServiceTest { @Spy @@ -49,14 +50,14 @@ class AntragraumGrpcServiceTest { class TestFindRueckfragen { @Nested - class TestFindRueckfragenGrpc { + class TestFindRueckfrageGrpc { @Mock private StreamObserver<GrpcFindRueckfragenResponse> streamObserver; @BeforeEach void setup() { when(antragraumService.findRueckfragen(any())).thenReturn(Stream.of(PostfachNachrichtTestFactory.create())); - when(mapper.toGrpc(any(PostfachNachricht.class))).thenReturn(GrpcRueckfrage.getDefaultInstance()); + when(mapper.toGrpc(any(PostfachNachricht.class))).thenReturn(GrpcRueckfrageTestFactory.create()); } @Test @@ -79,6 +80,13 @@ class AntragraumGrpcServiceTest { verify(streamObserver).onCompleted(); } + + @Test + void shouldLoadAnswers() { + antragsraumGrpcService.findRueckfragen(GrpcFindRueckfrageRequestTestFactory.create(), streamObserver); + + verify(antragraumService).findAnswers(GrpcFindRueckfrageRequestTestFactory.SAML_TOKEN, GrpcRueckfrageTestFactory.ID); + } } } @@ -91,14 +99,14 @@ class AntragraumGrpcServiceTest { void setup() { when(antragraumService.sendRueckfrageAnswer(anyString(), anyString(), any(PostfachNachricht.class))) .thenReturn(UUID.randomUUID().toString()); - when(mapper.toPostfachNachricht(any(GrpcRueckfrageAnswer.class))).thenReturn(PostfachNachrichtTestFactory.create()); + when(mapper.fromRueckfrageAnswer(any(GrpcRueckfrageAnswer.class))).thenReturn(PostfachNachrichtTestFactory.create()); } @Test void shouldCallMapper() { antragsraumGrpcService.sendRueckfrageAnswer(GrpcSendRueckfrageAnswerRequestTestFactory.create(), streamObserver); - verify(mapper).toPostfachNachricht(any(GrpcRueckfrageAnswer.class)); + verify(mapper).fromRueckfrageAnswer(any(GrpcRueckfrageAnswer.class)); } @Test @@ -121,6 +129,6 @@ class AntragraumGrpcServiceTest { verify(streamObserver).onCompleted(); } - } + } \ No newline at end of file diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumNachrichtMapperTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumNachrichtMapperTest.java index 5ff78a92ed2d37b75e8c380ea47c87d41a50790c..e42c73f0067c22281a20a3d8a2732a884fd4e43f 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumNachrichtMapperTest.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumNachrichtMapperTest.java @@ -29,6 +29,7 @@ import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; import de.ozgcloud.nachrichten.postfach.PostfachNachricht; +import de.ozgcloud.nachrichten.postfach.PostfachNachricht.Direction; import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; @@ -118,8 +119,15 @@ class AntragraumNachrichtMapperTest { assertThat(result.getAttachments()).isEqualTo(GrpcRueckfrageAnswerTestFactory.ATTACHMENT_ID_LIST); } + @Test + void shouldMapDirection() { + var result = map(); + + assertThat(result.getDirection()).isEqualTo(Direction.IN); + } + private PostfachNachricht map() { - return mapper.toPostfachNachricht(GrpcRueckfrageAnswerTestFactory.create()); + return mapper.fromRueckfrageAnswer(GrpcRueckfrageAnswerTestFactory.create()); } } } \ No newline at end of file diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumServiceTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumServiceTest.java index 34be1187a2443f1168462691bb5f687727381511..8ff8ca4b3c7cbf98fca3ac6f6dc9f545fb85afba 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumServiceTest.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumServiceTest.java @@ -6,6 +6,7 @@ import static org.mockito.Mockito.*; import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -99,7 +100,7 @@ class AntragraumServiceTest { void shouldCallVerify() { service.sendRueckfrageAnswer(SAML_TOKEN, RUECKFRAGE_ID, NACHRICHT); - verify(service).verifyToken(anyString()); + verify(service).verifyToken(SAML_TOKEN); } @Test @@ -113,7 +114,31 @@ class AntragraumServiceTest { void shouldCallPostfachService() { service.sendRueckfrageAnswer(SAML_TOKEN, RUECKFRAGE_ID, NACHRICHT); - verify(postfachNachrichtService).persistAnswer(anyString(), any(PostfachNachricht.class)); + verify(postfachNachrichtService).persistAnswer(eq(RUECKFRAGE_ID), any(PostfachNachricht.class)); + } + } + + @Nested + class TestFindAnswer { + + @BeforeEach + void init() { + when(decrypter.decryptPostfachId(any())).thenReturn(GrpcFindRueckfrageRequestTestFactory.POSTFACH_ID); + } + + @Test + void shouldCallVerify() { + service.findAnswers("TOKEN", PostfachNachrichtTestFactory.ID); + + verify(service).verifyToken("TOKEN"); + } + + @Test + void shouldCallFindAnswers() { + service.findAnswers("TOKEN", PostfachNachrichtTestFactory.ID); + + verify(postfachNachrichtService).findAnswers("BayernID", GrpcFindRueckfrageRequestTestFactory.POSTFACH_ID, + PostfachNachrichtTestFactory.ID); } } } \ No newline at end of file diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/GrpcFindRueckfrageRequestTestFactory.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/GrpcFindRueckfrageRequestTestFactory.java index 9795428ab0d6020b63251d765af3e25e0f89cfa4..11e529e4bc20d68865c12675ca4efe1912c216a4 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/GrpcFindRueckfrageRequestTestFactory.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/GrpcFindRueckfrageRequestTestFactory.java @@ -20,13 +20,12 @@ package de.ozgcloud.nachrichten.antragraum; -import de.ozgcloud.common.test.TestUtils; - import java.util.UUID; public class GrpcFindRueckfrageRequestTestFactory { static final String POSTFACH_ID = UUID.randomUUID().toString(); - static final String SAML_TOKEN = TestUtils.loadTextFile("SamlResponse.xml"); +// static final String SAML_TOKEN = TestUtils.loadTextFile("SamlResponse.xml"); + static final String SAML_TOKEN = "TOKEN"; static GrpcFindRueckfragenRequest create() { return createBuilder().build(); diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/GrpcRueckfrageTestFactory.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/GrpcRueckfrageTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..248e5abc56da8018fd832afef80ea32039aa2c07 --- /dev/null +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/GrpcRueckfrageTestFactory.java @@ -0,0 +1,18 @@ +package de.ozgcloud.nachrichten.antragraum; + +import java.util.UUID; + +public class GrpcRueckfrageTestFactory { + + public static final String ID = UUID.randomUUID().toString(); + + public static GrpcRueckfrage create() { + return createBuilder().build(); + } + + public static GrpcRueckfrage.Builder createBuilder() { + return GrpcRueckfrage.newBuilder() + .setId(ID); + + } +} diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/AttachedItemRemoteServiceTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/AttachedItemRemoteServiceTest.java index d06766d810ea307451dfa8a0ec1a70301d3b4a83..0c879370f9fc9d636ca233686e98a63d69f816d5 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/AttachedItemRemoteServiceTest.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/AttachedItemRemoteServiceTest.java @@ -24,6 +24,7 @@ package de.ozgcloud.nachrichten.postfach; import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Collections; @@ -51,11 +52,9 @@ class AttachedItemRemoteServiceTest { @Spy @InjectMocks - private AttachedItemRemoteService attachedItemRemoteService; - + private AttachedItemRemoteService service; @Mock private VorgangAttachedItemServiceBlockingStub vorgangAttachedItemServiceBlockingStub; - @Mock private PostfachNachrichtMapper postfachNachrichtMapper; @@ -75,63 +74,63 @@ class AttachedItemRemoteServiceTest { void init() { when(grpcFindVorgangAttachedItemResponse.getVorgangAttachedItemsList()).thenReturn(Collections.singletonList(GRPC_VORGANG_ATTACHED_ITEM)); when(vorgangAttachedItemServiceBlockingStub.find(any())).thenReturn(grpcFindVorgangAttachedItemResponse); - doReturn(vorgangAttachedItemServiceBlockingStub).when(attachedItemRemoteService).getVorgangAttachedItemServiceStub(); + doReturn(vorgangAttachedItemServiceBlockingStub).when(service).getVorgangAttachedItemServiceStub(); } @Test - void testCallGetVorgangAttachedItemServiceStub() { - attachedItemRemoteService.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID); + void shouldCallGetVorgangAttachedItemServiceStub() { + service.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID); - verify(attachedItemRemoteService).getVorgangAttachedItemServiceStub(); + verify(service).getVorgangAttachedItemServiceStub(); } @Test void shouldCallBuildFindRequest() { - attachedItemRemoteService.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID); + service.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID); - verify(attachedItemRemoteService).buildFindRequest(MessageTestFactory.VORGANG_ID); + verify(service).buildFindRequest(MessageTestFactory.VORGANG_ID); } @Test void shouldCallFind() { - doReturn(grpcFindVorgangAttachedItemRequest).when(attachedItemRemoteService).buildFindRequest(anyString()); + doReturn(grpcFindVorgangAttachedItemRequest).when(service).buildFindRequest(anyString()); - attachedItemRemoteService.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID); + service.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID); verify(vorgangAttachedItemServiceBlockingStub).find(grpcFindVorgangAttachedItemRequest); } @Test void shouldCallReplyAllowed() { - attachedItemRemoteService.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID).toList(); + service.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID).toList(); - verify(attachedItemRemoteService).replyAllowed(GRPC_VORGANG_ATTACHED_ITEM); + verify(service).replyAllowed(GRPC_VORGANG_ATTACHED_ITEM); } @Test void shouldCallPostfachNachrichtMapper() { - doReturn(true).when(attachedItemRemoteService).replyAllowed(any()); + doReturn(true).when(service).replyAllowed(any()); - attachedItemRemoteService.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID).toList(); + service.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID).toList(); verify(postfachNachrichtMapper).fromAttachedItem(GRPC_VORGANG_ATTACHED_ITEM); } @Test void shouldNotCallPostfachNachrichtMapper() { - doReturn(false).when(attachedItemRemoteService).replyAllowed(any()); + doReturn(false).when(service).replyAllowed(any()); - attachedItemRemoteService.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID).toList(); + service.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID).toList(); verify(postfachNachrichtMapper, never()).fromAttachedItem(GRPC_VORGANG_ATTACHED_ITEM); } @Test void shouldReturnResult() { - doReturn(true).when(attachedItemRemoteService).replyAllowed(any()); + doReturn(true).when(service).replyAllowed(any()); doReturn(postfachNachricht).when(postfachNachrichtMapper).fromAttachedItem(any()); - var result = attachedItemRemoteService.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID); + var result = service.findReplyAllowedPostfachNachrichts(MessageTestFactory.VORGANG_ID); assertThat(result).containsExactly(postfachNachricht); } @@ -147,7 +146,7 @@ class AttachedItemRemoteServiceTest { var grpcVorgangAttachedItem = GrpcVorgangAttachedItemTestFactory.createBuilder().setItem(GrpcObject.newBuilder() .addProperty(GrpcProperty.newBuilder().setName("replyOption").addValue(replyOption.name()))).build(); - var result = attachedItemRemoteService.replyAllowed(grpcVorgangAttachedItem); + var result = service.replyAllowed(grpcVorgangAttachedItem); assertThat(result).isTrue(); } @@ -157,7 +156,7 @@ class AttachedItemRemoteServiceTest { var grpcVorgangAttachedItem = GrpcVorgangAttachedItemTestFactory.createBuilder().setItem(GrpcObject.newBuilder() .addProperty(GrpcProperty.newBuilder().setName("replyOption").addValue("FORBIDDEN"))).build(); - var result = attachedItemRemoteService.replyAllowed(grpcVorgangAttachedItem); + var result = service.replyAllowed(grpcVorgangAttachedItem); assertThat(result).isFalse(); } @@ -168,21 +167,21 @@ class AttachedItemRemoteServiceTest { @Test void shouldSetVorgangId() { - var result = attachedItemRemoteService.buildFindRequest(MessageTestFactory.VORGANG_ID); + var result = service.buildFindRequest(MessageTestFactory.VORGANG_ID); assertThat(result.getVorgangId()).isEqualTo(MessageTestFactory.VORGANG_ID); } @Test void shouldSetClient() { - var result = attachedItemRemoteService.buildFindRequest(MessageTestFactory.VORGANG_ID); + var result = service.buildFindRequest(MessageTestFactory.VORGANG_ID); assertThat(result.getClient()).isEqualTo(AttachedItemRemoteService.CLIENT); } @Test void shouldSetItemName() { - var result = attachedItemRemoteService.buildFindRequest(MessageTestFactory.VORGANG_ID); + var result = service.buildFindRequest(MessageTestFactory.VORGANG_ID); assertThat(result.getItemName()).isEqualTo(AttachedItemRemoteService.ITEM_NAME); } @@ -196,7 +195,7 @@ class AttachedItemRemoteServiceTest { @Test void shouldAddInterceptor() { - attachedItemRemoteService.getVorgangAttachedItemServiceStub(); + service.getVorgangAttachedItemServiceStub(); verify(vorgangAttachedItemServiceBlockingStub).withInterceptors(any(NachrichtenCallContextAttachingInterceptor.class)); } @@ -205,9 +204,64 @@ class AttachedItemRemoteServiceTest { void shouldReturnStub() { when(vorgangAttachedItemServiceBlockingStub.withInterceptors(any())).thenReturn(stubWithInterceptor); - var result = attachedItemRemoteService.getVorgangAttachedItemServiceStub(); + var result = service.getVorgangAttachedItemServiceStub(); assertThat(result).isSameAs(stubWithInterceptor); } } + + @DisplayName("Find by vorgangId") + @Nested + class TestFindByVorgangId { + + private static final GrpcVorgangAttachedItem GRPC_VORGANG_ATTACHED_ITEM = GrpcVorgangAttachedItemTestFactory.create(); + + @Mock + private GrpcFindVorgangAttachedItemRequest grpcFindVorgangAttachedItemRequest; + @Mock + private GrpcFindVorgangAttachedItemResponse grpcFindVorgangAttachedItemResponse; + + private final PostfachNachricht postfachNachricht = PostfachNachrichtTestFactory.create(); + + @BeforeEach + void init() { + when(grpcFindVorgangAttachedItemResponse.getVorgangAttachedItemsList()).thenReturn(Collections.singletonList(GRPC_VORGANG_ATTACHED_ITEM)); + when(vorgangAttachedItemServiceBlockingStub.find(any())).thenReturn(grpcFindVorgangAttachedItemResponse); + doReturn(vorgangAttachedItemServiceBlockingStub).when(service).getVorgangAttachedItemServiceStub(); + doReturn(grpcFindVorgangAttachedItemRequest).when(service).buildFindRequest(any()); + } + + @BeforeEach + void mock() { + when(postfachNachrichtMapper.fromAttachedItem(any())).thenReturn(postfachNachricht); + } + + @Test + void shouldGetServiceStub() { + service.findByVorgangId(MessageTestFactory.VORGANG_ID).toList(); + + verify(service).getVorgangAttachedItemServiceStub(); + } + + @Test + void shouldCallServiceStub() { + service.findByVorgangId(MessageTestFactory.VORGANG_ID).toList(); + + verify(vorgangAttachedItemServiceBlockingStub).find(grpcFindVorgangAttachedItemRequest); + } + + @Test + void shouldCallMapper() { + service.findByVorgangId(MessageTestFactory.VORGANG_ID).toList(); + + verify(postfachNachrichtMapper).fromAttachedItem(GRPC_VORGANG_ATTACHED_ITEM); + } + + @Test + void shouldReturnMappedValue() { + var postfachNachrichten = service.findByVorgangId(MessageTestFactory.VORGANG_ID); + + assertThat(postfachNachrichten).containsExactly(postfachNachricht); + } + } } \ No newline at end of file diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtServiceImplTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtServiceImplTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4b990f5ff92c8d3c17655ec97045664181c094b5 --- /dev/null +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PersistPostfachNachrichtServiceImplTest.java @@ -0,0 +1,212 @@ +package de.ozgcloud.nachrichten.postfach; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Map; +import java.util.UUID; +import java.util.stream.Stream; + +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.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.apilib.common.command.OzgCloudCommand; +import de.ozgcloud.apilib.common.command.OzgCloudCommandId; +import de.ozgcloud.apilib.common.command.OzgCloudCommandService; +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; + +class PersistPostfachNachrichtServiceImplTest { + + @Spy + @InjectMocks + private PersistPostfachNachrichtServiceImpl service; + @Mock + private VorgangRemoteService vorgangRemoteService; + @Mock + private OzgCloudCommandService commandService; + @Mock + private AttachedItemRemoteService attachedItemRemoteService; + @Mock + private PostfachNachrichtMapper postfachNachrichtMapper; + + @DisplayName("Persist answer") + @Nested + class TestPersistAnswer { + + @Captor + private ArgumentCaptor<PostfachNachricht> postfachNachrichtCaptor; + + private final OzgCloudCommand command = OzgCloudCommand.builder().id(OzgCloudCommandId.from(UUID.randomUUID().toString())).build(); + private final PostfachNachricht postfachNachricht = PostfachNachrichtTestFactory.createBuilder().referencedNachricht(null).build(); + + @BeforeEach + void mock() { + doReturn(command).when(service).buildCommand(any()); + when(commandService.create(any())).thenReturn(command); + } + + @Test + void shouldCallBuildCommand() { + service.persistAnswer(GrpcPostfachMailTestFactory.REFERENCED_NACHRICHT_ID, postfachNachricht); + + verify(service).buildCommand(postfachNachrichtCaptor.capture()); + assertThat(postfachNachrichtCaptor.getValue().getReferencedNachricht()).isEqualTo(GrpcPostfachMailTestFactory.REFERENCED_NACHRICHT_ID); + } + + @Test + void shouldCallCommandService() { + service.persistAnswer(GrpcPostfachMailTestFactory.REFERENCED_NACHRICHT_ID, postfachNachricht); + + verify(commandService).create(command); + } + } + + @DisplayName("Build command") + @Nested + class TestBuildCommand { + + private final PostfachNachricht postfachNachricht = PostfachNachrichtTestFactory.create(); + + @BeforeEach + void mock() { + doReturn(Map.of("dummyKey", "dummyValue")).when(service).buildCommandBody(any()); + } + + @Test + void shouldHaveSetOrder() { + var command = service.buildCommand(postfachNachricht); + + assertThat(command.getOrder()).isEqualTo(PersistPostfachNachrichtServiceImpl.CREATE_ATTACHED_ITEM_ORDER); + } + + @Test + void shouldHaveSetVorgangId() { + var command = service.buildCommand(postfachNachricht); + + assertThat(command.getVorgangId()).hasToString(MessageTestFactory.VORGANG_ID); + } + + @Test + void shouldHaveSetRelationId() { + var command = service.buildCommand(postfachNachricht); + + assertThat(command.getRelationId()).hasToString(MessageTestFactory.VORGANG_ID); + } + + @Test + void shouldCallBuildCommandBody() { + service.buildCommand(postfachNachricht); + + verify(service).buildCommandBody(postfachNachricht); + } + + @Test + void shouldHaveSetBodyObjet() { + var command = service.buildCommand(postfachNachricht); + + assertThat(command.getBodyObject()).isNotEmpty(); + } + } + + @DisplayName("Build command body") + @Nested + class TestBuildCommandBody { + + private final PostfachNachricht postfachNachricht = PostfachNachrichtTestFactory.create(); + private Map<String, Object> postfachNachrichtAsMap = Map.of("dummyKey", "dummyValue"); + + @BeforeEach + void mock() { + when(postfachNachrichtMapper.mapToMap(any())).thenReturn(postfachNachrichtAsMap); + } + + @Test + void shouldHaveSetClient() { + var body = service.buildCommandBody(postfachNachricht); + + assertThat(body).containsEntry(PersistPostfachNachrichtServiceImpl.CLIENT_FIELD, PersistPostfachNachrichtServiceImpl.CLIENT); + } + + @Test + void shouldHaveSetVorgangId() { + var body = service.buildCommandBody(postfachNachricht); + + assertThat(body).containsEntry(PersistPostfachNachrichtServiceImpl.VORGANG_ID_FIELD, MessageTestFactory.VORGANG_ID); + } + + @Test + void shouldHaveSetItemName() { + var body = service.buildCommandBody(postfachNachricht); + + assertThat(body).containsEntry(PersistPostfachNachrichtServiceImpl.ITEM_NAME_FIELD, PersistPostfachNachrichtServiceImpl.ITEM_NAME); + } + + @Test + void shouldCallMapper() { + service.buildCommandBody(postfachNachricht); + + verify(postfachNachrichtMapper).mapToMap(postfachNachricht); + } + + @Test + void shouldHaveSetItem() { + var body = service.buildCommandBody(postfachNachricht); + + assertThat(body).containsEntry(PersistPostfachNachrichtServiceImpl.ITEM_FIELD, postfachNachrichtAsMap); + } + } + + @DisplayName("Find answers") + @Nested + class TestFindAnswers { + + private final String serviceKontoType = "serviceKontoTypeDummy"; + + private final PostfachNachricht postfachNachrichtWithNoReferencedNachricht = PostfachNachrichtTestFactory.createBuilder() + .referencedNachricht(null).build(); + private final PostfachNachricht postfachNachrichtWithNonMatchingReferencedNachricht = PostfachNachrichtTestFactory.createBuilder() + .referencedNachricht("quatsch").build(); + private final PostfachNachricht matchingPostfachNachricht = PostfachNachrichtTestFactory.create(); + + @BeforeEach + void mock() { + when(vorgangRemoteService.findVorgangIds(any(), any())).thenReturn(Stream.of(MessageTestFactory.VORGANG_ID)); + when(attachedItemRemoteService.findByVorgangId(any())).thenReturn(Stream.of(postfachNachrichtWithNoReferencedNachricht, + matchingPostfachNachricht, postfachNachrichtWithNonMatchingReferencedNachricht)); + } + + @Test + void shouldCallVorgangRemoteService() { + doFindAnswers().toList(); + + verify(vorgangRemoteService).findVorgangIds(serviceKontoType, PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); + } + + @Test + void shouldCallAttachedItemRemoteService() { + doFindAnswers().toList(); + + verify(attachedItemRemoteService).findByVorgangId(MessageTestFactory.VORGANG_ID); + } + + @Test + void shouldReturnMatchingPostfachNachricht() { + var answers = doFindAnswers(); + + assertThat(answers).containsExactly(matchingPostfachNachricht); + } + + private Stream<PostfachNachricht> doFindAnswers() { + return service.findAnswers(serviceKontoType, PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE, + GrpcPostfachMailTestFactory.REFERENCED_NACHRICHT_ID); + } + } +} diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerTest.java index 3964f981ad91a24b27d679420b55d43e0dbc8ed2..adfc03a3811ecb8059370480d93df84c496def8e 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerTest.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachEventListenerTest.java @@ -82,7 +82,8 @@ class PostfachEventListenerTest { verify(service).sendMail(eq(COMMAND_ID), eq(USER_ID), nachrichtCaptor.capture()); assertThat(nachrichtCaptor.getValue()) - .usingRecursiveComparison().ignoringFields("id", "createdAt", "messageCode", "messageId", "sentAt", "sentSuccessful") + .usingRecursiveComparison() + .ignoringFields("id", "createdAt", "messageCode", "messageId", "sentAt", "sentSuccessful", "referencedNachricht") .isEqualTo(PostfachNachrichtTestFactory.createBuilder().direction(Direction.OUT).build()); } diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapperTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapperTest.java index ad4c9544f7cf39b6f5f22ffa9e13444e5b520b71..344a5073a639ccc488b9d38a62ea5fbc792a9f44 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapperTest.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtMapperTest.java @@ -283,4 +283,52 @@ class PostfachNachrichtMapperTest { return field.get(obj); } + + @DisplayName("Map to map") + @Nested + class TestMapToMap { + + @Test + void shouldContainAllFieldsIgnoringId() { + var map = mapper.mapToMap(PostfachNachrichtTestFactory.createBuilder().id(null).build()); + + var mapWithoutId = PostfachNachrichtTestFactory.asMap(); + mapWithoutId.remove("id"); + + assertThat(map).containsAllEntriesOf(mapWithoutId); + } + + @Test + void shouldIgnoreEmptyMessageId() { + assertDoesNotThrow(() -> mapper.mapToMap(PostfachNachrichtTestFactory.createBuilder().messageId(null).build())); + } + + @Test + void shouldIgnoreEmptyCreatedBy() { + assertDoesNotThrow(() -> mapper.mapToMap(PostfachNachrichtTestFactory.createBuilder().createdBy(null).build())); + } + + @Test + void shouldHandleNullAsPostfachId() { + var postfachMail = PostfachNachrichtTestFactory.createBuilder().postfachId(null).build(); + + assertDoesNotThrow(() -> mapper.mapToMap(postfachMail)); + } + + @Test + void shouldProceedWithEmptyPostfachAddress() { + var postfachMail = PostfachNachrichtTestFactory.createBuilder().postfachAddress(null).build(); + + assertDoesNotThrow(() -> mapper.mapToMap(postfachMail)); + } + + @Test + void shouldHandleEmptyReferencedNachrichtId() { + var postfachNachricht = PostfachNachrichtTestFactory.createBuilder().id(null) + .referencedNachricht(null) + .build(); + + assertDoesNotThrow(() -> mapper.mapToMap(postfachNachricht)); + } + } } diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtTestFactory.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtTestFactory.java index 23276159b678b7b0501794021e79c7fbe2241283..d58ab79a63e7b6984c5c9d641bef9460086e2117 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtTestFactory.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/PostfachNachrichtTestFactory.java @@ -60,6 +60,7 @@ public class PostfachNachrichtTestFactory { public static PostfachNachricht.PostfachNachrichtBuilder createBuilder() { return PostfachNachricht.builder() .id(ID) + .referencedNachricht(GrpcPostfachMailTestFactory.REFERENCED_NACHRICHT_ID) .postfachId(POSTFACH_ID) .postfachAddress(PostfachAddressTestFactory.create()) .messageId(MESSAGE_ID) @@ -79,6 +80,7 @@ public class PostfachNachrichtTestFactory { public static Map<String, Object> asMap() { var map = new HashMap<String, Object>(); map.put(PostfachNachricht.FIELD_ID, ID); + map.put(PostfachNachricht.REFERENCED_NACHRICHT_FIELD, GrpcPostfachMailTestFactory.REFERENCED_NACHRICHT_ID); map.put(PostfachNachricht.FIELD_POSTFACH_ID, POSTFACH_ID); map.put(PostfachNachricht.POSTFACH_ADDRESS_FIELD, getPostfachAddressAsMap()); map.put(PostfachNachricht.FIELD_MESSAGE_ID, MESSAGE_ID); diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java index 1efd3e30ec8f02a80a7601b6920e6ce40ab2dcd8..ef35049daa926c5dd751258b91897f796469061e 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/MessageWithFilesSenderTest.java @@ -28,11 +28,13 @@ import static org.mockito.Mockito.*; import java.io.InputStream; import java.util.List; +import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BiFunction; import java.util.function.Function; 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.mockito.Mock; @@ -178,149 +180,239 @@ class MessageWithFilesSenderTest { @Nested class TestSendAttachments { - private String attachmentId = "id1"; + @Test + void shouldCallCompleteRequest() { + doNothing().when(messageWithFilesSender).completeRequest(); + + messageWithFilesSender.sendAttachments(); + + verify(messageWithFilesSender).completeRequest(); + } + + @Test + void shouldCallSendData() { + ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of("attachmentId")); + doNothing().when(messageWithFilesSender).sendData(); + + messageWithFilesSender.sendAttachments(); + + verify(messageWithFilesSender).sendData(); + } + + } + + @Nested + class TestSendData { @Mock private FileSender fileSender; + @Mock + private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; @BeforeEach void setup() { - ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of(attachmentId)); - doNothing().when(messageWithFilesSender).completeRequest(); + ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver); } @Test - void shouldCallCreateFileSenders() { - doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any()); + void shouldCallGetFileSender() { + doReturn(Optional.of(fileSender)).when(messageWithFilesSender).getFileSender(); - messageWithFilesSender.sendAttachments(); + messageWithFilesSender.sendData(); - verify(messageWithFilesSender).createFileSenders(); + verify(messageWithFilesSender).getFileSender(); } @Test - void shouldNotRecreateFileSenders() { - ReflectionTestUtils.setField(messageWithFilesSender, "fileSenders", List.of(fileSender)); + void shouldCallSendOnFileSender() { + doReturn(Optional.of(fileSender)).when(messageWithFilesSender).getFileSender(); + when(requestObserver.isReady()).thenReturn(true, false); - messageWithFilesSender.sendAttachments(); + messageWithFilesSender.sendData(); - verify(messageWithFilesSender, never()).createFileSenders(); + verify(fileSender).send(); } @Test - void shouldCallSendOnFileSender() { - doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any()); + @DisplayName("should not complete request if attachments not sent") + void shouldNotCompleteIfNotDone() { + doReturn(Optional.of(fileSender)).when(messageWithFilesSender).getFileSender(); + when(requestObserver.isReady()).thenReturn(true, false); - messageWithFilesSender.sendAttachments(); + messageWithFilesSender.sendData(); - verify(fileSender).send(); + verify(messageWithFilesSender, never()).completeRequest(); } @Test - void shouldCallCompleteRequest() { - doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any()); + void shouldCompleteRequest() { + doReturn(Optional.empty()).when(messageWithFilesSender).getFileSender(); - messageWithFilesSender.sendAttachments(); + messageWithFilesSender.sendData(); verify(messageWithFilesSender).completeRequest(); } } @Nested - class TestCreateFileSenders { - - private String attachmentId = "id1"; + class TestGetFileSender { @Mock private FileSender fileSender; - @BeforeEach - void setup() { - doReturn(fileSender).when(messageWithFilesSender).buildFileSender(any()); - ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of(attachmentId)); - } + @Nested + class TestCreateFirstFileSender { - @Test - void shouldCalToAttachment() { - messageWithFilesSender.createFileSenders(); + @BeforeEach + void setup() { + doReturn(fileSender).when(messageWithFilesSender).buildNextFileSender(); + } + + @Test + void shouldCallBuildNextSender() { + messageWithFilesSender.getFileSender(); + + verify(messageWithFilesSender).buildNextFileSender(); + } + + @Test + void shouldSetCurrentFileSender() { + messageWithFilesSender.getFileSender(); + + assertThat(messageWithFilesSender).extracting("currentFileSender").isSameAs(fileSender); + } + + @Test + void shouldReturnCurrentFileSender() { + var result = messageWithFilesSender.getFileSender(); + + assertThat(result).containsSame(fileSender); + } - verify(toAttachment).apply(attachmentId); } - @Test - void shouldCallBuildFileSender() { - messageWithFilesSender.createFileSenders(); + @Nested + class TestReturnCurrentFileSender { + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(messageWithFilesSender, "currentFileSender", fileSender); + } + + @Test + void shouldReturnCurrentFileSender() { + var result = messageWithFilesSender.getFileSender(); - verify(messageWithFilesSender).buildFileSender(any()); + assertThat(result).containsSame(fileSender); + } + + @Test + void shouldNotCallBuildNextSender() { + messageWithFilesSender.getFileSender(); + + verify(messageWithFilesSender, never()).buildNextFileSender(); + } } - @Test - void shouldReturnFileSenders() { - var result = messageWithFilesSender.createFileSenders(); + @Nested + class TestCreateNextFileSender { + + @Mock + private FileSender nextFileSender; + + @BeforeEach + void setup() { + when(fileSender.isDone()).thenReturn(true); + ReflectionTestUtils.setField(messageWithFilesSender, "currentFileSender", fileSender); + ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of("attachmentId")); + doReturn(nextFileSender).when(messageWithFilesSender).buildNextFileSender(); + } + + @Test + void shouldCallBuildNextSender() { + messageWithFilesSender.getFileSender(); + + verify(messageWithFilesSender).buildNextFileSender(); + } + + @Test + void shouldSetCurrentFileSender() { + messageWithFilesSender.getFileSender(); + + assertThat(messageWithFilesSender).extracting("currentFileSender").isSameAs(nextFileSender); + } + + @Test + void shouldReturnCurrentFileSender() { + var result = messageWithFilesSender.getFileSender(); - assertThat(result).containsExactly(fileSender); + assertThat(result).containsSame(nextFileSender); + } } + } @Nested - class TestBuildFileSender { + class TestBuildNextFileSender { - private String attachmentId = "id1"; + private final String attachmentId = "id1"; @Mock private CallStreamObserver<GrpcSendBayernIdMessageRequest> requestObserver; @Mock private GrpcSendBayernIdMessageRequest attachmentMetadata; - @Mock - private BayernIdAttachment attachment; @Mock private InputStream inputStream; + private final BayernIdAttachment attachment = BayernIdAttachmentTestFactory.create(); + @BeforeEach void setup() { - ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver); + ReflectionTestUtils.setField(messageWithFilesSender, "attachmentIds", List.of(attachmentId)); + when(toAttachment.apply(any())).thenReturn(attachment); + } + + @Test + void shouldCallToAttachment() { + messageWithFilesSender.buildNextFileSender(); + + verify(toAttachment).apply(attachmentId); } @Test void shouldSetChunkBuilder() { - var result = messageWithFilesSender.buildFileSender(attachment); + var result = messageWithFilesSender.buildNextFileSender(); assertThat(result).extracting("chunkBuilder").isSameAs(chunkBuilder); } @Test void shouldSetRequestObserver() { - var result = messageWithFilesSender.buildFileSender(attachment); + ReflectionTestUtils.setField(messageWithFilesSender, "requestObserver", requestObserver); + + var result = messageWithFilesSender.buildNextFileSender(); assertThat(result).extracting("requestObserver").isSameAs(requestObserver); } @Test void shouldCallAttachmentMetadataMapper() { - ReflectionTestUtils.setField(messageWithFilesSender, "attachmentMetadataMapper", attachmentMetadataMapper); - messageWithFilesSender.buildFileSender(attachment); + messageWithFilesSender.buildNextFileSender(); verify(attachmentMetadataMapper).apply(attachment); } @Test void shouldSetAttachmentMetadata() { - ReflectionTestUtils.setField(messageWithFilesSender, "attachmentMetadataMapper", attachmentMetadataMapper); when(attachmentMetadataMapper.apply(any())).thenReturn(attachmentMetadata); - var result = messageWithFilesSender.buildFileSender(attachment); + var result = messageWithFilesSender.buildNextFileSender(); assertThat(result).extracting("metadata").isSameAs(attachmentMetadata); } - @Test - void shouldGetContent() { - messageWithFilesSender.buildFileSender(attachment); - - verify(attachment).getContent(); - } } @Nested