/* DigiDoc4J library * * This software is released under either the GNU Library General Public * License (see LICENSE.LGPL). * * Note that the only valid version of the LGPL license as far as this * project is concerned is the original GNU Library General Public License * Version 2.1, February 1999 */ package org.digidoc4j; import static org.apache.commons.lang.StringUtils.containsIgnoreCase; import static org.digidoc4j.ContainerBuilder.BDOC_CONTAINER_TYPE; import static org.digidoc4j.ContainerBuilder.DDOC_CONTAINER_TYPE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipFile; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.digidoc4j.exceptions.InvalidDataFileException; import org.digidoc4j.impl.DigiDoc4JTestHelper; import org.digidoc4j.impl.bdoc.BDocContainer; import org.digidoc4j.impl.bdoc.NewBDocContainer; import org.digidoc4j.impl.ddoc.DDocContainer; import org.digidoc4j.impl.ddoc.DDocSignature; import org.digidoc4j.testutils.CustomConfiguration; import org.digidoc4j.testutils.TestContainer; import org.digidoc4j.testutils.TestDataBuilder; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; public class ContainerBuilderTest extends DigiDoc4JTestHelper { public static final Configuration TEST_CONFIGURATION = new Configuration(Configuration.Mode.TEST); private static final String BDOC_TEST_FILE = "testFiles/one_signature.bdoc"; private static final String DDOC_TEST_FILE = "testFiles/ddoc_for_testing.ddoc"; private File tempFolder; @Rule public TemporaryFolder testFolder = new TemporaryFolder(); @Before public void setUp() throws Exception { tempFolder = testFolder.newFolder(); } @After public void tearDown() throws Exception { ContainerBuilder.removeCustomContainerImplementations(); } @Test public void buildEmptyContainer() throws Exception { ContainerBuilder builder = ContainerBuilder.aContainer(); Container container = builder.build(); assertEquals("BDOC", container.getType()); assertTrue(container.getDataFiles().isEmpty()); assertTrue(container.getSignatures().isEmpty()); } @Test public void buildDDocContainer() throws Exception { Container container = ContainerBuilder. aContainer(DDOC_CONTAINER_TYPE). build(); assertEquals("DDOC", container.getType()); assertTrue(container.getDataFiles().isEmpty()); assertTrue(container.getSignatures().isEmpty()); } @Test public void buildBDocContainer() throws Exception { Configuration configuration = new Configuration(Configuration.Mode.TEST); configuration.setTspSource("test-value"); Container container = ContainerBuilder. aContainer(BDOC_CONTAINER_TYPE). withConfiguration(configuration). build(); BDocContainer bDocContainer = (BDocContainer) container; assertEquals("BDOC", container.getType()); assertEquals("test-value", bDocContainer.getConfiguration().getTspSource()); } @Test public void buildBDocContainerWithDataFiles() throws Exception { File testFile1 = createTestFile("testFile.txt"); File testFile2 = createTestFile("testFile2.txt"); LargeDataFile largeDataFile = new LargeDataFile(new ByteArrayInputStream(new byte[]{1, 2, 3}), "largeStreamFile.txt", "text/plain"); Container container = ContainerBuilder. aContainer(). withDataFile(testFile1.getPath(), "text/plain"). withDataFile(new ByteArrayInputStream(new byte[]{1, 2, 3}), "streamFile.txt", "text/plain"). withDataFile(createTestFile("ExampleFile.txt"), "text/plain"). withDataFile(new DataFile(testFile2.getPath(), "text/plain")). withDataFile(largeDataFile). build(); assertEquals(5, container.getDataFiles().size()); assertEquals("testFile.txt", container.getDataFiles().get(0).getName()); assertEquals("streamFile.txt", container.getDataFiles().get(1).getName()); assertEquals("ExampleFile.txt", container.getDataFiles().get(2).getName()); assertEquals("testFile2.txt", container.getDataFiles().get(3).getName()); assertEquals("largeStreamFile.txt", container.getDataFiles().get(4).getName()); } @Test public void buildDDocContainerWithDataFiles() throws Exception { File testFile1 = createTestFile("testFile.txt"); File testFile2 = createTestFile("testFile2.txt"); Container container = ContainerBuilder. aContainer(DDOC_CONTAINER_TYPE). withDataFile(testFile1.getPath(), "text/plain"). withDataFile(new ByteArrayInputStream(new byte[]{1, 2, 3}), "streamFile.txt", "text/plain"). withDataFile(createTestFile("ExampleFile.txt"), "text/plain"). withDataFile(new DataFile(testFile2.getPath(), "text/plain")). build(); assertEquals(4, container.getDataFiles().size()); assertEquals("testFile.txt", container.getDataFiles().get(0).getName()); assertEquals("streamFile.txt", container.getDataFiles().get(1).getName()); assertEquals("ExampleFile.txt", container.getDataFiles().get(2).getName()); assertEquals("testFile2.txt", container.getDataFiles().get(3).getName()); } @Test(expected = InvalidDataFileException.class) public void buildContainer_withNullFilePath_shouldThrowException() throws Exception { String path = null; ContainerBuilder. aContainer(). withDataFile(path, "text/plain"). build(); } @Test(expected = InvalidDataFileException.class) public void buildContainer_withStreamDocAndNullFileName_shouldThrowException() throws Exception { String name = null; ContainerBuilder. aContainer(). withDataFile(new ByteArrayInputStream(new byte[]{1, 2, 3}), name, "text/plain"). build(); } @Test(expected = InvalidDataFileException.class) public void buildContainer_withNullMimeType_shouldThrowException() throws Exception { String mimeType = null; ContainerBuilder. aContainer(). withDataFile("testFile.txt", mimeType). build(); } @Test(expected = InvalidDataFileException.class) public void buildContainer_withInvalidMimeType_shouldThrowException() throws Exception { String mimeType = "application\\rtf"; ContainerBuilder. aContainer(). withDataFile("testFiles/test.txt", mimeType). build(); } @Test public void signAndValidateContainer() throws Exception { Container container = TestDataBuilder.createContainerWithFile(testFolder); TestDataBuilder.signContainer(container); ValidationResult result = container.validate(); assertFalse(result.hasErrors()); assertFalse(result.hasWarnings()); assertTrue(result.getContainerErrors().isEmpty()); assertTrue(result.isValid()); assertTrue(containsIgnoreCase(result.getReport(), "<Indication>TOTAL_PASSED</Indication>")); } @Test public void saveContainerWithoutSignaturesToFile() throws Exception { File dataFile = TestDataBuilder.createTestFile(testFolder); Container container = TestDataBuilder.createContainerWithFile(dataFile.getPath()); String filePath = testFolder.newFile("test-container.bdoc").getPath(); File containerFile = container.saveAsFile(filePath); assertTrue(FileUtils.sizeOf(containerFile) > 0); ZipFile zip = new ZipFile(filePath); assertNotNull(zip.getEntry("mimetype")); assertNotNull(zip.getEntry("META-INF/manifest.xml")); assertNotNull(zip.getEntry(dataFile.getName())); } @Test public void signAndSaveContainerToFile() throws Exception { Container container = TestDataBuilder.createContainerWithFile(testFolder); TestDataBuilder.signContainer(container); assertEquals(1, container.getSignatures().size()); String filePath = testFolder.newFile("test-container.bdoc").getPath(); File file = container.saveAsFile(filePath); assertTrue(FileUtils.sizeOf(file) > 0); ZipFile zip = new ZipFile(filePath); assertNotNull(zip.getEntry("META-INF/signatures0.xml")); } @Test public void signAndSaveContainerToStream() throws Exception { Container container = TestDataBuilder.createContainerWithFile(testFolder); TestDataBuilder.signContainer(container); InputStream stream = container.saveAsStream(); byte[] bytes = IOUtils.toByteArray(stream); assertTrue(bytes.length > 10); } @Test public void signAndSaveDDocContainerToStream() throws Exception { File testFile = createTestFile("testFile.txt"); Container container = ContainerBuilder. aContainer(DDOC_CONTAINER_TYPE). withConfiguration(TEST_CONFIGURATION). withDataFile(testFile, "text/plain"). build(); TestDataBuilder.signContainer(container, DigestAlgorithm.SHA1); InputStream stream = container.saveAsStream(); byte[] bytes = IOUtils.toByteArray(stream); assertTrue(bytes.length > 10); } @Test public void addAndRemoveSignatureFromDDocContainer() throws Exception { File testFile = createTestFile("testFile.txt"); Container container = ContainerBuilder. aContainer(DDOC_CONTAINER_TYPE). withConfiguration(TEST_CONFIGURATION). withDataFile(testFile, "text/plain"). build(); DDocSignature signature1 = (DDocSignature) TestDataBuilder.signContainer(container, DigestAlgorithm.SHA1); DDocSignature signature2 = (DDocSignature) TestDataBuilder.signContainer(container, DigestAlgorithm.SHA1); assertEquals(0, ((DDocSignature) container.getSignatures().get(0)).getIndexInArray()); assertEquals(1, ((DDocSignature) container.getSignatures().get(1)).getIndexInArray()); assertEquals(0, signature1.getIndexInArray()); assertEquals(1, signature2.getIndexInArray()); } @Test public void removeSignatureFromSignedContainer() throws Exception { Container container = TestDataBuilder.createContainerWithFile(testFolder); Signature signature = TestDataBuilder.signContainer(container); container.saveAsFile(testFolder.newFile("test-container.bdoc").getPath()); container.removeSignature(signature); assertTrue(container.getSignatures().isEmpty()); } @Test public void buildCustomContainerWithCustomImplementation() throws Exception { ContainerBuilder.setContainerImplementation("TEST-FORMAT", TestContainer.class); Container container = ContainerBuilder. aContainer("TEST-FORMAT"). build(); assertEquals("TEST-FORMAT", container.getType()); } @Test public void overrideExistingBDocContainerImplementation() throws Exception { ContainerBuilder.setContainerImplementation("BDOC", TestContainer.class); Container container = ContainerBuilder. aContainer("BDOC"). build(); assertEquals("TEST-FORMAT", container.getType()); } @Test public void useExtendedBDocContainerImplementation() throws Exception { ContainerBuilder.setContainerImplementation("BDOC", ExtendedBDocContainer.class); Container container = ContainerBuilder. aContainer("BDOC"). build(); assertEquals("BDOC-EXTENDED", container.getType()); } @Test public void clearCustomContainerImplementations_shouldUseDefaultContainerImplementation() throws Exception { ContainerBuilder.setContainerImplementation("BDOC", ExtendedBDocContainer.class); ContainerBuilder.removeCustomContainerImplementations(); Container container = ContainerBuilder. aContainer("BDOC"). build(); assertEquals("BDOC", container.getType()); } @Test public void createCustomContainerWithConfiguration() throws Exception { ContainerBuilder.setContainerImplementation("TEST-FORMAT", TestContainer.class); Container container = ContainerBuilder. aContainer("TEST-FORMAT"). withConfiguration(TEST_CONFIGURATION). build(); assertEquals("TEST-FORMAT", container.getType()); assertSame(TEST_CONFIGURATION, ((TestContainer) container).getConfiguration()); } @Test public void createCustomContainerWithCustomConfiguration() throws Exception { ContainerBuilder.setContainerImplementation("TEST-FORMAT", TestContainer.class); CustomConfiguration configuration = new CustomConfiguration(); Container container = ContainerBuilder. aContainer("TEST-FORMAT"). withConfiguration(configuration). build(); assertEquals("TEST-FORMAT", container.getType()); assertSame(configuration, ((TestContainer) container).getConfiguration()); } @Test public void openDefaultContainerFromFile() throws Exception { Container container = ContainerBuilder. aContainer(). fromExistingFile(BDOC_TEST_FILE). build(); assertContainerOpened(container, "BDOC"); } @Test public void openDefaultContainerFromFileWithConfiguration() throws Exception { Configuration configuration = new Configuration(Configuration.Mode.TEST); configuration.setTspSource("test-value"); Container container = ContainerBuilder. aContainer(). fromExistingFile(BDOC_TEST_FILE). withConfiguration(configuration). build(); assertContainerOpened(container, "BDOC"); assertEquals("test-value", ((BDocContainer) container).getConfiguration().getTspSource()); } @Test public void openDDocContainerFromFile_whenUsingDefaultContainer() throws Exception { Container container = ContainerBuilder. aContainer(). fromExistingFile(DDOC_TEST_FILE). build(); assertContainerOpened(container, "DDOC"); } @Test public void openDDocContainerFromFile() throws Exception { Container container = ContainerBuilder. aContainer("DDOC"). fromExistingFile(DDOC_TEST_FILE). build(); assertContainerOpened(container, "DDOC"); } @Test public void openCustomContainerFromFile() throws Exception { File testFile = createTestFile("testFile.txt"); ContainerBuilder.setContainerImplementation("TEST-FORMAT", TestContainer.class); Container container = ContainerBuilder. aContainer("TEST-FORMAT"). fromExistingFile(testFile.getPath()). build(); assertEquals("TEST-FORMAT", container.getType()); assertEquals(testFile.getPath(), ((TestContainer) container).getOpenedFromFile()); } @Test public void openCustomContainerFromFile_withConfiguration() throws Exception { File testFile = createTestFile("testFile.txt"); ContainerBuilder.setContainerImplementation("TEST-FORMAT", TestContainer.class); Container container = ContainerBuilder. aContainer("TEST-FORMAT"). withConfiguration(TEST_CONFIGURATION). fromExistingFile(testFile.getPath()). build(); assertEquals("TEST-FORMAT", container.getType()); assertEquals(testFile.getPath(), ((TestContainer) container).getOpenedFromFile()); assertSame(TEST_CONFIGURATION, ((TestContainer) container).getConfiguration()); } @Test public void openCustomContainerFromFile_withCustomConfiguration() throws Exception { CustomConfiguration configuration = new CustomConfiguration(Configuration.Mode.TEST); File testFile = createTestFile("testFile.txt"); ContainerBuilder.setContainerImplementation("TEST-FORMAT", TestContainer.class); Container container = ContainerBuilder. aContainer("TEST-FORMAT"). withConfiguration(configuration). fromExistingFile(testFile.getPath()). build(); assertEquals("TEST-FORMAT", container.getType()); assertEquals(testFile.getPath(), ((TestContainer) container).getOpenedFromFile()); assertSame(configuration, ((TestContainer) container).getConfiguration()); } @Test public void openBDocContainerFromStream() throws Exception { InputStream stream = FileUtils.openInputStream(new File(BDOC_TEST_FILE)); Container container = ContainerBuilder. aContainer("BDOC"). fromStream(stream). build(); assertContainerOpened(container, "BDOC"); } @Test public void openBDocContainerFromStream_withConfiguration() throws Exception { Configuration configuration = new Configuration(Configuration.Mode.TEST); configuration.setTspSource("test-value"); InputStream stream = FileUtils.openInputStream(new File(BDOC_TEST_FILE)); Container container = ContainerBuilder. aContainer("BDOC"). withConfiguration(configuration). fromStream(stream). build(); assertContainerOpened(container, "BDOC"); assertEquals("test-value", ((BDocContainer) container).getConfiguration().getTspSource()); } @Test public void openDDocContainerFromStream() throws Exception { InputStream stream = FileUtils.openInputStream(new File(DDOC_TEST_FILE)); Container container = ContainerBuilder. aContainer("DDOC"). fromStream(stream). build(); assertContainerOpened(container, "DDOC"); } @Test public void openDDocContainerFromStream_withConfiguration() throws Exception { InputStream stream = FileUtils.openInputStream(new File(DDOC_TEST_FILE)); Container container = ContainerBuilder. aContainer("DDOC"). withConfiguration(TEST_CONFIGURATION). fromStream(stream). build(); assertContainerOpened(container, "DDOC"); assertSame(TEST_CONFIGURATION, ((DDocContainer) container).getJDigiDocFacade().getConfiguration()); } @Test public void openDefaultContainerFromStream_withBDOC() throws Exception { InputStream stream = FileUtils.openInputStream(new File(BDOC_TEST_FILE)); Container container = ContainerBuilder. aContainer(). withConfiguration(TEST_CONFIGURATION). fromStream(stream). build(); assertContainerOpened(container, "BDOC"); } @Test public void openDefaultContainerFromStream_withDDOC() throws Exception { InputStream stream = FileUtils.openInputStream(new File(DDOC_TEST_FILE)); Container container = ContainerBuilder. aContainer(). withConfiguration(TEST_CONFIGURATION). fromStream(stream). build(); assertContainerOpened(container, "DDOC"); } @Test public void openCustomContainerFromStream() throws Exception { InputStream stream = FileUtils.openInputStream(createTestFile("testFile.txt")); ContainerBuilder.setContainerImplementation("TEST-FORMAT", TestContainer.class); Container container = ContainerBuilder. aContainer("TEST-FORMAT"). fromStream(stream). build(); assertEquals("TEST-FORMAT", container.getType()); assertSame(stream, ((TestContainer) container).getOpenedFromStream()); } @Test public void openCustomContainerFromStream_withConfiguration() throws Exception { InputStream stream = FileUtils.openInputStream(createTestFile("testFile.txt")); ContainerBuilder.setContainerImplementation("TEST-FORMAT", TestContainer.class); Container container = ContainerBuilder. aContainer("TEST-FORMAT"). withConfiguration(TEST_CONFIGURATION). fromStream(stream). build(); assertEquals("TEST-FORMAT", container.getType()); assertSame(stream, ((TestContainer) container).getOpenedFromStream()); assertSame(TEST_CONFIGURATION, ((TestContainer) container).getConfiguration()); } @Test public void openCustomContainerFromStream_withCustomConfiguration() throws Exception { CustomConfiguration configuration = new CustomConfiguration(); InputStream stream = FileUtils.openInputStream(createTestFile("testFile.txt")); ContainerBuilder.setContainerImplementation("TEST-FORMAT", TestContainer.class); Container container = ContainerBuilder. aContainer("TEST-FORMAT"). withConfiguration(configuration). fromStream(stream). build(); assertEquals("TEST-FORMAT", container.getType()); assertSame(stream, ((TestContainer) container).getOpenedFromStream()); assertSame(configuration, ((TestContainer) container).getConfiguration()); } @Test public void openDDocContainerWithTempDirectory() throws Exception { assertTrue(tempFolder.exists()); assertTrue(tempFolder.list().length == 0); ContainerBuilder. aContainer(DDOC_CONTAINER_TYPE). fromExistingFile("testFiles/ddoc_for_testing.ddoc"). usingTempDirectory(tempFolder.getPath()). build(); assertTrue(tempFolder.list().length > 0); } @Test public void openDDocContainerWithTempDirectoryAndConfiguration() throws Exception { assertTrue(tempFolder.list().length == 0); ContainerBuilder. aContainer(DDOC_CONTAINER_TYPE). fromExistingFile("testFiles/ddoc_for_testing.ddoc"). withConfiguration(TEST_CONFIGURATION). usingTempDirectory(tempFolder.getPath()). build(); assertTrue(tempFolder.list().length > 0); } @Test public void openDDocContainerFromStreamWithTempDirectory() throws Exception { assertTrue(tempFolder.list().length == 0); InputStream stream = FileUtils.openInputStream(new File(DDOC_TEST_FILE)); ContainerBuilder. aContainer("DDOC"). fromStream(stream). usingTempDirectory(tempFolder.getPath()). build(); assertTrue(tempFolder.list().length > 0); } @Test public void openDDocContainerFromStreamWithTempDirectoryAndConfiguration() throws Exception { assertTrue(tempFolder.list().length == 0); InputStream stream = FileUtils.openInputStream(new File(DDOC_TEST_FILE)); ContainerBuilder. aContainer("DDOC"). withConfiguration(TEST_CONFIGURATION). fromStream(stream). usingTempDirectory(tempFolder.getPath()). build(); assertTrue(tempFolder.list().length > 0); } private File createTestFile(String fileName) throws IOException { File testFile1 = testFolder.newFile(fileName); FileUtils.writeStringToFile(testFile1, "Banana Pancakes"); return testFile1; } private void assertContainerOpened(Container container, String containerType) { assertEquals(containerType, container.getType()); assertFalse(container.getDataFiles().isEmpty()); assertFalse(container.getSignatures().isEmpty()); } public static class ExtendedBDocContainer extends NewBDocContainer { @Override public String getType() { return "BDOC-EXTENDED"; } } }