diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/collaboration/CollaborationITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/collaboration/CollaborationITCase.java index acd60e5393d455769e639db9f61e24cf23e11f2a..32db2a67bebf61625a2e5eea835a61eaa5c87665 100644 --- a/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/collaboration/CollaborationITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/vorgang/collaboration/CollaborationITCase.java @@ -24,14 +24,21 @@ package de.ozgcloud.vorgang.collaboration; import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.InstanceOfAssertFactories.*; import static org.awaitility.Awaitility.*; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import org.bson.types.ObjectId; 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; @@ -41,29 +48,41 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.test.annotation.DirtiesContext; +import com.google.protobuf.ByteString; + import de.ozgcloud.apilib.user.OzgCloudUserId; import de.ozgcloud.apilib.user.OzgCloudUserProfile; import de.ozgcloud.apilib.user.OzgCloudUserProfileService; +import de.ozgcloud.collaboration.CollaborationServiceGrpc.CollaborationServiceBlockingStub; +import de.ozgcloud.collaboration.GrpcGetFileContentRequest; import de.ozgcloud.command.Command; import de.ozgcloud.command.CommandStatus; import de.ozgcloud.common.test.DataITCase; import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; import de.ozgcloud.vorgang.callcontext.CallContext; +import de.ozgcloud.vorgang.callcontext.TestCallContextAttachingInterceptor; import de.ozgcloud.vorgang.callcontext.WithMockCustomUser; import de.ozgcloud.vorgang.command.CommandService; import de.ozgcloud.vorgang.command.CommandTestFactory; import de.ozgcloud.vorgang.command.CreateCommandRequest; +import de.ozgcloud.vorgang.files.FileService; +import de.ozgcloud.vorgang.files.GridFsTestFactory; +import de.ozgcloud.vorgang.files.OzgFileTestFactory; import de.ozgcloud.vorgang.vorgang.Vorgang; import de.ozgcloud.vorgang.vorgang.VorgangHead; import de.ozgcloud.vorgang.vorgang.VorgangTestFactory; import de.ozgcloud.vorgang.vorgang.ZustaendigeStelleTestFactory; +import net.devh.boot.grpc.client.inject.GrpcClient; @SpringBootTest(properties = { "grpc.server.inProcessName=test", "grpc.client.vorgang-manager.address=in-process:test", "grpc.client.ozgcloud-command-manager.address=in-process:test", + "grpc.client.file-manager.address=in-process:test", + "grpc.client.inProcess.address=in-process:test" }) @DataITCase @WithMockCustomUser @@ -78,32 +97,30 @@ class CollaborationITCase { @MockBean private OzgCloudUserProfileService ozgCloudUserProfileService; + @Mock private OzgCloudUserProfile ozgCloudUserProfile; - @BeforeEach - void init() { - mongoOperations.dropCollection(Command.class); - mongoOperations.dropCollection(Vorgang.class); - mongoOperations.dropCollection(VorgangAttachedItem.class); - when(ozgCloudUserProfile.getId()).thenReturn(OzgCloudUserId.from(CommandTestFactory.CREATED_BY)); - when(ozgCloudUserProfileService.getById(any())).thenReturn(ozgCloudUserProfile); - } - @Nested class TestCreateCollaborationVorgang { + @BeforeEach + void init() { + mongoOperations.dropCollection(Command.class); + mongoOperations.dropCollection(Vorgang.class); + mongoOperations.dropCollection(VorgangAttachedItem.class); + when(ozgCloudUserProfile.getId()).thenReturn(OzgCloudUserId.from(CommandTestFactory.CREATED_BY)); + when(ozgCloudUserProfileService.getById(any())).thenReturn(ozgCloudUserProfile); + + vorgangId = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).version(0L).build()).getId(); + } + private static final String FIELD_COLLABORATION_VORGANG_ID = "collaborationVorgangId"; private static final String TITEL = "Collaboration Vorgang"; private static final String ANFRAGE = "Anfrage"; private String vorgangId; - @BeforeEach - void init() { - vorgangId = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).version(0L).build()).getId(); - } - @Test void shouldSetCollaborationVorgangId() { var command = commandService.createCommand(buildCreateCollaborationVorgangCommand(vorgangId)); @@ -138,16 +155,14 @@ class CollaborationITCase { .bodyObject(Map.of( "titel", TITEL, "anfrage", ANFRAGE, - "zustaendigeStelle", ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID - )) + "zustaendigeStelle", ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)) .build(); } private void waitUntilCommandFinished(String commandId) { await().atMost(60, TimeUnit.SECONDS).until( () -> mongoOperations.findById(commandId, Command.class), - command -> command.getStatus() == CommandStatus.FINISHED - ); + command -> command.getStatus() == CommandStatus.FINISHED); } private Vorgang loadCollaborationVorgang(String sourceVorgangId) { @@ -158,10 +173,75 @@ class CollaborationITCase { private List<VorgangAttachedItem> loadCollaborationRequest(String vorgangId) { var query = new Query(new Criteria().andOperator( Criteria.where(VorgangAttachedItem.FIELDNAME_VORGANG_ID).is(vorgangId), - Criteria.where(VorgangAttachedItem.FIELDNAME_ITEM_NAME).is("CollaborationRequest") - )); + Criteria.where(VorgangAttachedItem.FIELDNAME_ITEM_NAME).is("CollaborationRequest"))); return mongoOperations.find(query, VorgangAttachedItem.class); } } + @DisplayName("Get file content") + @Nested + class TestGetFileContent { + + @GrpcClient("inProcess") + private CollaborationServiceBlockingStub collaborationStub; + + @Autowired + private GridFsTemplate gridFsTemplate; + + @BeforeEach + void initDatabase() { + gridFsTemplate.delete(new Query()); + } + + @Test + void shouldReturnStoredSmallFile() { + var fileId = gridFsTemplate.store(GridFsTestFactory.createUpload()); + + var file = downloadBinaryFile(fileId); + + assertThat(file).hasSameSizeAs(OzgFileTestFactory.CONTENT).isEqualTo(OzgFileTestFactory.CONTENT); + } + + @Test + void shouldReturnStoredFileWithSizeEqualChunkSize() { + var content = OzgFileTestFactory.createContentInByte(FileService.CHUNK_SIZE); + var fileId = gridFsTemplate.store(GridFsTestFactory.createUpload(content)); + + var file = downloadBinaryFile(fileId); + + assertThat(file).hasSameSizeAs(content).isEqualTo(content); + } + + @Test + void shouldReturnStoredLargeFile() { + var input = OzgFileTestFactory.createContentInMiB(5); + var fileId = gridFsTemplate + .store(GridFsTestFactory.createUpload(input)); + + var downloadedFile = downloadBinaryFile(fileId); + + assertThat(downloadedFile).hasSameSizeAs(input).isEqualTo(input); + } + + private byte[] downloadBinaryFile(ObjectId fileId) { + var request = GrpcGetFileContentRequest.newBuilder() + .setId(fileId.toHexString()).build(); + var it = prepareBinaryFileServiceBlockingStub().getFileContent(request); + var content = new ByteArrayOutputStream(); + while (it.hasNext()) { + ByteString chunkContent = it.next().getFileContent(); + try { + content.write(chunkContent.toByteArray()); + } catch (IOException e) { + fail(e); + } + } + + return content.toByteArray(); + } + + private CollaborationServiceBlockingStub prepareBinaryFileServiceBlockingStub() { + return collaborationStub.withInterceptors(new TestCallContextAttachingInterceptor()); + } + } } \ No newline at end of file