package com.constellio.model.services.search; import static com.constellio.sdk.tests.TestUtils.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.constellio.app.modules.rm.DemoTestRecords; import com.constellio.app.modules.rm.RMTestRecords; import com.constellio.app.modules.rm.services.RMSchemasRecordsServices; import com.constellio.app.modules.rm.services.decommissioning.DecommissioningService; import com.constellio.app.modules.rm.wrappers.Document; import com.constellio.app.modules.rm.wrappers.Folder; import com.constellio.app.modules.tasks.model.wrappers.Task; import com.constellio.app.modules.tasks.services.TasksSchemasRecordsServices; import com.constellio.data.io.services.facades.IOServices; import com.constellio.data.io.services.zip.ZipService; import com.constellio.model.entities.records.Content; import com.constellio.model.entities.records.Transaction; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.entities.schemas.MetadataSchema; import com.constellio.model.services.contents.ContentManager; import com.constellio.model.services.contents.ContentVersionDataSummary; import com.constellio.model.services.records.RecordServices; import com.constellio.model.services.records.RecordServicesException; import com.constellio.model.services.schemas.MetadataSchemasManager; import com.constellio.model.services.search.zipContents.ZipContentsService; import com.constellio.model.services.search.zipContents.ZipContentsService.NoContentToZipRuntimeException; import com.constellio.sdk.tests.ConstellioTest; import com.constellio.sdk.tests.setups.Users; public class ZipContentsServicesAcceptanceTest extends ConstellioTest { private static final String TEST_ID = "ZipSearchResultsContentsServicesAcceptanceTest-inputStreams"; Users users = new Users(); DecommissioningService service; RMSchemasRecordsServices rm; RMTestRecords records = new RMTestRecords(zeCollection); RecordServices recordServices; SearchServices searchServices; TasksSchemasRecordsServices taskSchemas; ZipContentsService zipSearchResultsContentsServices; ZipService zipService; //test data Content content1_title1, content1_title2, content2_title1, content2_title2, content3_title1; File content1File, content2File, content3File; String title1 = "Chevreuil.odt"; String title2 = "Grenouille.odt"; String title3 = "Poire.odt"; Document documentWithContent1HavingTitle1; Document document11WithContent1HavingTitle1InFolderA2; Document document12WithContent1HavingTitle2; Document document21WithContent2HavingTitle1; Document document22WithContent2HavingTitle2InSubFolder1; Document document31WithContent3HavingTitle1; Document documentWithoutContent; Folder folderA2WithDocument1AndSubFolder1WithContent2AndSubFolder2, subFolder1WithDocumentHavingContent2, subFolder2WithoutDocuments; Task taskWithContent1AndContent2; private ContentManager contentManager; File zippedContentsResult; List<String> selectedRecordIds; IOServices ioServices; @Before public void setUp() throws Exception { prepareSystem( withZeCollection().withConstellioRMModule().withRMTest(records) .withFoldersAndContainersOfEveryStatus().withAllTestUsers() ); rm = new RMSchemasRecordsServices(zeCollection, getAppLayerFactory()); service = new DecommissioningService(zeCollection, getAppLayerFactory()); recordServices = getModelLayerFactory().newRecordServices(); searchServices = getModelLayerFactory().newSearchServices(); taskSchemas = new TasksSchemasRecordsServices(zeCollection, getAppLayerFactory()); users.setUp(getModelLayerFactory().newUserServices()); zipSearchResultsContentsServices = new ZipContentsService(getModelLayerFactory(), zeCollection); zipService = new ZipService(new IOServices(newTempFolder())); contentManager = getModelLayerFactory().getContentManager(); ioServices = getDataLayerFactory().getIOServicesFactory().newIOServices(); initTestData(); } @After public void cleanUp() throws Exception { } @Test(expected = NoContentToZipRuntimeException.class) public void givenFolderWithNoContentWhenZipThenNoContentToZipRuntimeException() throws Exception { selectedRecordIds = asList(subFolder2WithoutDocuments.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); } @Test public void givenFolderWithContentWhenZipThenOk() throws Exception { selectedRecordIds = asList(subFolder1WithDocumentHavingContent2.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); assertZipHasContents(zippedContentsResult, asList(content2File)); File unzippedResult = newTempFolder(); zipService.unzip(zippedContentsResult, unzippedResult); assertThat(unzippedResult.list()).containsOnly(subFolder1WithDocumentHavingContent2.getTitle()); } @Test public void givenDocumentAndFolderContainingDocumentSelectedWhenZipThenDocumentAppearsOnlyInItsFolder() throws Exception { selectedRecordIds = asList(subFolder1WithDocumentHavingContent2.getId(), document22WithContent2HavingTitle2InSubFolder1.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); assertZipHasContents(zippedContentsResult, asList(content2File)); File unzippedResult = newTempFolder(); zipService.unzip(zippedContentsResult, unzippedResult); assertThat(unzippedResult.list()).containsOnly(subFolder1WithDocumentHavingContent2.getTitle()); } @Test public void givenFolderAndItsSubFolderSelectedWhenZipThenSubFolderOnlyOnceInZip() throws Exception { selectedRecordIds = asList(folderA2WithDocument1AndSubFolder1WithContent2AndSubFolder2.getId(), subFolder1WithDocumentHavingContent2.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); assertZipHasContents(zippedContentsResult, asList(content1File, content2File)); File unzippedResult = newTempFolder(); zipService.unzip(zippedContentsResult, unzippedResult); assertThat(unzippedResult.list()).containsOnly(folderA2WithDocument1AndSubFolder1WithContent2AndSubFolder2.getTitle()); File folderA2Unzipped = new File(unzippedResult, folderA2WithDocument1AndSubFolder1WithContent2AndSubFolder2.getTitle()); assertThat(folderA2Unzipped.list()).containsOnly(subFolder1WithDocumentHavingContent2.getTitle(), content1_title1.getCurrentVersion().getFilename()); File subFolder1WithDocumentHavingContent2File = new File(folderA2Unzipped, subFolder1WithDocumentHavingContent2.getTitle()); assertThat(subFolder1WithDocumentHavingContent2File.list()) .containsOnly(content2_title2.getCurrentVersion().getFilename()); } @Test(expected = NoContentToZipRuntimeException.class) public void givenDocumentWithNoContentWhenZipThenNoContentToZipRuntimeException() throws Exception { selectedRecordIds = asList(documentWithoutContent.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); } @Test public void givenDocumentWithContentWhenZipThenOk() throws Exception { selectedRecordIds = asList(document12WithContent1HavingTitle2.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); assertZipHasContentsWithTitles(zippedContentsResult, asList(content1File), asList(title2)); } @Test public void givenRecordsWithSameContentHashAndSameTitleWhenZipThenOk() throws Exception { selectedRecordIds = asList(document11WithContent1HavingTitle1InFolderA2.getId(), documentWithContent1HavingTitle1.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); assertZipHasContentsWithTitles(zippedContentsResult, asList(content1File, content1File), asList("Chevreuil(" + document11WithContent1HavingTitle1InFolderA2.getId() + ").odt", "Chevreuil(" + documentWithContent1HavingTitle1.getId() + ").odt")); } @Test public void givenRecordsWithSameContentHashAndDifferentTitleWhenZipThenTwoZippedFilesWithDifferentTitles() throws Exception { selectedRecordIds = asList(document11WithContent1HavingTitle1InFolderA2.getId(), document12WithContent1HavingTitle2.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); assertZipHasContentsWithTitles(zippedContentsResult, asList(content1File, content1File), asList(title1, title2)); } @Test public void givenRecordsWithDifferentContentHashAndDifferentTitleWhenZipThenTwoZippedFilesWithDifferentTitles() throws Exception { selectedRecordIds = asList(document11WithContent1HavingTitle1InFolderA2.getId(), document22WithContent2HavingTitle2InSubFolder1.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); assertZipHasContentsWithTitles(zippedContentsResult, asList(content1File, content2File), asList(title1, title2)); } @Test public void givenRecordsWithThreeDifferentContentHashAndSameTitleWhenZipThenThreeZippedFilesWithDifferentTitles() throws Exception { selectedRecordIds = asList(document11WithContent1HavingTitle1InFolderA2.getId(), document21WithContent2HavingTitle1.getId(), document31WithContent3HavingTitle1.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); assertZipHasContentsWithTitles(zippedContentsResult, asList(content1File, content2File, content3File), asList("Chevreuil(" + document11WithContent1HavingTitle1InFolderA2.getId() + ").odt", "Chevreuil(" + document21WithContent2HavingTitle1.getId() + ").odt", "Chevreuil(" + document31WithContent3HavingTitle1.getId() + ").odt")); } @Test public void givenTaskWithTwoContentsWhenZipThenTwoContentsZippedCorrectly() throws Exception { selectedRecordIds = asList(taskWithContent1AndContent2.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); assertZipHasContents(zippedContentsResult, asList(content1File, content2File)); File unzippedResult = newTempFolder(); zipService.unzip(zippedContentsResult, unzippedResult); assertThat(unzippedResult.list()).containsOnly(taskWithContent1AndContent2.getTitle()); File taskUnzipped = new File(unzippedResult, taskWithContent1AndContent2.getTitle()); assertThat(taskUnzipped.list()).containsOnly(title1, title2); } @Test public void whenCanHaveChildrenThenOk() throws Exception { MetadataSchemasManager metadataSchemaManager = getModelLayerFactory() .getMetadataSchemasManager(); MetadataSchema schema = metadataSchemaManager.getSchemaTypes(zeCollection) .getSchema(Folder.SCHEMA_TYPE + "_default"); assertThat(zipSearchResultsContentsServices.canHaveChildren(schema)).isTrue(); schema = metadataSchemaManager.getSchemaTypes(zeCollection) .getSchema(Task.SCHEMA_TYPE + "_default"); assertThat(zipSearchResultsContentsServices.canHaveChildren(schema)).isTrue(); schema = metadataSchemaManager.getSchemaTypes(zeCollection) .getSchema(Document.SCHEMA_TYPE + "_default"); assertThat(zipSearchResultsContentsServices.canHaveChildren(schema)).isFalse(); } @Test public void givenDocumentWithContentWhenZipThenContentZippedCorrectly() throws Exception { selectedRecordIds = asList(document11WithContent1HavingTitle1InFolderA2.getId()); zipSearchResultsContentsServices.zipContentsOfRecords(selectedRecordIds, zippedContentsResult); assertZipHasContentsWithTitles(zippedContentsResult, asList(content1File), asList(title1)); } private void initTestData() throws RecordServicesException { Transaction transaction = new Transaction(); content1_title1 = createContent(title1, title1); content1_title2 = createContent(title1, title2); content2_title1 = createContent(title2, title1); content2_title2 = createContent(title2, title2); content3_title1 = createContent(title3, title1); File folder = newTempFolder(); content1File = createFileFromContent(content1_title1, folder.getPath() + "/1"); content2File = createFileFromContent(content2_title2, folder.getPath() + "/2"); content3File = createFileFromContent(content3_title1, folder.getPath() + "/3"); documentWithContent1HavingTitle1 = rm.newDocument().setType(records.documentTypeId_1) .setFolder(records.getFolder_A01().getId()); transaction.add(documentWithContent1HavingTitle1.setContent(content1_title1).setTitle(title1)); folderA2WithDocument1AndSubFolder1WithContent2AndSubFolder2 = records.getFolder_A02(); document11WithContent1HavingTitle1InFolderA2 = rm.newDocument().setType(records.documentTypeId_1) .setFolder(folderA2WithDocument1AndSubFolder1WithContent2AndSubFolder2); transaction.add(document11WithContent1HavingTitle1InFolderA2.setContent(content1_title1).setTitle(title1)); document12WithContent1HavingTitle2 = rm.newDocument().setType(records.documentTypeId_1).setFolder( records.getFolder_A01().getId()); transaction.add(document12WithContent1HavingTitle2.setContent(content1_title2).setTitle(title2)); document21WithContent2HavingTitle1 = rm.newDocument().setType(records.documentTypeId_1).setFolder( records.getFolder_A01().getId()); transaction.add(document21WithContent2HavingTitle1.setContent(content2_title1).setTitle(title1)); document22WithContent2HavingTitle2InSubFolder1 = rm.newDocument().setType(records.documentTypeId_1).setFolder( records.getFolder_A01().getId()); transaction.add(document22WithContent2HavingTitle2InSubFolder1.setContent(content2_title2).setTitle(title2)); documentWithoutContent = rm.newDocument().setType(records.documentTypeId_1).setTitle("withoutContent").setFolder( records.getFolder_A01().getId()); transaction.add(documentWithoutContent); document31WithContent3HavingTitle1 = rm.newDocument().setType(records.documentTypeId_1).setFolder( records.getFolder_A01().getId()); transaction.add(document31WithContent3HavingTitle1.setTitle(title1).setContent(content3_title1)); taskWithContent1AndContent2 = taskSchemas.newTask().setTitle("zeTask") .setContent(asList(content1_title1, content2_title2)); transaction.add(taskWithContent1AndContent2); subFolder1WithDocumentHavingContent2 = records.getFolder_A03(); subFolder2WithoutDocuments = records.getFolder_A13(); //FIXME Cis car pas meme regle? recordServices.add(records.getFolder_A04().setParentFolder(records.getFolder_A02())); transaction.add(document22WithContent2HavingTitle2InSubFolder1.setFolder(subFolder1WithDocumentHavingContent2)); transaction.add(subFolder1WithDocumentHavingContent2 .setParentFolder(folderA2WithDocument1AndSubFolder1WithContent2AndSubFolder2)); transaction.add(subFolder2WithoutDocuments.setParentFolder(folderA2WithDocument1AndSubFolder1WithContent2AndSubFolder2)); recordServices.execute(transaction); zippedContentsResult = new File(newTempFolder().getPath() + "result.zip"); } private File createFileFromContent(Content content, String filePath) { InputStream inputStream = null; try { inputStream = contentManager.getContentInputStream(content.getCurrentVersion().getHash(), TEST_ID); FileUtils.copyInputStreamToFile(inputStream, new File(filePath)); return new File(filePath); } catch (Exception e) { fail(e.getMessage()); return null; } finally { ioServices.closeQuietly(inputStream); } } private void assertZipHasContentsWithTitles(File zippedContents, List<File> contents, List<String> titles) throws Exception { for (File content : contents) { assertThat(zipService.contains(zippedContents, content.getPath())); } File zipDestination = newTempFolder(); zipService.unzip(zippedContents, zipDestination); String[] zippedFilesPaths = zipDestination.list(); assertThat(zipDestination.list().length).isEqualTo(contents.size()); assertFilesTitlesAreValid(zippedFilesPaths, titles); } private void assertZipHasContents(File zippedContents, List<File> contents) throws Exception { for (File content : contents) { assertThat(zipService.contains(zippedContents, content.getPath())); } } private void assertFilesTitlesAreValid(String[] filesPaths, List<String> titles) { List<String> filesTitles = new ArrayList<>(); for (String filePath : filesPaths) { File file = new File(filePath); filesTitles.add(file.getName()); } assertThat(filesTitles).containsAll(titles); } private Content createContent(String resource, String title) { User user = users.adminIn(zeCollection); ContentVersionDataSummary version01 = upload("Minor_" + resource); Content content = contentManager.createMinor(user, title, version01); ContentVersionDataSummary version10 = upload("Major_" + resource); content.updateContent(user, version10, true); return content; } private ContentVersionDataSummary upload(String resource) { InputStream inputStream = DemoTestRecords.class.getResourceAsStream("RMTestRecords_" + resource); return contentManager.upload(inputStream); } }