diff --git a/pom.xml b/pom.xml index e8c8ec64c40f1795975863be8bc7a4fe76ef4549..0a7a5bd184a4a38bebdbc4a8ab427f1465484eca 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,7 @@ <jaxb2-plugin.version>0.15.2</jaxb2-plugin.version> <jaxb3-plugin.version>0.15.0</jaxb3-plugin.version> <mojo-jaxb2-plugin.version>3.1.0</mojo-jaxb2-plugin.version> + <grpcmock.version>0.13.0</grpcmock.version> </properties> <dependencyManagement> @@ -134,6 +135,12 @@ <type>test-jar</type> <scope>test</scope> </dependency> + <dependency> + <groupId>org.grpcmock</groupId> + <artifactId>grpcmock-spring-boot</artifactId> + <version>${grpcmock.version}</version> + <scope>test</scope> + </dependency> </dependencies> </dependencyManagement> diff --git a/semantik-adapter/pom.xml b/semantik-adapter/pom.xml index 18c5fe1bb8ace2afd5e890daf9196ed782046a29..1b88eb4cd3a10839f277a1e4d52526eaf9b9e408 100644 --- a/semantik-adapter/pom.xml +++ b/semantik-adapter/pom.xml @@ -61,6 +61,15 @@ <type>test-jar</type> <scope>test</scope> </dependency> + <dependency> + <groupId>org.grpcmock</groupId> + <artifactId>grpcmock-spring-boot</artifactId> + </dependency> + <dependency> + <groupId>de.ozgcloud.vorgang</groupId> + <artifactId>vorgang-manager-interface</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragITCase.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragITCase.java index e80eeca2598ef00dc45d827401744d80eb10ba4c..68276370784ab74c52ed506b1e75345f9c042b09 100644 --- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragITCase.java +++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragITCase.java @@ -2,27 +2,25 @@ package de.ozgcloud.eingang.semantik.formbased.mantelantrag; import static de.ozgcloud.eingang.common.formdata.FormDataTestFactory.*; import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; +import static org.grpcmock.GrpcMock.*; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.List; -import java.util.Optional; +import java.util.function.Predicate; +import org.grpcmock.interceptors.CapturedRequest; +import org.grpcmock.springboot.AutoConfigureGrpcMock; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; 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.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; @@ -32,31 +30,92 @@ import de.ozgcloud.common.test.TestUtils; import de.ozgcloud.eingang.Application; import de.ozgcloud.eingang.common.formdata.FormData; import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory; -import de.ozgcloud.eingang.router.VorgangRemoteService; import de.ozgcloud.eingang.semantik.SemantikAdapter; import de.ozgcloud.eingang.semantik.enginebased.formsolutions.FormSolutionsEngineBasedAdapterITCase; +import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest; +import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileResponse; +import de.ozgcloud.vorgang.vorgang.GrpcCreateVorgangRequest; +import de.ozgcloud.vorgang.vorgang.GrpcCreateVorgangResponse; +import de.ozgcloud.vorgang.vorgang.GrpcEingang; +import de.ozgcloud.vorgang.vorgang.GrpcFinishCreationResponse; +import de.ozgcloud.vorgang.vorgang.GrpcZustaendigeStelle; +import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc; import lombok.SneakyThrows; -@ActiveProfiles({ "local", "itcase" }) -@SpringBootTest(classes = Application.class) +@ActiveProfiles({ "itcase" }) +@SpringBootTest(classes = Application.class, properties = { + "ozgcloud.adapter.targetVorgangManagerName=itcase", + "grpc.client.vorgang-manager-itcase.address=in-process:vorgang-manager-itcase", + "grpc.client.vorgang-manager-itcase.negotiationType=PLAINTEXT", +}) +@AutoConfigureGrpcMock(name = "vorgang-manager-itcase", useInProcessServer = true) public class MantelantragITCase { private static final String FILE_NAME_XDOMEA = "mantelantrag/4620-EH6C_b3c9168a-6ae9-4361-8b2f-6837bb341021_Geschaeftsgang.Geschaeftsgang.0201.xml"; private static final String FILE_NAME_MANTELANTRAG = "mantelantrag/4620-EH6C_7d703670-15b6-42b2-8cd1-88a7e4c494b9_Antrag_Max_Mustermann_SGBXII.xml"; - @MockBean - VorgangRemoteService vorgangRemoteService; + @BeforeEach + void setup() { + mockStartVorgangCreation(); + mockUploadBinaryFiles(); + mockFinishVorgangCreation(); + } + + private void mockStartVorgangCreation() { + stubFor( + unaryMethod(VorgangServiceGrpc.getStartCreationMethod()) + .willReturn(GrpcCreateVorgangResponse.getDefaultInstance())); + } + + private void mockUploadBinaryFiles() { + stubFor( + clientStreamingMethod(BinaryFileServiceGrpc.getUploadBinaryFileAsStreamMethod()) + .willReturn(GrpcUploadBinaryFileResponse.getDefaultInstance())); + } + + private void mockFinishVorgangCreation() { + stubFor( + unaryMethod(VorgangServiceGrpc.getFinishCreationMethod()) + .willReturn(GrpcFinishCreationResponse.getDefaultInstance())); + } - @SpyBean + @AfterEach + void teardown() { + try { + expectOneVorgangCreateAndFinishCall(); + expectTwoUploadCallsForXmlRepresentations(); + } finally { + resetMappings(); + } + } + + private void expectOneVorgangCreateAndFinishCall() { + verifyThat( + calledMethod(VorgangServiceGrpc.getStartCreationMethod()) + .withRequest(GrpcCreateVorgangRequest::hasEingang), + times(1)); + verifyThat( + calledMethod(VorgangServiceGrpc.getFinishCreationMethod()), + times(1)); + } + + private void expectTwoUploadCallsForXmlRepresentations() { + Predicate<GrpcUploadBinaryFileRequest> hasXMLContentType = request -> request.hasMetadata() && request + .getMetadata() + .getContentType() + .contains("xml"); + verifyThat( + calledMethod(BinaryFileServiceGrpc.getUploadBinaryFileAsStreamMethod()) + .withRequestsContaining(hasXMLContentType), + times(2)); + } + + @Autowired SemantikAdapter semantikAdapter; - @Captor - ArgumentCaptor<FormData> formDataCaptor; private FormData formData; - @Captor - ArgumentCaptor<Optional<String>> oeIdCaptor; - @Autowired MantelantragZustaendigeStelleMapper mantelantragZustaendigeStelleMapper; @@ -64,8 +123,6 @@ public class MantelantragITCase { @BeforeEach void mock() { - clearInvocations(vorgangRemoteService); - doReturn(VORGANG_ID).when(vorgangRemoteService).createVorgang(any(FormData.class), any()); formData = prepareTestData(); mantelantragZustaendigeStelleMapper.init(); } @@ -89,8 +146,9 @@ public class MantelantragITCase { void shouldCreateOneVorgang() { semantikAdapter.processFormData(formData); - verify(vorgangRemoteService, times(1)).createVorgang(formDataCaptor.capture(), oeIdCaptor.capture()); - assertThat(oeIdCaptor.getValue()).isEmpty(); + var eingangs = captureEingangs(); + assertThat(eingangs).hasSize(1); + assertThat(eingangs.getFirst().getZustaendigeStelle().getOrganisationseinheitenId()).isEmpty(); } } @@ -107,8 +165,10 @@ public class MantelantragITCase { void shouldCreateOneVorgang() { semantikAdapter.processFormData(formData); - verify(vorgangRemoteService, times(1)).createVorgang(formDataCaptor.capture(), oeIdCaptor.capture()); - assertThat(oeIdCaptor.getValue()).contains("123"); + var eingangs = captureEingangs(); + assertThat(eingangs).extracting(GrpcEingang::getZustaendigeStelle) + .extracting(GrpcZustaendigeStelle::getOrganisationseinheitenId) + .containsOnly("123"); } } @@ -126,8 +186,10 @@ public class MantelantragITCase { void shouldCreateTwoVorangsWithPartiallyMatchingZustaendigeStelle() { semantikAdapter.processFormData(formData); - verify(vorgangRemoteService, times(2)).createVorgang(formDataCaptor.capture(), oeIdCaptor.capture()); - assertThat(oeIdCaptor.getAllValues()).contains(Optional.of("123"), Optional.of("444")); + var eingangs = captureEingangs(); + assertThat(eingangs).extracting(GrpcEingang::getZustaendigeStelle) + .extracting(GrpcZustaendigeStelle::getOrganisationseinheitenId) + .containsOnly("123", "444"); } } @@ -145,8 +207,10 @@ public class MantelantragITCase { void shouldCreateThreeVorgangs() { semantikAdapter.processFormData(formData); - verify(vorgangRemoteService, times(3)).createVorgang(formDataCaptor.capture(), oeIdCaptor.capture()); - assertThat(oeIdCaptor.getAllValues()).contains(Optional.of("123"), Optional.of("321"), Optional.of("444")); + var eingangs = captureEingangs(); + assertThat(eingangs).extracting(GrpcEingang::getZustaendigeStelle) + .extracting(GrpcZustaendigeStelle::getOrganisationseinheitenId) + .containsOnly("123", "321", "444"); } } @@ -175,6 +239,16 @@ public class MantelantragITCase { return FormData.builder().representations(List.of(xdomeaFile, mantelantragFile)).build(); } + private List<GrpcEingang> captureEingangs() { + return capturedRequestsFor( + calledMethod(VorgangServiceGrpc.getStartCreationMethod())) + .stream() + .map(CapturedRequest::requests) + .flatMap(List::stream) + .map(GrpcCreateVorgangRequest::getEingang) + .toList(); + } + @SneakyThrows private long getFileSize(String fileName) { Path filePath = Path.of(FormSolutionsEngineBasedAdapterITCase.class.getClassLoader().getResource(fileName).toURI()); diff --git a/xta-adapter/pom.xml b/xta-adapter/pom.xml index e96fb6c3dd46267839a27a0e6c9b19dea237b91d..20aea7aa8aa90ed1c38c4c4f2f430ee774b83cad 100644 --- a/xta-adapter/pom.xml +++ b/xta-adapter/pom.xml @@ -92,6 +92,11 @@ <type>test-jar</type> <scope>test</scope> </dependency> + <dependency> + <groupId>org.grpcmock</groupId> + <artifactId>grpcmock-spring-boot</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build>