diff --git a/alfresco-docker-alfresco-pdf-renderer/pom.xml b/alfresco-docker-alfresco-pdf-renderer/pom.xml index 0e95212e..a88a499a 100644 --- a/alfresco-docker-alfresco-pdf-renderer/pom.xml +++ b/alfresco-docker-alfresco-pdf-renderer/pom.xml @@ -4,8 +4,6 @@ Alfresco Docker Pdf Renderer jar - 0.9-SNAPSHOT - org.alfresco alfresco-docker-transformers @@ -50,6 +48,14 @@ alfresco-core ${dependency.alfresco-core.version} + + org.alfresco + alfresco-transformer-base + ${project.version} + tests + test-jar + test + diff --git a/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/AlfrescoPdfRendererController.java b/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/AlfrescoPdfRendererController.java index cbf1815f..7f605c18 100644 --- a/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/AlfrescoPdfRendererController.java +++ b/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/AlfrescoPdfRendererController.java @@ -103,6 +103,7 @@ public class AlfrescoPdfRendererController extends AbstractTransformerController @RequestParam("file") MultipartFile sourceMultipartFile, @RequestParam("targetExtension") String targetExtension, @RequestParam(value = "timeout", required = false) Long timeout, + @RequestParam(value = "testDelay", required = false) Long testDelay, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "width", required = false) Integer width, @@ -146,6 +147,6 @@ public class AlfrescoPdfRendererController extends AbstractTransformerController executeTransformCommand(properties, targetFile, timeout); - return createAttachment(targetFilename, targetFile); + return createAttachment(targetFilename, targetFile, testDelay); } } diff --git a/alfresco-docker-alfresco-pdf-renderer/src/main/resources/templates/transformForm.html b/alfresco-docker-alfresco-pdf-renderer/src/main/resources/templates/transformForm.html index f142aeee..3d16a701 100644 --- a/alfresco-docker-alfresco-pdf-renderer/src/main/resources/templates/transformForm.html +++ b/alfresco-docker-alfresco-pdf-renderer/src/main/resources/templates/transformForm.html @@ -5,16 +5,17 @@

Alfresco PDF Renderer Test Transformation

- - - + + + + + + - - - - - - + + + +
file *
targetExtension *
timeout
file *
targetExtension *
timeout
testDelay
page
page
width
height
allowEnlargement
maintainAspectRatio
width
height
allowEnlargement
maintainAspectRatio
diff --git a/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererControllerTest.java b/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererControllerTest.java new file mode 100644 index 00000000..15ffbd28 --- /dev/null +++ b/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererControllerTest.java @@ -0,0 +1,52 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transformer; + +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.IOException; + +/** + * Test the AlfrescoPdfRendererControllerTest without a server. + * Super class includes tests for the AbstractTransformerController. + */ +@RunWith(SpringRunner.class) +@WebMvcTest(AlfrescoPdfRendererController.class) +public class AlfrescoPdfRendererControllerTest extends AbstractTransformerControllerTest +{ + @SpyBean + private AlfrescoPdfRendererController controller; + + @Before + public void before() throws IOException + { + super.mockTransformCommand(controller, "pdf", "png", "application/pdf"); + } +} diff --git a/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererHttpRequestTest.java b/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererHttpRequestTest.java new file mode 100644 index 00000000..c4de8383 --- /dev/null +++ b/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererHttpRequestTest.java @@ -0,0 +1,51 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transformer; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Tests AlfrescoPdfRendererHttpRequestTest with a server test harness. + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class AlfrescoPdfRendererHttpRequestTest extends AbstractHttpRequestTest +{ + @Override + protected String getTransformerName() + { + return "Alfresco PDF Renderer"; + } + + @Override + protected String getSourceExtension() + { + return "pdf"; + }; +} \ No newline at end of file diff --git a/alfresco-docker-alfresco-pdf-renderer/src/test/resources/quick.pdf b/alfresco-docker-alfresco-pdf-renderer/src/test/resources/quick.pdf new file mode 100644 index 00000000..a1779afd Binary files /dev/null and b/alfresco-docker-alfresco-pdf-renderer/src/test/resources/quick.pdf differ diff --git a/alfresco-docker-alfresco-pdf-renderer/src/test/resources/quick.png b/alfresco-docker-alfresco-pdf-renderer/src/test/resources/quick.png new file mode 100644 index 00000000..8f1f89b8 Binary files /dev/null and b/alfresco-docker-alfresco-pdf-renderer/src/test/resources/quick.png differ diff --git a/alfresco-docker-imagemagick/pom.xml b/alfresco-docker-imagemagick/pom.xml index 732dcd0b..1e289539 100644 --- a/alfresco-docker-imagemagick/pom.xml +++ b/alfresco-docker-imagemagick/pom.xml @@ -4,8 +4,6 @@ Alfresco Docker ImageMagick jar - 0.9-SNAPSHOT - org.alfresco alfresco-docker-transformers @@ -50,6 +48,14 @@ alfresco-core ${dependency.alfresco-core.version} + + org.alfresco + alfresco-transformer-base + ${project.version} + tests + test-jar + test + diff --git a/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/ImageMagickController.java b/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/ImageMagickController.java index 837b77ff..6f81dbd6 100644 --- a/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/ImageMagickController.java +++ b/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/ImageMagickController.java @@ -114,6 +114,7 @@ public class ImageMagickController extends AbstractTransformerController @RequestParam("file") MultipartFile sourceMultipartFile, @RequestParam("targetExtension") String targetExtension, @RequestParam(value = "timeout", required = false) Long timeout, + @RequestParam(value = "testDelay", required = false) Long testDelay, @RequestParam(value = "startPage", required = false) Integer startPage, @RequestParam(value = "endPage", required = false) Integer endPage, @@ -138,7 +139,11 @@ public class ImageMagickController extends AbstractTransformerController if (cropGravity != null) { cropGravity = cropGravity.trim(); - if (!cropGravity.isEmpty() && !GRAVITY_VALUES.contains(cropGravity)) + if (cropGravity.isEmpty()) + { + cropGravity = null; + } + else if (!GRAVITY_VALUES.contains(cropGravity)) { throw new TransformException(400, "Invalid cropGravity value"); } @@ -258,6 +263,6 @@ public class ImageMagickController extends AbstractTransformerController executeTransformCommand(properties, targetFile, timeout); - return createAttachment(targetFilename, targetFile); + return createAttachment(targetFilename, targetFile, testDelay); } } diff --git a/alfresco-docker-imagemagick/src/main/resources/templates/transformForm.html b/alfresco-docker-imagemagick/src/main/resources/templates/transformForm.html index a33c40d9..3ced2d95 100644 --- a/alfresco-docker-imagemagick/src/main/resources/templates/transformForm.html +++ b/alfresco-docker-imagemagick/src/main/resources/templates/transformForm.html @@ -8,6 +8,7 @@
file *
targetExtension *
timeout
+
testDelay
startPage
endPage
diff --git a/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickControllerTest.java b/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickControllerTest.java new file mode 100644 index 00000000..477165da --- /dev/null +++ b/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickControllerTest.java @@ -0,0 +1,116 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transformer; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.io.IOException; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Test the ImageMagickController without a server. + * Super class includes tests for the AbstractTransformerController. + */ +@RunWith(SpringRunner.class) +@WebMvcTest(ImageMagickController.class) +public class ImageMagickControllerTest extends AbstractTransformerControllerTest +{ + @SpyBean + private ImageMagickController controller; + + @Before + public void before() throws IOException + { + super.mockTransformCommand(controller, "jpg", "png", "image/jpg"); + } + + @Test + public void cropGravityGoodTest() throws Exception + { + for (String value: new String[] {"North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West", "NorthWest", "Center"}) + { + expectedOptions = "-gravity "+value+" +repage"; + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", targetExtension) + .param("cropGravity", value)) + .andExpect(status().is(200)) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + } + } + + @Test + public void cropGravityBadTest() throws Exception + { + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", targetExtension) + .param("cropGravity", "badValue")) + .andExpect(status().is(400)); + } + + @Test + public void optionsTest() throws Exception + { + expectedOptions = "-alpha remove -gravity SouthEast -crop 123x456%+90+12 +repage -thumbnail 321x654%!"; + expectedSourceSuffix = "[2-3]"; + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", targetExtension) + + .param("startPage", "2") + .param("endPage", "3") + + .param("alphaRemove", "true") + .param("autoOrient", "false") + + .param("cropGravity", "SouthEast") + .param("cropWidth", "123") + .param("cropHeight", "456") + .param("cropPercentage", "true") + .param("cropXOffset", "90") + .param("cropYOffset", "12") + + .param("thumbnail", "true") + .param("resizeWidth", "321") + .param("resizeHeight", "654") + .param("resizePercentage", "true") + .param("allowEnlargement", "true") + .param("maintainAspectRatio", "true") + ) + .andExpect(status().is(200)) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + } +} diff --git a/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickHttpRequestTest.java b/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickHttpRequestTest.java new file mode 100644 index 00000000..16d588fa --- /dev/null +++ b/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickHttpRequestTest.java @@ -0,0 +1,51 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transformer; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Tests AlfrescoPdfRendererHttpRequestTest with a server test harness. + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class ImageMagickHttpRequestTest extends AbstractHttpRequestTest +{ + @Override + protected String getTransformerName() + { + return "ImageMagick"; + } + + @Override + protected String getSourceExtension() + { + return "jpg"; + }; +} diff --git a/alfresco-docker-imagemagick/src/test/resources/quick.jpg b/alfresco-docker-imagemagick/src/test/resources/quick.jpg new file mode 100644 index 00000000..08473b8e Binary files /dev/null and b/alfresco-docker-imagemagick/src/test/resources/quick.jpg differ diff --git a/alfresco-docker-imagemagick/src/test/resources/quick.png b/alfresco-docker-imagemagick/src/test/resources/quick.png new file mode 100644 index 00000000..8f1f89b8 Binary files /dev/null and b/alfresco-docker-imagemagick/src/test/resources/quick.png differ diff --git a/alfresco-docker-libreoffice/pom.xml b/alfresco-docker-libreoffice/pom.xml index 8365a66b..7fbe0f50 100644 --- a/alfresco-docker-libreoffice/pom.xml +++ b/alfresco-docker-libreoffice/pom.xml @@ -4,8 +4,6 @@ Alfresco Docker LibreOffice jar - 0.9-SNAPSHOT - org.alfresco alfresco-docker-transformers @@ -60,6 +58,14 @@ pdfbox ${dependency.pdfbox.version} + + org.alfresco + alfresco-transformer-base + ${project.version} + tests + test-jar + test + diff --git a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/JodConverterSharedInstance.java b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/JodConverterSharedInstance.java index b87c707f..2b9c1023 100644 --- a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/JodConverterSharedInstance.java +++ b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/JodConverterSharedInstance.java @@ -291,7 +291,7 @@ public class JodConverterSharedInstance implements InitializingBean, DisposableB * (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ - public void afterPropertiesSet() throws Exception + public void afterPropertiesSet() { // isAvailable defaults to false afterPropertiesSet. It only becomes true on successful completion of this method. this.isAvailable = false; diff --git a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/LibreOfficeController.java b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/LibreOfficeController.java index 5378a56a..304a9d99 100644 --- a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/LibreOfficeController.java +++ b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/LibreOfficeController.java @@ -71,16 +71,17 @@ public class LibreOfficeController extends AbstractTransformerController logEnterpriseLicenseMessage(); logger.info("This transformer uses LibreOffice from The Document Foundation. See the license at https://www.libreoffice.org/download/license/ or in /libreoffice.txt"); logger.info("-------------------------------------------------------------------------------------------------------------------------------------------------------"); - setJodConverter(createJodConverter()); } - private static JodConverter createJodConverter() throws Exception + private static JodConverter createJodConverter(Long taskExecutionTimeout) { + String timeout = taskExecutionTimeout <= 0 ? "120000" : taskExecutionTimeout.toString(); + JodConverterSharedInstance jodconverter = new JodConverterSharedInstance(); jodconverter.setOfficeHome(OFFICE_HOME); // jodconverter.officeHome jodconverter.setMaxTasksPerProcess("200"); // jodconverter.maxTasksPerProcess - jodconverter.setTaskExecutionTimeout("120000"); // jodconverter.maxTasksPerProcess + jodconverter.setTaskExecutionTimeout(timeout); // jodconverter.maxTaskExecutionTimeout jodconverter.setTaskQueueTimeout("30000"); // jodconverter.taskQueueTimeout jodconverter.setConnectTimeout("28000"); // jodconverter.connectTimeout jodconverter.setPortNumbers("8100"); // jodconverter.portNumbers @@ -96,6 +97,19 @@ public class LibreOfficeController extends AbstractTransformerController this.jodconverter = jodconverter; } + /** + * Jodconverter timeouts are per OfficeManager, so we would need multiple OfficeManagers if we + * have different timeouts. Alfresco only has one. So we delay building it until the first request. + * This was not done previously. + */ + private synchronized void setJodConverterOnFirstRequest(Long timeout) + { + if (jodconverter == null) + { + setJodConverter(createJodConverter(timeout)); + } + } + @Override protected String getTransformerName() { @@ -118,29 +132,30 @@ public class LibreOfficeController extends AbstractTransformerController public ResponseEntity transform(HttpServletRequest request, @RequestParam("file") MultipartFile sourceMultipartFile, @RequestParam("targetExtension") String targetExtension, - @RequestParam(value = "timeout", required = false) Long timeout) + @RequestParam(value = "timeout", required = false) Long timeout, + @RequestParam(value = "testDelay", required = false) Long testDelay) { String targetFilename = createTargetFileName(sourceMultipartFile, targetExtension); File sourceFile = createSourceFile(request, sourceMultipartFile); File targetFile = createTargetFile(request, targetFilename); // Both files are deleted by TransformInterceptor.afterCompletion - executeTransformCommand(sourceFile, targetFile); + executeTransformCommand(sourceFile, targetFile, timeout); - return createAttachment(targetFilename, targetFile); + return createAttachment(targetFilename, targetFile, testDelay); } - protected void executeTransformCommand(File sourceFile, File targetFile) + protected void executeTransformCommand(File sourceFile, File targetFile, Long timeout) { + timeout = timeout != null && timeout > 0 ? timeout : 0; + try { - OfficeManager officeManager = jodconverter.getOfficeManager(); - OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager); - converter.convert(sourceFile, targetFile); + convert(sourceFile, targetFile, timeout); } catch (OfficeException e) { - throw new TransformException(500, "LibreOffice server conversion failed: \n"+ + throw new TransformException(400, "LibreOffice server conversion failed: \n"+ " from file: " + sourceFile + "\n" + " to file: " + targetFile, e); @@ -169,6 +184,14 @@ public class LibreOfficeController extends AbstractTransformerController } } + void convert(File sourceFile, File targetFile, long timeout) + { + setJodConverterOnFirstRequest(timeout); + OfficeManager officeManager = jodconverter.getOfficeManager(); + OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager); + converter.convert(sourceFile, targetFile); + } + /** * This method produces an empty PDF file at the specified File location. * Apache's PDFBox is used to create the PDF file. diff --git a/alfresco-docker-libreoffice/src/main/resources/templates/transformForm.html b/alfresco-docker-libreoffice/src/main/resources/templates/transformForm.html index 40667bf7..82995888 100644 --- a/alfresco-docker-libreoffice/src/main/resources/templates/transformForm.html +++ b/alfresco-docker-libreoffice/src/main/resources/templates/transformForm.html @@ -8,6 +8,7 @@
file *
targetExtension *
timeout
+
testDelay
diff --git a/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeControllerTest.java b/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeControllerTest.java new file mode 100644 index 00000000..b7bc2439 --- /dev/null +++ b/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeControllerTest.java @@ -0,0 +1,130 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transformer; + +import org.artofsolving.jodconverter.office.OfficeException; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.stubbing.Answer; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.util.Arrays; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Test the LibreOfficeController without a server. + * Super class includes tests for the AbstractTransformerController. + */ +@RunWith(SpringRunner.class) +@WebMvcTest(LibreOfficeControllerTest.class) +public class LibreOfficeControllerTest extends AbstractTransformerControllerTest +{ + @SpyBean + private LibreOfficeController controller; + + @Before + public void before() throws IOException + { + sourceExtension = "doc"; + targetExtension = "pdf"; + sourceMimetype = "application/msword"; + + // The following is based on super.mockTransformCommand(...) + // This is because LibreOffice used JodConverter rather than a RuntimeExec + + expectedSourceFileBytes = Files.readAllBytes(getTestFile("quick."+sourceExtension, true).toPath()); + expectedTargetFileBytes = Files.readAllBytes(getTestFile("quick."+targetExtension, true).toPath()); + sourceFile = new MockMultipartFile("file", "quick."+sourceExtension, sourceMimetype, expectedSourceFileBytes); + + doAnswer((Answer) invocation -> + { + File sourceFile = invocation.getArgumentAt(0, File.class); + File targetFile = invocation.getArgumentAt(1, File.class); + + assertNotNull(sourceFile); + assertNotNull(targetFile); + + Long actualTimeout = invocation.getArgumentAt(2, Long.class); + assertNotNull(actualTimeout); + if (expectedTimeout != null) + { + assertEquals("expectedTimeout", expectedTimeout, actualTimeout); + } + + // Copy a test file into the target file location if it exists + String actualTarget = targetFile.getAbsolutePath(); + int i = actualTarget.lastIndexOf('_'); + if (i >= 0) + { + String testFilename = actualTarget.substring(i+1); + File testFile = getTestFile(testFilename, false); + if (testFile != null) + { + FileChannel source = new FileInputStream(testFile).getChannel(); + FileChannel target = new FileOutputStream(targetFile).getChannel(); + target.transferFrom(source, 0, source.size()); + } + } + + // Check the supplied source file has not been changed. + byte[] actualSourceFileBytes = Files.readAllBytes(sourceFile.toPath()); + assertTrue("Source file is not the same", Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes)); + + return null; + }).when(controller).convert(any(), any(), anyLong()); + } + + @Test + @Override + public void badExitCodeTest() throws Exception + { + doThrow(OfficeException.class).when(controller).convert(any(), any(), anyLong()); + + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", "xxx")) + .andExpect(status().is(400)) + .andExpect(status().reason(containsString("LibreOffice - LibreOffice server conversion failed:"))); + } +} diff --git a/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeHttpRequestTest.java b/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeHttpRequestTest.java new file mode 100644 index 00000000..b4a898fd --- /dev/null +++ b/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeHttpRequestTest.java @@ -0,0 +1,50 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transformer; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Tests AlfrescoPdfRendererHttpRequestTest with a server test harness. + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class LibreOfficeHttpRequestTest extends AbstractHttpRequestTest +{ + @Override + protected String getTransformerName() + { + return "LibreOffice"; + } + + @Override + protected String getSourceExtension() + { + return "doc"; + }; +} \ No newline at end of file diff --git a/alfresco-docker-libreoffice/src/test/resources/quick.doc b/alfresco-docker-libreoffice/src/test/resources/quick.doc new file mode 100644 index 00000000..eb307fb2 Binary files /dev/null and b/alfresco-docker-libreoffice/src/test/resources/quick.doc differ diff --git a/alfresco-docker-libreoffice/src/test/resources/quick.pdf b/alfresco-docker-libreoffice/src/test/resources/quick.pdf new file mode 100644 index 00000000..a1779afd Binary files /dev/null and b/alfresco-docker-libreoffice/src/test/resources/quick.pdf differ diff --git a/alfresco-transformer-base/pom.xml b/alfresco-transformer-base/pom.xml index 6ac34611..20ecb735 100644 --- a/alfresco-transformer-base/pom.xml +++ b/alfresco-transformer-base/pom.xml @@ -41,4 +41,20 @@ + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.0 + + + + test-jar + + + + + + diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/AbstractTransformerController.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/AbstractTransformerController.java index 8b0dfef0..cf64cf81 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/AbstractTransformerController.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/AbstractTransformerController.java @@ -241,10 +241,10 @@ public abstract class AbstractTransformerController if (sourceFilename != null && !sourceFilename.isEmpty()) { String ext = StringUtils.getFilenameExtension(sourceFilename); - if (ext != null && !ext.isEmpty()) - { - targetFilename =sourceFilename.substring(0, sourceFilename.length()-ext.length()-1)+'.'+targetExtension; - } + targetFilename = (ext != null && !ext.isEmpty() + ? sourceFilename.substring(0, sourceFilename.length()-ext.length()-1) + : sourceFilename)+ + '.'+targetExtension; } return targetFilename; } @@ -330,7 +330,6 @@ public abstract class AbstractTransformerController else { throw new TransformException(500, "Could not read the target file: " + file.getPath()); - } } catch (MalformedURLException e) @@ -339,14 +338,14 @@ public abstract class AbstractTransformerController } } - protected void executeTransformCommand(Map properties, File targetFile, Long timeout) + public void executeTransformCommand(Map properties, File targetFile, Long timeout) { - long timeoutMs = timeout != null && timeout > 0 ? timeout : 0; - RuntimeExec.ExecutionResult result = transformCommand.execute(properties, timeoutMs); + timeout = timeout != null && timeout > 0 ? timeout : 0; + RuntimeExec.ExecutionResult result = transformCommand.execute(properties, timeout); if (result.getExitValue() != 0 && result.getStdErr() != null && result.getStdErr().length() > 0) { - throw new TransformException(400, "Transformer exit code was not 0: \n" + result); + throw new TransformException(400, "Transformer exit code was not 0: \n" + result.getStdErr()); } if (!targetFile.exists() || targetFile.length() == 0) @@ -355,7 +354,7 @@ public abstract class AbstractTransformerController } } - protected ResponseEntity createAttachment(String targetFilename, File targetFile) + protected ResponseEntity createAttachment(String targetFilename, File targetFile, Long testDelay) { try { @@ -365,6 +364,7 @@ public abstract class AbstractTransformerController "attachment; filename*= UTF-8''" + targetFilename).body(targetResource); LogEntry.setTargetSize(targetFile.length()); LogEntry.setStatusCodeAndMessage(200, "Success"); + LogEntry.addDelay(testDelay); return body; } catch (UnsupportedEncodingException e) diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/LogEntry.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/LogEntry.java index d8600320..c520ecca 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/LogEntry.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/LogEntry.java @@ -67,6 +67,7 @@ public class LogEntry private long durationStreamIn; private long durationTransform; private long durationStreamOut; + private long durationDelay; private String source; private long sourceSize; @@ -152,10 +153,40 @@ public class LogEntry logEntry.durationTransform = System.currentTimeMillis() - logEntry.start - logEntry.durationStreamIn; } + // In order to test connection timeouts, a testDelay may be added as a request parameter. + // This method waits for this period to end. It is in this class as all the times are recorded here. + public static void addDelay(Long testDelay) + { + if (testDelay != null && testDelay > 0) + { + currentLogEntry.get().addDelayInternal(testDelay); + } + } + + private void addDelayInternal(Long testDelay) + { + durationDelay = testDelay - System.currentTimeMillis() + start; + if (durationDelay > 0) + { + try + { + Thread.sleep(durationDelay); + } + catch (InterruptedException ignore) + { + Thread.currentThread().interrupt(); + } + } + else + { + durationDelay = 0; + } + } + public static void complete() { LogEntry logEntry = currentLogEntry.get(); - logEntry.durationStreamOut = System.currentTimeMillis() - logEntry.start - logEntry.durationStreamIn - logEntry.durationTransform; + logEntry.durationStreamOut = System.currentTimeMillis() - logEntry.start - logEntry.durationStreamIn - logEntry.durationTransform - logEntry.durationDelay; currentLogEntry.remove(); if (AbstractTransformerController.logger != null && AbstractTransformerController.logger.isDebugEnabled()) @@ -181,23 +212,11 @@ public class LogEntry public String getDuration() { - return time(durationStreamIn + durationTransform + durationStreamOut)+" ("+ - time(durationStreamIn)+' '+time(durationTransform)+' '+time(durationStreamOut)+")"; - } - - public long getDurationStreamIn() - { - return durationStreamIn; - } - - public long getDurationTransform() - { - return durationTransform; - } - - public long getDurationStreamOut() - { - return durationStreamOut; + return time(durationStreamIn + durationTransform + durationDelay + durationStreamOut)+" ("+ + time(durationStreamIn)+' '+ + time(durationTransform)+' '+ + (durationDelay > 0 ? time(durationDelay)+' ' : "")+ + time(durationStreamOut)+")"; } public String getSource() diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/TransformException.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/TransformException.java index e3a67172..0f6b9e00 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/TransformException.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/base/TransformException.java @@ -38,6 +38,7 @@ public class TransformException extends RuntimeException public TransformException(int statusCode, String message, Throwable cause) { super(message, cause); + this.statusCode = statusCode; } public int getStatusCode() diff --git a/alfresco-transformer-base/src/main/resources/templates/error.html b/alfresco-transformer-base/src/main/resources/templates/error.html index b6cd4be7..54b0facd 100644 --- a/alfresco-transformer-base/src/main/resources/templates/error.html +++ b/alfresco-transformer-base/src/main/resources/templates/error.html @@ -2,8 +2,13 @@
-

-

+
+

Error Page

+
+
+

+

+

diff --git a/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractHttpRequestTest.java b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractHttpRequestTest.java new file mode 100644 index 00000000..f45fcbe1 --- /dev/null +++ b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractHttpRequestTest.java @@ -0,0 +1,134 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transformer; + +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.springframework.test.util.AssertionErrors.assertTrue; + +/** + * Super class for testing controllers with a server. Includes tests for the AbstractTransformerController itself. + * Note: Currently uses json rather than HTML as json is returned by this spring boot test harness. + */ +public abstract class AbstractHttpRequestTest +{ + @LocalServerPort + private int port; + + @Autowired + private TestRestTemplate restTemplate; + + protected abstract String getTransformerName(); + + protected abstract String getSourceExtension(); + + @Test + public void testPageExists() throws Exception + { + String result = restTemplate.getForObject("http://localhost:" + port + "/", String.class); + + String title = getTransformerName() + ' ' + "Test Transformation"; + assertTrue("\"" + title + "\" should be part of the page title", result.contains(title)); + } + + @Test + public void logPageExists() throws Exception + { + String result = restTemplate.getForObject("http://localhost:" + port + "/log", String.class); + + String title = getTransformerName() + ' ' + "Log"; + assertTrue("\"" + title + "\" should be part of the page title", result.contains(title)); + } + + @Test + public void errorPageExists() throws Exception + { + String result = restTemplate.getForObject("http://localhost:" + port + "/error", String.class); + + String title = getTransformerName() + ' ' + "Error Page"; + assertTrue("\"" + title + "\" should be part of the page title", result.contains("Error Page")); + } + + @Test + public void noFileError() throws Exception + { + // Transformer name is not part of the title as this is checked by another handler + assertTransformError(false, + "Required request part 'file' is not present"); + } + + @Test + public void noTargetExtensionError() throws Exception + { + assertMissingParameter("targetExtension"); + } + + protected void assertMissingParameter(String name) throws IOException + { + assertTransformError(true, + getTransformerName() + " - Request parameter " + name + " is missing"); + } + + protected void assertTransformError(boolean addFile, String errorMessage) throws IOException + { + LinkedMultiValueMap parameters = new LinkedMultiValueMap(); + if (addFile) + { + parameters.add("file", new org.springframework.core.io.ClassPathResource("quick."+getSourceExtension())); + } + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + HttpEntity> entity = new HttpEntity>(parameters, headers); + ResponseEntity response = restTemplate.exchange("/transform", HttpMethod.POST, entity, String.class, ""); + assertEquals(errorMessage, getErrorMessage(response.getBody())); + } + + // Strip out just the error message from the returned json content body + // Had been expecting the Error page to be returned, but we end up with the json in this test harness. + // Is correct if run manually, so not worrying too much about this. + private String getErrorMessage(String content) throws IOException + { + String message = ""; + int i = content.indexOf("\"message\":\""); + if (i != -1) + { + int j = content.indexOf("\",\"path\":", i); + if (j != -1) + { + message = content.substring(i+11, j); + } + } + return message; + } +} \ No newline at end of file diff --git a/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java new file mode 100644 index 00000000..40dfcd96 --- /dev/null +++ b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java @@ -0,0 +1,292 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transformer; + +import org.alfresco.transformer.base.AbstractTransformerController; +import org.alfresco.util.exec.RuntimeExec; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.Map; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.*; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Super class for testing controllers without a server. Includes tests for the AbstractTransformerController itself. + */ +public abstract class AbstractTransformerControllerTest +{ + @Autowired + protected MockMvc mockMvc; + + @Mock + private RuntimeExec mockTransformCommand; + + @Mock + private RuntimeExec mockCheckCommand; + + @Mock + private RuntimeExec.ExecutionResult mockExecutionResult; + + protected String sourceExtension; + protected String targetExtension; + protected String sourceMimetype; + + protected MockMultipartFile sourceFile; + protected String expectedOptions; + protected String expectedSourceSuffix; + protected Long expectedTimeout = 0L; + protected byte[] expectedSourceFileBytes; + protected byte[] expectedTargetFileBytes; + + private AbstractTransformerController controller; + + // Called by sub class + public void mockTransformCommand(AbstractTransformerController controller, String sourceExtension, String targetExtension, String sourceMimetype) throws IOException + { + this.controller = controller; + this.sourceExtension = sourceExtension; + this.targetExtension = targetExtension; + this.sourceMimetype = sourceMimetype; + + expectedOptions = null; + expectedSourceSuffix = null; + expectedSourceFileBytes = Files.readAllBytes(getTestFile("quick."+sourceExtension, true).toPath()); + expectedTargetFileBytes = Files.readAllBytes(getTestFile("quick."+targetExtension, true).toPath()); + sourceFile = new MockMultipartFile("file", "quick."+sourceExtension, sourceMimetype, expectedSourceFileBytes); + + controller.setTransformCommand(mockTransformCommand); + controller.setCheckCommand(mockCheckCommand); + + when(mockTransformCommand.execute(anyObject(), anyLong())).thenAnswer(new Answer() + { + public RuntimeExec.ExecutionResult answer(InvocationOnMock invocation) throws Throwable + { + Map actualProperties = invocation.getArgumentAt(0, Map.class); + assertEquals("There should be 3 properties", 3, actualProperties.size()); + + String actualOptions = actualProperties.get("options"); + String actualSource = actualProperties.get("source"); + String actualTarget = actualProperties.get("target"); + + assertNotNull(actualSource); + assertNotNull(actualTarget); + if (expectedSourceSuffix != null) + { + assertTrue("The source file \""+actualSource+"\" should have ended in \""+expectedSourceSuffix+"\"", actualSource.endsWith(expectedSourceSuffix)); + actualSource = actualSource.substring(0, actualSource.length()-expectedSourceSuffix.length()); + } + + assertNotNull(actualOptions); + if (expectedOptions != null) + { + assertEquals("expectedOptions", expectedOptions, actualOptions); + } + + Long actualTimeout = invocation.getArgumentAt(1, Long.class); + assertNotNull(actualTimeout); + if (expectedTimeout != null) + { + assertEquals("expectedTimeout", expectedTimeout, actualTimeout); + } + + // Copy a test file into the target file location if it exists + int i = actualTarget.lastIndexOf('_'); + if (i >= 0) + { + String testFilename = actualTarget.substring(i+1); + File testFile = getTestFile(testFilename, false); + if (testFile != null) + { + File targetFile = new File(actualTarget); + FileChannel source = new FileInputStream(testFile).getChannel(); + FileChannel target = new FileOutputStream(targetFile).getChannel(); + target.transferFrom(source, 0, source.size()); + } + } + + // Check the supplied source file has not been changed. + byte[] actualSourceFileBytes = Files.readAllBytes(new File(actualSource).toPath()); + assertTrue("Source file is not the same", Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes)); + + return mockExecutionResult; + } + }); + + when(mockExecutionResult.getExitValue()).thenReturn(0); + when(mockExecutionResult.getStdErr()).thenReturn("STDERROR"); + when(mockExecutionResult.getStdOut()).thenReturn("STDOUT"); + } + + protected File getTestFile(String testFilename, boolean required) throws IOException + { + ClassLoader classLoader = getClass().getClassLoader(); + URL testFileUrl = classLoader.getResource(testFilename); + if (required && testFileUrl == null) + { + throw new IOException("The test file "+testFilename+" does not exist in the resources directory"); + } + return testFileUrl == null ? null : new File(testFileUrl.getFile()); + } + + @Test + public void simpleTransformTest() throws Exception + { + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", targetExtension)) + .andExpect(status().is(200)) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + } + + @Test + public void testDelayTest() throws Exception + { + long start = System.currentTimeMillis(); + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", targetExtension) + .param("testDelay", "400")) + .andExpect(status().is(200)) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + long ms = System.currentTimeMillis()- start; + System.out.println("Transform incluing test delay was "+ms); + assertTrue("Delay sending the result back was too small "+ms, ms >= 400); + assertTrue("Delay sending the result back was too big "+ms, ms <= 500); + } + + @Test + public void noTargetFileTest() throws Exception + { + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", "xxx")) + .andExpect(status().is(500)); + } + + @Test + public void badExitCodeTest() throws Exception + { + when(mockExecutionResult.getExitValue()).thenReturn(1); + + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", "xxx")) + .andExpect(status().is(400)) + .andExpect(status().reason(containsString("Transformer exit code was not 0: \nSTDERR"))); + } + + @Test + // Looks dangerous but is okay as we only use the final filename + public void dotDotSourceFilenameTest() throws Exception + { + sourceFile = new MockMultipartFile("file", "../quick."+sourceExtension, sourceMimetype, expectedSourceFileBytes); + + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", targetExtension)) + .andExpect(status().is(200)) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + } + + @Test + // Is okay, as the target filename is built up from the whole source filename and the targetExtenstion + public void noExtensionSourceFilenameTest() throws Exception + { + sourceFile = new MockMultipartFile("file", "../quick", sourceMimetype, expectedSourceFileBytes); + + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", targetExtension)) + .andExpect(status().is(200)) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + } + + @Test + // Invalid file name that ends in / + public void badSourceFilenameTest() throws Exception + { + sourceFile = new MockMultipartFile("file", "abc/", sourceMimetype, expectedSourceFileBytes); + + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", targetExtension)) + .andExpect(status().is(400)) + .andExpect(status().reason(containsString("The source filename was not supplied"))); + } + + @Test + public void blankSourceFilenameTest() throws Exception + { + sourceFile = new MockMultipartFile("file", "", sourceMimetype, expectedSourceFileBytes); + + mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform") + .file(sourceFile) + .param("targetExtension", targetExtension)) + .andExpect(status().is(400)) + .andExpect(status().reason(containsString("The source filename was not supplied"))); + } + +// @Test +// // Not a real test, but helpful for trying out the duration times in log code. +// public void testTimes() throws InterruptedException +// { +// LogEntry.start(); +// Thread.sleep(50); +// LogEntry.setSource("test File", 1234); +// Thread.sleep(200); +// LogEntry.setStatusCodeAndMessage(200, "Success"); +// LogEntry.addDelay(2000L); +// for (LogEntry logEntry: LogEntry.getLog()) +// { +// String str = logEntry.getDuration(); +// System.out.println(str); +// } +// } +} diff --git a/alfresco-transformer-base/src/test/java/org/org/alfresco/transformer/AbstractTransformerControllerTest b/alfresco-transformer-base/src/test/java/org/org/alfresco/transformer/AbstractTransformerControllerTest new file mode 100644 index 00000000..e69de29b diff --git a/pom.xml b/pom.xml index 32f033a5..4b4b40cd 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,6 @@ org.alfresco alfresco-docker-transformers - 0.9-SNAPSHOT pom