diff --git a/app/common/src/test/java/stirling/software/common/annotations/AutoJobPostMappingIntegrationTest.java b/app/common/src/test/java/stirling/software/common/annotations/AutoJobPostMappingIntegrationTest.java index dd7a0f79b..0b676b9cb 100644 --- a/app/common/src/test/java/stirling/software/common/annotations/AutoJobPostMappingIntegrationTest.java +++ b/app/common/src/test/java/stirling/software/common/annotations/AutoJobPostMappingIntegrationTest.java @@ -31,8 +31,6 @@ import stirling.software.common.aop.AutoJobAspect; import stirling.software.common.model.api.PDFFile; import stirling.software.common.service.FileStorage; import stirling.software.common.service.JobExecutorService; -import stirling.software.common.service.JobQueue; -import stirling.software.common.service.ResourceMonitor; @ExtendWith(MockitoExtension.class) class AutoJobPostMappingIntegrationTest { @@ -45,10 +43,6 @@ class AutoJobPostMappingIntegrationTest { @Mock private FileStorage fileStorage; - @Mock private ResourceMonitor resourceMonitor; - - @Mock private JobQueue jobQueue; - @BeforeEach void setUp() { autoJobAspect = new AutoJobAspect(jobExecutorService, request, fileStorage); @@ -73,7 +67,7 @@ class AutoJobPostMappingIntegrationTest { // Given PDFFile pdfFile = new PDFFile(); pdfFile.setFileId("test-file-id"); - Object[] args = new Object[] {pdfFile}; + Object[] args = {pdfFile}; when(joinPoint.getArgs()).thenReturn(args); when(request.getParameter("async")).thenReturn("true"); @@ -153,7 +147,7 @@ class AutoJobPostMappingIntegrationTest { // Given PDFFile pdfFile = new PDFFile(); pdfFile.setFileInput(mock(MultipartFile.class)); - Object[] args = new Object[] {pdfFile}; + Object[] args = {pdfFile}; when(joinPoint.getArgs()).thenReturn(args); when(request.getParameter("async")).thenReturn("true"); diff --git a/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesDynamicYamlPropertySourceTest.java b/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesDynamicYamlPropertySourceTest.java index 71d3997be..f8d4cc345 100644 --- a/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesDynamicYamlPropertySourceTest.java +++ b/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesDynamicYamlPropertySourceTest.java @@ -20,11 +20,13 @@ class ApplicationPropertiesDynamicYamlPropertySourceTest { void loads_yaml_into_environment() throws Exception { // YAML-Config in Temp-Datei schreiben String yaml = - "" - + "ui:\n" - + " appName: \"My App\"\n" - + "system:\n" - + " enableAnalytics: true\n"; + """ + \ + ui: + appName: "My App" + system: + enableAnalytics: true + """; Path tmp = Files.createTempFile("spdf-settings-", ".yml"); Files.writeString(tmp, yaml); @@ -44,7 +46,7 @@ class ApplicationPropertiesDynamicYamlPropertySourceTest { } @Test - void throws_when_settings_file_missing() throws Exception { + void throws_when_settings_file_missing() { String missing = "/path/does/not/exist/spdf.yml"; try (MockedStatic mocked = Mockito.mockStatic(InstallationPathConfig.class)) { diff --git a/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesLogicTest.java b/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesLogicTest.java index 3f06ce14f..e5c89fc26 100644 --- a/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesLogicTest.java +++ b/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesLogicTest.java @@ -232,7 +232,7 @@ class ApplicationPropertiesLogicTest { Collection nullColl = null; Collection empty = List.of(); - assertFalse(oauth2.isValid(nullColl, "scopes")); + assertFalse(oauth2.isValid((Collection) null, "scopes")); assertFalse(oauth2.isValid(empty, "scopes")); } diff --git a/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesSaml2HttpTest.java b/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesSaml2HttpTest.java index 0e3545e8b..de25c20f8 100644 --- a/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesSaml2HttpTest.java +++ b/app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesSaml2HttpTest.java @@ -61,7 +61,7 @@ class ApplicationPropertiesSaml2HttpTest { Resource r = s.getSpCert(); assertNotNull(r); - assertTrue(r instanceof FileSystemResource, "Expected FileSystemResource for FS path"); + assertInstanceOf(FileSystemResource.class, r, "Expected FileSystemResource for FS path"); assertTrue(r.exists(), "Temp file should exist"); } @@ -75,7 +75,7 @@ class ApplicationPropertiesSaml2HttpTest { Resource r = s.getIdpCert(); assertNotNull(r); - assertTrue(r instanceof FileSystemResource, "Expected FileSystemResource for FS path"); + assertInstanceOf(FileSystemResource.class, r, "Expected FileSystemResource for FS path"); assertFalse(r.exists(), "Resource should not exist for missing file"); } } diff --git a/app/common/src/test/java/stirling/software/common/model/InputStreamTemplateResourceTest.java b/app/common/src/test/java/stirling/software/common/model/InputStreamTemplateResourceTest.java index 2ceabd2e0..0c9ecd08d 100644 --- a/app/common/src/test/java/stirling/software/common/model/InputStreamTemplateResourceTest.java +++ b/app/common/src/test/java/stirling/software/common/model/InputStreamTemplateResourceTest.java @@ -7,6 +7,7 @@ import java.io.InputStream; import java.io.Reader; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import org.junit.jupiter.api.Test; @@ -47,7 +48,7 @@ public class InputStreamTemplateResourceTest { @Test void readerReturnsCorrectContent() throws Exception { String content = "Hello, world!"; - InputStream is = new ByteArrayInputStream(content.getBytes("UTF-8")); + InputStream is = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)); InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8"); try (Reader reader = resource.reader()) { diff --git a/app/common/src/test/java/stirling/software/common/service/CustomPDFDocumentFactoryTest.java b/app/common/src/test/java/stirling/software/common/service/CustomPDFDocumentFactoryTest.java index 34b62bf75..b54fdb923 100644 --- a/app/common/src/test/java/stirling/software/common/service/CustomPDFDocumentFactoryTest.java +++ b/app/common/src/test/java/stirling/software/common/service/CustomPDFDocumentFactoryTest.java @@ -41,58 +41,7 @@ class CustomPDFDocumentFactoryTest { } } - @ParameterizedTest - @CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"}) - void testStrategy_FileInput(int sizeMB, StrategyType expected) throws IOException { - File file = writeTempFile(inflatePdf(basePdfBytes, sizeMB)); - try (PDDocument doc = factory.load(file)) { - Assertions.assertEquals(expected, factory.lastStrategyUsed); - } - } - - @ParameterizedTest - @CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"}) - void testStrategy_ByteArray(int sizeMB, StrategyType expected) throws IOException { - byte[] inflated = inflatePdf(basePdfBytes, sizeMB); - try (PDDocument doc = factory.load(inflated)) { - Assertions.assertEquals(expected, factory.lastStrategyUsed); - } - } - - @ParameterizedTest - @CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"}) - void testStrategy_InputStream(int sizeMB, StrategyType expected) throws IOException { - byte[] inflated = inflatePdf(basePdfBytes, sizeMB); - try (PDDocument doc = factory.load(new ByteArrayInputStream(inflated))) { - Assertions.assertEquals(expected, factory.lastStrategyUsed); - } - } - - @ParameterizedTest - @CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"}) - void testStrategy_MultipartFile(int sizeMB, StrategyType expected) throws IOException { - byte[] inflated = inflatePdf(basePdfBytes, sizeMB); - MockMultipartFile multipart = - new MockMultipartFile("file", "doc.pdf", MediaType.APPLICATION_PDF_VALUE, inflated); - try (PDDocument doc = factory.load(multipart)) { - Assertions.assertEquals(expected, factory.lastStrategyUsed); - } - } - - @ParameterizedTest - @CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"}) - void testStrategy_PDFFile(int sizeMB, StrategyType expected) throws IOException { - byte[] inflated = inflatePdf(basePdfBytes, sizeMB); - MockMultipartFile multipart = - new MockMultipartFile("file", "doc.pdf", MediaType.APPLICATION_PDF_VALUE, inflated); - PDFFile pdfFile = new PDFFile(); - pdfFile.setFileInput(multipart); - try (PDDocument doc = factory.load(pdfFile)) { - Assertions.assertEquals(expected, factory.lastStrategyUsed); - } - } - - private byte[] inflatePdf(byte[] input, int sizeInMB) throws IOException { + private static byte[] inflatePdf(byte[] input, int sizeInMB) throws IOException { try (PDDocument doc = Loader.loadPDF(input)) { byte[] largeData = new byte[sizeInMB * 1024 * 1024]; Arrays.fill(largeData, (byte) 'A'); @@ -111,6 +60,46 @@ class CustomPDFDocumentFactoryTest { } } + private static File writeTempFile(byte[] content) throws IOException { + File file = Files.createTempFile("pdf-test-", ".pdf").toFile(); + Files.write(file.toPath(), content); + return file; + } + + @ParameterizedTest + @CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"}) + void testStrategy_FileInput(int sizeMB, StrategyType expected) throws IOException { + File file = writeTempFile(inflatePdf(basePdfBytes, sizeMB)); + factory.load(file); + Assertions.assertEquals(expected, factory.lastStrategyUsed); + } + + @ParameterizedTest + @CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"}) + void testStrategy_ByteArray(int sizeMB, StrategyType expected) throws IOException { + byte[] inflated = inflatePdf(basePdfBytes, sizeMB); + factory.load(inflated); + Assertions.assertEquals(expected, factory.lastStrategyUsed); + } + + @ParameterizedTest + @CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"}) + void testStrategy_InputStream(int sizeMB, StrategyType expected) throws IOException { + byte[] inflated = inflatePdf(basePdfBytes, sizeMB); + factory.load(new ByteArrayInputStream(inflated)); + Assertions.assertEquals(expected, factory.lastStrategyUsed); + } + + @ParameterizedTest + @CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"}) + void testStrategy_MultipartFile(int sizeMB, StrategyType expected) throws IOException { + byte[] inflated = inflatePdf(basePdfBytes, sizeMB); + MockMultipartFile multipart = + new MockMultipartFile("file", "doc.pdf", MediaType.APPLICATION_PDF_VALUE, inflated); + factory.load(multipart); + Assertions.assertEquals(expected, factory.lastStrategyUsed); + } + @Test void testLoadFromPath() throws IOException { File file = writeTempFile(inflatePdf(basePdfBytes, 5)); @@ -210,10 +199,16 @@ class CustomPDFDocumentFactoryTest { assertTrue(newBytes.length > 0); } - private File writeTempFile(byte[] content) throws IOException { - File file = Files.createTempFile("pdf-test-", ".pdf").toFile(); - Files.write(file.toPath(), content); - return file; + @ParameterizedTest + @CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"}) + void testStrategy_PDFFile(int sizeMB, StrategyType expected) throws IOException { + byte[] inflated = inflatePdf(basePdfBytes, sizeMB); + MockMultipartFile multipart = + new MockMultipartFile("file", "doc.pdf", MediaType.APPLICATION_PDF_VALUE, inflated); + PDFFile pdfFile = new PDFFile(); + pdfFile.setFileInput(multipart); + factory.load(pdfFile); + Assertions.assertEquals(expected, factory.lastStrategyUsed); } @BeforeEach diff --git a/app/common/src/test/java/stirling/software/common/service/JobExecutorServiceTest.java b/app/common/src/test/java/stirling/software/common/service/JobExecutorServiceTest.java index 630ac80bf..3b168552b 100644 --- a/app/common/src/test/java/stirling/software/common/service/JobExecutorServiceTest.java +++ b/app/common/src/test/java/stirling/software/common/service/JobExecutorServiceTest.java @@ -1,8 +1,6 @@ package stirling.software.common.service; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; @@ -63,7 +61,7 @@ class JobExecutorServiceTest { } @Test - void shouldRunSyncJobSuccessfully() throws Exception { + void shouldRunSyncJobSuccessfully() { // Given Supplier work = () -> "test-result"; @@ -79,7 +77,7 @@ class JobExecutorServiceTest { } @Test - void shouldRunAsyncJobSuccessfully() throws Exception { + void shouldRunAsyncJobSuccessfully() { // Given Supplier work = () -> "test-result"; @@ -88,7 +86,7 @@ class JobExecutorServiceTest { // Then assertEquals(HttpStatus.OK, response.getStatusCode()); - assertTrue(response.getBody() instanceof JobResponse); + assertInstanceOf(JobResponse.class, response.getBody()); JobResponse jobResponse = (JobResponse) response.getBody(); assertTrue(jobResponse.isAsync()); assertNotNull(jobResponse.getJobId()); @@ -113,6 +111,7 @@ class JobExecutorServiceTest { @SuppressWarnings("unchecked") Map errorMap = (Map) response.getBody(); + assertNotNull(errorMap); assertEquals("Job failed: Test error", errorMap.get("error")); } @@ -133,7 +132,7 @@ class JobExecutorServiceTest { // Then assertEquals(HttpStatus.OK, response.getStatusCode()); - assertTrue(response.getBody() instanceof JobResponse); + assertInstanceOf(JobResponse.class, response.getBody()); // Verify job was queued verify(jobQueue).queueJob(anyString(), eq(80), any(), eq(5000L)); @@ -186,7 +185,7 @@ class JobExecutorServiceTest { try { executeMethod.invoke(jobExecutorService, work, 1L); // Very short timeout } catch (Exception e) { - assertTrue(e.getCause() instanceof TimeoutException); + assertInstanceOf(TimeoutException.class, e.getCause()); } } } diff --git a/app/common/src/test/java/stirling/software/common/service/ResourceMonitorTest.java b/app/common/src/test/java/stirling/software/common/service/ResourceMonitorTest.java index 25a098764..f17730603 100644 --- a/app/common/src/test/java/stirling/software/common/service/ResourceMonitorTest.java +++ b/app/common/src/test/java/stirling/software/common/service/ResourceMonitorTest.java @@ -33,11 +33,11 @@ class ResourceMonitorTest { @Mock private MemoryMXBean memoryMXBean; @Spy - private AtomicReference currentStatus = + private final AtomicReference currentStatus = new AtomicReference<>(ResourceStatus.OK); @Spy - private AtomicReference latestMetrics = + private final AtomicReference latestMetrics = new AtomicReference<>(new ResourceMetrics()); @BeforeEach diff --git a/app/common/src/test/java/stirling/software/common/service/TaskManagerTest.java b/app/common/src/test/java/stirling/software/common/service/TaskManagerTest.java index 15aa46bc8..e0597f725 100644 --- a/app/common/src/test/java/stirling/software/common/service/TaskManagerTest.java +++ b/app/common/src/test/java/stirling/software/common/service/TaskManagerTest.java @@ -215,7 +215,7 @@ class TaskManagerTest { } @Test - void testCleanupOldJobs() throws Exception { + void testCleanupOldJobs() { // Arrange // 1. Create a recent completed job String recentJobId = "recent-job"; @@ -253,6 +253,7 @@ class TaskManagerTest { taskManager.createTask(activeJobId); // Verify all jobs are in the map + assertNotNull(jobResultsMap); assertTrue(jobResultsMap.containsKey(recentJobId)); assertTrue(jobResultsMap.containsKey(oldJobId)); assertTrue(jobResultsMap.containsKey(activeJobId)); @@ -268,7 +269,7 @@ class TaskManagerTest { } @Test - void testShutdown() throws Exception { + void testShutdown() { // This mainly tests that the shutdown method doesn't throw exceptions taskManager.shutdown(); diff --git a/app/common/src/test/java/stirling/software/common/service/TempFileCleanupServiceTest.java b/app/common/src/test/java/stirling/software/common/service/TempFileCleanupServiceTest.java index 286fe859f..fa448e9c7 100644 --- a/app/common/src/test/java/stirling/software/common/service/TempFileCleanupServiceTest.java +++ b/app/common/src/test/java/stirling/software/common/service/TempFileCleanupServiceTest.java @@ -219,9 +219,9 @@ public class TempFileCleanupServiceTest { }); // Act - set containerMode to false for this test - invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000); - invokeCleanupDirectoryStreaming(customTempDir, false, 0, 3600000); - invokeCleanupDirectoryStreaming(libreOfficeTempDir, false, 0, 3600000); + invokeCleanupDirectoryStreaming(systemTempDir, false, 3600000); + invokeCleanupDirectoryStreaming(customTempDir, false, 3600000); + invokeCleanupDirectoryStreaming(libreOfficeTempDir, false, 3600000); // Assert - Only old temp files and empty files should be deleted assertTrue(deletedFiles.contains(oldTempFile), "Old temp file should be deleted"); @@ -306,7 +306,7 @@ public class TempFileCleanupServiceTest { }); // Act - set containerMode to true and maxAgeMillis to 0 for container startup cleanup - invokeCleanupDirectoryStreaming(systemTempDir, true, 0, 0); + invokeCleanupDirectoryStreaming(systemTempDir, true, 0); // Assert - In container mode, both our temp files and system temp files should be // deleted @@ -379,7 +379,7 @@ public class TempFileCleanupServiceTest { }); // Act - invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000); + invokeCleanupDirectoryStreaming(systemTempDir, false, 3600000); // Assert assertTrue( @@ -462,7 +462,7 @@ public class TempFileCleanupServiceTest { }); // Act - invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000); + invokeCleanupDirectoryStreaming(systemTempDir, false, 3600000); // Debug - print what was deleted System.out.println("Deleted files: " + deletedFiles); @@ -479,8 +479,7 @@ public class TempFileCleanupServiceTest { /** Helper method to invoke the private cleanupDirectoryStreaming method using reflection */ private void invokeCleanupDirectoryStreaming( - Path directory, boolean containerMode, int depth, long maxAgeMillis) - throws IOException { + Path directory, boolean containerMode, long maxAgeMillis) { try { // Create a consumer that tracks deleted files AtomicInteger deleteCount = new AtomicInteger(0); @@ -503,7 +502,7 @@ public class TempFileCleanupServiceTest { cleanupService, directory, containerMode, - depth, + 0, maxAgeMillis, false, deleteCallback); diff --git a/app/common/src/test/java/stirling/software/common/util/CheckProgramInstallTest.java b/app/common/src/test/java/stirling/software/common/util/CheckProgramInstallTest.java index ae8132618..a994937af 100644 --- a/app/common/src/test/java/stirling/software/common/util/CheckProgramInstallTest.java +++ b/app/common/src/test/java/stirling/software/common/util/CheckProgramInstallTest.java @@ -49,7 +49,7 @@ class CheckProgramInstallTest { } /** Reset static fields in the CheckProgramInstall class using reflection */ - private void resetStaticFields() throws Exception { + private static void resetStaticFields() throws Exception { Field pythonAvailableCheckedField = CheckProgramInstall.class.getDeclaredField("pythonAvailableChecked"); pythonAvailableCheckedField.setAccessible(true); @@ -108,8 +108,7 @@ class CheckProgramInstallTest { } @Test - void testGetAvailablePythonCommand_WhenPythonReturnsNonZeroExitCode() - throws IOException, InterruptedException, Exception { + void testGetAvailablePythonCommand_WhenPythonReturnsNonZeroExitCode() throws Exception { // Arrange // Reset the static fields again to ensure clean state resetStaticFields(); diff --git a/app/common/src/test/java/stirling/software/common/util/ChecksumUtilsTest.java b/app/common/src/test/java/stirling/software/common/util/ChecksumUtilsTest.java index 0a5d20a33..774a24464 100644 --- a/app/common/src/test/java/stirling/software/common/util/ChecksumUtilsTest.java +++ b/app/common/src/test/java/stirling/software/common/util/ChecksumUtilsTest.java @@ -46,7 +46,7 @@ public class ChecksumUtilsTest { @Test void crc32_unsignedFormatting_highBitSet() throws Exception { // CRC32 of single zero byte (0x00) is 0xD202EF8D (>= 0x8000_0000) - byte[] data = new byte[] {0x00}; + byte[] data = {0x00}; // Hex (unsigned, 8 chars, lowercase) try (InputStream is = new ByteArrayInputStream(data)) { diff --git a/app/common/src/test/java/stirling/software/common/util/EmlToPdfTest.java b/app/common/src/test/java/stirling/software/common/util/EmlToPdfTest.java index 9385d260c..b121be6b6 100644 --- a/app/common/src/test/java/stirling/software/common/util/EmlToPdfTest.java +++ b/app/common/src/test/java/stirling/software/common/util/EmlToPdfTest.java @@ -765,7 +765,7 @@ class EmlToPdfTest { } // Helper methods - private String getTimestamp() { + private static String getTimestamp() { java.time.ZonedDateTime fixedDateTime = java.time.ZonedDateTime.of(2023, 1, 1, 12, 0, 0, 0, java.time.ZoneId.of("GMT")); return java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME.format(fixedDateTime); @@ -1039,13 +1039,13 @@ class EmlToPdfTest { } // Creates a basic EmlToPdfRequest with default settings - private EmlToPdfRequest createBasicRequest() { + private static EmlToPdfRequest createBasicRequest() { EmlToPdfRequest request = new EmlToPdfRequest(); request.setIncludeAttachments(false); return request; } - private EmlToPdfRequest createRequestWithAttachments() { + private static EmlToPdfRequest createRequestWithAttachments() { EmlToPdfRequest request = new EmlToPdfRequest(); request.setIncludeAttachments(true); request.setMaxAttachmentSizeMB(10); diff --git a/app/common/src/test/java/stirling/software/common/util/ImageProcessingUtilsTest.java b/app/common/src/test/java/stirling/software/common/util/ImageProcessingUtilsTest.java index 59c187662..8aa248a34 100644 --- a/app/common/src/test/java/stirling/software/common/util/ImageProcessingUtilsTest.java +++ b/app/common/src/test/java/stirling/software/common/util/ImageProcessingUtilsTest.java @@ -11,10 +11,18 @@ import org.junit.jupiter.api.Test; public class ImageProcessingUtilsTest { + private static void fillImageWithColor(BufferedImage image) { + for (int y = 0; y < image.getHeight(); y++) { + for (int x = 0; x < image.getWidth(); x++) { + image.setRGB(x, y, Color.RED.getRGB()); + } + } + } + @Test void testConvertColorTypeToGreyscale() { BufferedImage sourceImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); - fillImageWithColor(sourceImage, Color.RED); + fillImageWithColor(sourceImage); BufferedImage convertedImage = ImageProcessingUtils.convertColorType(sourceImage, "greyscale"); @@ -33,7 +41,7 @@ public class ImageProcessingUtilsTest { @Test void testConvertColorTypeToBlackWhite() { BufferedImage sourceImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); - fillImageWithColor(sourceImage, Color.RED); + fillImageWithColor(sourceImage); BufferedImage convertedImage = ImageProcessingUtils.convertColorType(sourceImage, "blackwhite"); @@ -51,7 +59,7 @@ public class ImageProcessingUtilsTest { @Test void testConvertColorTypeToFullColor() { BufferedImage sourceImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); - fillImageWithColor(sourceImage, Color.RED); + fillImageWithColor(sourceImage); BufferedImage convertedImage = ImageProcessingUtils.convertColorType(sourceImage, "fullcolor"); @@ -63,7 +71,7 @@ public class ImageProcessingUtilsTest { @Test void testConvertColorTypeInvalid() { BufferedImage sourceImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); - fillImageWithColor(sourceImage, Color.RED); + fillImageWithColor(sourceImage); BufferedImage convertedImage = ImageProcessingUtils.convertColorType(sourceImage, "invalidtype"); @@ -71,12 +79,4 @@ public class ImageProcessingUtilsTest { assertNotNull(convertedImage); assertEquals(sourceImage, convertedImage); } - - private void fillImageWithColor(BufferedImage image, Color color) { - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - image.setRGB(x, y, color.getRGB()); - } - } - } } diff --git a/app/common/src/test/java/stirling/software/common/util/PDFToFileTest.java b/app/common/src/test/java/stirling/software/common/util/PDFToFileTest.java index 2ebb58c0d..9aac6f907 100644 --- a/app/common/src/test/java/stirling/software/common/util/PDFToFileTest.java +++ b/app/common/src/test/java/stirling/software/common/util/PDFToFileTest.java @@ -329,12 +329,10 @@ class PDFToFileTest { boolean foundImage = false; while ((entry = zipStream.getNextEntry()) != null) { - if ("test.html".equals(entry.getName())) { - foundMainHtml = true; - } else if ("test_ind.html".equals(entry.getName())) { - foundIndexHtml = true; - } else if ("test_img.png".equals(entry.getName())) { - foundImage = true; + switch (entry.getName()) { + case "test.html" -> foundMainHtml = true; + case "test_ind.html" -> foundIndexHtml = true; + case "test_img.png" -> foundImage = true; } zipStream.closeEntry(); } @@ -382,6 +380,7 @@ class PDFToFileTest { } // Create output file + assertNotNull(outDir); Files.write( Path.of(outDir, "document.docx"), "Fake DOCX content".getBytes()); @@ -442,6 +441,7 @@ class PDFToFileTest { // Create multiple output files (simulating a presentation with // multiple files) + assertNotNull(outDir); Files.write( Path.of(outDir, "document.odp"), "Fake ODP content".getBytes()); @@ -530,6 +530,7 @@ class PDFToFileTest { } // Create text output file + assertNotNull(outDir); Files.write( Path.of(outDir, "document.txt"), "Extracted text content".getBytes()); @@ -587,6 +588,7 @@ class PDFToFileTest { } // Create output file - uses default name + assertNotNull(outDir); Files.write( Path.of(outDir, "output.docx"), "Fake DOCX content".getBytes()); diff --git a/app/common/src/test/java/stirling/software/common/util/ProcessExecutorTest.java b/app/common/src/test/java/stirling/software/common/util/ProcessExecutorTest.java index d2142d70d..4ee684b7a 100644 --- a/app/common/src/test/java/stirling/software/common/util/ProcessExecutorTest.java +++ b/app/common/src/test/java/stirling/software/common/util/ProcessExecutorTest.java @@ -48,9 +48,7 @@ public class ProcessExecutorTest { IOException thrown = assertThrows( IOException.class, - () -> { - processExecutor.runCommandWithOutputHandling(command); - }); + () -> processExecutor.runCommandWithOutputHandling(command)); // Check the exception message to ensure it indicates the command was not found String errorMessage = thrown.getMessage(); diff --git a/app/common/src/test/java/stirling/software/common/util/PropertyConfigsTest.java b/app/common/src/test/java/stirling/software/common/util/PropertyConfigsTest.java index 6fe9c7202..a8101add6 100644 --- a/app/common/src/test/java/stirling/software/common/util/PropertyConfigsTest.java +++ b/app/common/src/test/java/stirling/software/common/util/PropertyConfigsTest.java @@ -1,6 +1,7 @@ package stirling.software.common.util; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.List; @@ -22,7 +23,7 @@ public class PropertyConfigsTest { boolean result = PropertyConfigs.getBooleanValue(keys, defaultValue); // Verify the result - assertEquals(true, result); + assertTrue(result); } @Test @@ -51,7 +52,7 @@ public class PropertyConfigsTest { boolean result = PropertyConfigs.getBooleanValue(key, defaultValue); // Verify the result - assertEquals(true, result); + assertTrue(result); } @Test diff --git a/app/common/src/test/java/stirling/software/common/util/RegexPatternUtilsTest.java b/app/common/src/test/java/stirling/software/common/util/RegexPatternUtilsTest.java index a691cd42b..90ef5c802 100644 --- a/app/common/src/test/java/stirling/software/common/util/RegexPatternUtilsTest.java +++ b/app/common/src/test/java/stirling/software/common/util/RegexPatternUtilsTest.java @@ -62,17 +62,11 @@ public class RegexPatternUtilsTest { @Test void testNullRegexHandling() { - assertThrows( - IllegalArgumentException.class, - () -> { - utils.getPattern(null); - }); + assertThrows(IllegalArgumentException.class, () -> utils.getPattern(null)); assertThrows( IllegalArgumentException.class, - () -> { - utils.getPattern(null, Pattern.CASE_INSENSITIVE); - }); + () -> utils.getPattern(null, Pattern.CASE_INSENSITIVE)); assertFalse(utils.isCached(null)); assertFalse(utils.removeFromCache(null)); diff --git a/app/common/src/test/java/stirling/software/common/util/SpringContextHolderTest.java b/app/common/src/test/java/stirling/software/common/util/SpringContextHolderTest.java index 0f53bb404..438381cd6 100644 --- a/app/common/src/test/java/stirling/software/common/util/SpringContextHolderTest.java +++ b/app/common/src/test/java/stirling/software/common/util/SpringContextHolderTest.java @@ -57,8 +57,7 @@ class SpringContextHolderTest { void testGetBean_BeanNotFound() { // Arrange contextHolder.setApplicationContext(mockApplicationContext); - when(mockApplicationContext.getBean(TestBean.class)) - .thenThrow(new org.springframework.beans.BeansException("Bean not found") {}); + when(mockApplicationContext.getBean(TestBean.class)).thenThrow(new MyBeansException()); // Act TestBean result = SpringContextHolder.getBean(TestBean.class); @@ -69,4 +68,10 @@ class SpringContextHolderTest { // Simple test class private static class TestBean {} + + private static class MyBeansException extends org.springframework.beans.BeansException { + public MyBeansException() { + super("Bean not found"); + } + } } diff --git a/app/common/src/test/java/stirling/software/common/util/misc/InvertFullColorStrategyTest.java b/app/common/src/test/java/stirling/software/common/util/misc/InvertFullColorStrategyTest.java index 7bdf4f612..85d0d2513 100644 --- a/app/common/src/test/java/stirling/software/common/util/misc/InvertFullColorStrategyTest.java +++ b/app/common/src/test/java/stirling/software/common/util/misc/InvertFullColorStrategyTest.java @@ -33,22 +33,9 @@ import stirling.software.common.model.api.misc.ReplaceAndInvert; class InvertFullColorStrategyTest { private InvertFullColorStrategy strategy; - private MultipartFile mockPdfFile; - - @BeforeEach - void setUp() throws Exception { - // Create a simple PDF document for testing - byte[] pdfBytes = createSimplePdfWithRectangle(); - mockPdfFile = - new MockMultipartFile( - "file", "test.pdf", MediaType.APPLICATION_PDF_VALUE, pdfBytes); - - // Create the strategy instance - strategy = new InvertFullColorStrategy(mockPdfFile, ReplaceAndInvert.FULL_INVERSION); - } /** Helper method to create a simple PDF with a colored rectangle for testing */ - private byte[] createSimplePdfWithRectangle() throws IOException { + private static byte[] createSimplePdfWithRectangle() throws IOException { PDDocument document = new PDDocument(); PDPage page = new PDPage(PDRectangle.A4); document.addPage(page); @@ -68,6 +55,18 @@ class InvertFullColorStrategyTest { return baos.toByteArray(); } + @BeforeEach + void setUp() throws Exception { + // Create a simple PDF document for testing + byte[] pdfBytes = createSimplePdfWithRectangle(); + MultipartFile mockPdfFile = + new MockMultipartFile( + "file", "test.pdf", MediaType.APPLICATION_PDF_VALUE, pdfBytes); + + // Create the strategy instance + strategy = new InvertFullColorStrategy(mockPdfFile, ReplaceAndInvert.FULL_INVERSION); + } + @Test void testReplace() throws IOException { // Test the replace method diff --git a/app/common/src/test/java/stirling/software/common/util/misc/PdfTextStripperCustomTest.java b/app/common/src/test/java/stirling/software/common/util/misc/PdfTextStripperCustomTest.java index 35898718e..0d448a86a 100644 --- a/app/common/src/test/java/stirling/software/common/util/misc/PdfTextStripperCustomTest.java +++ b/app/common/src/test/java/stirling/software/common/util/misc/PdfTextStripperCustomTest.java @@ -1,7 +1,6 @@ package stirling.software.common.util.misc; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -16,7 +15,6 @@ class PdfTextStripperCustomTest { private PdfTextStripperCustom stripper; private PDPage mockPage; - private PDRectangle mockMediaBox; @BeforeEach void setUp() throws IOException { @@ -25,7 +23,7 @@ class PdfTextStripperCustomTest { // Create mock objects mockPage = mock(PDPage.class); - mockMediaBox = mock(PDRectangle.class); + PDRectangle mockMediaBox = mock(PDRectangle.class); // Configure mock behavior when(mockPage.getMediaBox()).thenReturn(mockMediaBox); @@ -43,14 +41,14 @@ class PdfTextStripperCustomTest { } @Test - void testBasicFunctionality() throws IOException { + void testBasicFunctionality() { // Simply test that the method runs without exceptions try { stripper.addRegion("testRegion", new java.awt.geom.Rectangle2D.Float(0, 0, 100, 100)); stripper.extractRegions(mockPage); assertTrue(true, "Should execute without errors"); } catch (Exception e) { - assertTrue(false, "Method should not throw exception: " + e.getMessage()); + fail("Method should not throw exception: " + e.getMessage()); } } } diff --git a/app/common/src/test/java/stirling/software/common/util/propertyeditor/StringToArrayListPropertyEditorTest.java b/app/common/src/test/java/stirling/software/common/util/propertyeditor/StringToArrayListPropertyEditorTest.java index ce1535986..bda522e0f 100644 --- a/app/common/src/test/java/stirling/software/common/util/propertyeditor/StringToArrayListPropertyEditorTest.java +++ b/app/common/src/test/java/stirling/software/common/util/propertyeditor/StringToArrayListPropertyEditorTest.java @@ -1,9 +1,6 @@ package stirling.software.common.util.propertyeditor; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import java.util.List; @@ -33,7 +30,7 @@ class StringToArrayListPropertyEditorTest { // Assert assertNotNull(value, "Value should not be null"); - assertTrue(value instanceof List, "Value should be a List"); + assertInstanceOf(List.class, value, "Value should be a List"); @SuppressWarnings("unchecked") List list = (List) value; @@ -63,7 +60,7 @@ class StringToArrayListPropertyEditorTest { // Assert assertNotNull(value, "Value should not be null"); - assertTrue(value instanceof List, "Value should be a List"); + assertInstanceOf(List.class, value, "Value should be a List"); @SuppressWarnings("unchecked") List list = (List) value; @@ -91,7 +88,7 @@ class StringToArrayListPropertyEditorTest { // Assert assertNotNull(value, "Value should not be null"); - assertTrue(value instanceof List, "Value should be a List"); + assertInstanceOf(List.class, value, "Value should be a List"); @SuppressWarnings("unchecked") List list = (List) value; @@ -106,7 +103,7 @@ class StringToArrayListPropertyEditorTest { // Assert assertNotNull(value, "Value should not be null"); - assertTrue(value instanceof List, "Value should be a List"); + assertInstanceOf(List.class, value, "Value should be a List"); @SuppressWarnings("unchecked") List list = (List) value; @@ -125,7 +122,7 @@ class StringToArrayListPropertyEditorTest { // Assert assertNotNull(value, "Value should not be null"); - assertTrue(value instanceof List, "Value should be a List"); + assertInstanceOf(List.class, value, "Value should be a List"); @SuppressWarnings("unchecked") List list = (List) value; diff --git a/app/common/src/test/java/stirling/software/common/util/propertyeditor/StringToMapPropertyEditorTest.java b/app/common/src/test/java/stirling/software/common/util/propertyeditor/StringToMapPropertyEditorTest.java index cfee8709c..3e492c9bd 100644 --- a/app/common/src/test/java/stirling/software/common/util/propertyeditor/StringToMapPropertyEditorTest.java +++ b/app/common/src/test/java/stirling/software/common/util/propertyeditor/StringToMapPropertyEditorTest.java @@ -1,9 +1,6 @@ package stirling.software.common.util.propertyeditor; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import java.util.Map; @@ -30,7 +27,7 @@ class StringToMapPropertyEditorTest { // Assert assertNotNull(value, "Value should not be null"); - assertTrue(value instanceof Map, "Value should be a Map"); + assertInstanceOf(Map.class, value, "Value should be a Map"); @SuppressWarnings("unchecked") Map map = (Map) value; @@ -50,7 +47,7 @@ class StringToMapPropertyEditorTest { // Assert assertNotNull(value, "Value should not be null"); - assertTrue(value instanceof Map, "Value should be a Map"); + assertInstanceOf(Map.class, value, "Value should be a Map"); @SuppressWarnings("unchecked") Map map = (Map) value; @@ -68,7 +65,7 @@ class StringToMapPropertyEditorTest { // Assert assertNotNull(value, "Value should not be null"); - assertTrue(value instanceof Map, "Value should be a Map"); + assertInstanceOf(Map.class, value, "Value should be a Map"); @SuppressWarnings("unchecked") Map map = (Map) value; @@ -87,7 +84,7 @@ class StringToMapPropertyEditorTest { // Assert assertNotNull(value, "Value should not be null"); - assertTrue(value instanceof Map, "Value should be a Map"); + assertInstanceOf(Map.class, value, "Value should be a Map"); @SuppressWarnings("unchecked") Map map = (Map) value; diff --git a/app/core/src/test/java/stirling/software/SPDF/SPDFApplicationTest.java b/app/core/src/test/java/stirling/software/SPDF/SPDFApplicationTest.java index 087475c85..dd53d24dd 100644 --- a/app/core/src/test/java/stirling/software/SPDF/SPDFApplicationTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/SPDFApplicationTest.java @@ -5,22 +5,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.core.env.Environment; - -import stirling.software.common.model.ApplicationProperties; @ExtendWith(MockitoExtension.class) public class SPDFApplicationTest { - @Mock private Environment env; - - @Mock private ApplicationProperties applicationProperties; - - @InjectMocks private SPDFApplication sPDFApplication; - @BeforeEach public void setUp() { SPDFApplication.setServerPortStatic("8080"); diff --git a/app/core/src/test/java/stirling/software/SPDF/controller/api/MergeControllerTest.java b/app/core/src/test/java/stirling/software/SPDF/controller/api/MergeControllerTest.java index 9cf11ad79..c245cffb0 100644 --- a/app/core/src/test/java/stirling/software/SPDF/controller/api/MergeControllerTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/controller/api/MergeControllerTest.java @@ -37,10 +37,8 @@ class MergeControllerTest { private MockMultipartFile mockFile1; private MockMultipartFile mockFile2; private MockMultipartFile mockFile3; - private PDDocument mockDocument; private PDDocument mockMergedDocument; private PDDocumentCatalog mockCatalog; - private PDPageTree mockPages; private PDPage mockPage1; private PDPage mockPage2; @@ -65,10 +63,10 @@ class MergeControllerTest { MediaType.APPLICATION_PDF_VALUE, "PDF content 3".getBytes()); - mockDocument = mock(PDDocument.class); + PDDocument mockDocument = mock(PDDocument.class); mockMergedDocument = mock(PDDocument.class); mockCatalog = mock(PDDocumentCatalog.class); - mockPages = mock(PDPageTree.class); + PDPageTree mockPages = mock(PDPageTree.class); mockPage1 = mock(PDPage.class); mockPage2 = mock(PDPage.class); } diff --git a/app/core/src/test/java/stirling/software/SPDF/controller/api/RotationControllerTest.java b/app/core/src/test/java/stirling/software/SPDF/controller/api/RotationControllerTest.java index 6ac0b45d3..a16746bd5 100644 --- a/app/core/src/test/java/stirling/software/SPDF/controller/api/RotationControllerTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/controller/api/RotationControllerTest.java @@ -61,7 +61,7 @@ public class RotationControllerTest { } @Test - public void testRotatePDFInvalidAngle() throws IOException { + public void testRotatePDFInvalidAngle() { // Create a mock file MockMultipartFile mockFile = new MockMultipartFile( diff --git a/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPdfTest.java b/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPdfTest.java index 9abcbae92..d3850bc6e 100644 --- a/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPdfTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPdfTest.java @@ -213,7 +213,6 @@ public class ConvertWebsiteToPdfTest { assertNotNull(outPathStr); // Temp file must be deleted in finally - Path outPath = Path.of(outPathStr); assertFalse( Files.exists(Path.of(htmlPathStr)), "Temp HTML file should be deleted after the call"); @@ -283,6 +282,24 @@ public class ConvertWebsiteToPdfTest { } } + private static MockedStatic mockHttpClientReturning(String body) throws Exception { + MockedStatic httpClientStatic = Mockito.mockStatic(HttpClient.class); + HttpClient.Builder builder = Mockito.mock(HttpClient.Builder.class); + HttpClient client = Mockito.mock(HttpClient.class); + HttpResponse response = Mockito.mock(); + + httpClientStatic.when(HttpClient::newBuilder).thenReturn(builder); + when(builder.followRedirects(HttpClient.Redirect.NORMAL)).thenReturn(builder); + when(builder.connectTimeout(any(Duration.class))).thenReturn(builder); + when(builder.build()).thenReturn(client); + + Mockito.doReturn(response).when(client).send(any(HttpRequest.class), any()); + when(response.statusCode()).thenReturn(200); + when(response.body()).thenReturn(body); + + return httpClientStatic; + } + @Test void redirect_with_error_when_disallowed_content_detected() throws Exception { UrlToPdfRequest request = new UrlToPdfRequest(); @@ -291,7 +308,7 @@ public class ConvertWebsiteToPdfTest { try (MockedStatic gu = Mockito.mockStatic(GeneralUtils.class); MockedStatic httpClient = mockHttpClientReturning( - ""); ) { + "")) { gu.when(() -> GeneralUtils.isValidURL("https://example.com")).thenReturn(true); gu.when(() -> GeneralUtils.isURLReachable("https://example.com")).thenReturn(true); @@ -306,23 +323,4 @@ public class ConvertWebsiteToPdfTest { && location.getQuery().contains("error=error.disallowedUrlContent")); } } - - private MockedStatic mockHttpClientReturning(String body) throws Exception { - MockedStatic httpClientStatic = Mockito.mockStatic(HttpClient.class); - HttpClient.Builder builder = Mockito.mock(HttpClient.Builder.class); - HttpClient client = Mockito.mock(HttpClient.class); - HttpResponse response = Mockito.mock(HttpResponse.class); - - httpClientStatic.when(HttpClient::newBuilder).thenReturn(builder); - when(builder.followRedirects(HttpClient.Redirect.NORMAL)).thenReturn(builder); - when(builder.connectTimeout(any(Duration.class))).thenReturn(builder); - when(builder.build()).thenReturn(client); - - when(client.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class))) - .thenReturn(response); - when(response.statusCode()).thenReturn(200); - when(response.body()).thenReturn(body); - - return httpClientStatic; - } } diff --git a/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/PdfToCbzUtilsTest.java b/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/PdfToCbzUtilsTest.java index 6cd6c6821..1667c465f 100644 --- a/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/PdfToCbzUtilsTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/PdfToCbzUtilsTest.java @@ -42,9 +42,7 @@ public class PdfToCbzUtilsTest { IllegalArgumentException exception = Assertions.assertThrows( IllegalArgumentException.class, - () -> { - PdfToCbzUtils.convertPdfToCbz(null, 300, pdfDocumentFactory); - }); + () -> PdfToCbzUtils.convertPdfToCbz(null, 300, pdfDocumentFactory)); Assertions.assertEquals("File cannot be null or empty", exception.getMessage()); } @@ -56,9 +54,7 @@ public class PdfToCbzUtilsTest { IllegalArgumentException exception = Assertions.assertThrows( IllegalArgumentException.class, - () -> { - PdfToCbzUtils.convertPdfToCbz(emptyFile, 300, pdfDocumentFactory); - }); + () -> PdfToCbzUtils.convertPdfToCbz(emptyFile, 300, pdfDocumentFactory)); Assertions.assertEquals("File cannot be null or empty", exception.getMessage()); } @@ -70,9 +66,7 @@ public class PdfToCbzUtilsTest { IllegalArgumentException exception = Assertions.assertThrows( IllegalArgumentException.class, - () -> { - PdfToCbzUtils.convertPdfToCbz(nonPdfFile, 300, pdfDocumentFactory); - }); + () -> PdfToCbzUtils.convertPdfToCbz(nonPdfFile, 300, pdfDocumentFactory)); Assertions.assertEquals("File must be a PDF", exception.getMessage()); } @@ -90,9 +84,7 @@ public class PdfToCbzUtilsTest { // structure Assertions.assertThrows( Exception.class, - () -> { - PdfToCbzUtils.convertPdfToCbz(pdfFile, 300, pdfDocumentFactory); - }); + () -> PdfToCbzUtils.convertPdfToCbz(pdfFile, 300, pdfDocumentFactory)); // Verify that load was called Mockito.verify(pdfDocumentFactory).load(pdfFile); diff --git a/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/PdfVectorExportControllerTest.java b/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/PdfVectorExportControllerTest.java index 2c0e4c7ed..ad63b2103 100644 --- a/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/PdfVectorExportControllerTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/PdfVectorExportControllerTest.java @@ -116,7 +116,7 @@ class PdfVectorExportControllerTest { void convertGhostscript_pdfPassThrough_success() throws Exception { when(endpointConfiguration.isGroupEnabled("Ghostscript")).thenReturn(false); - byte[] content = new byte[] {1}; + byte[] content = {1}; MockMultipartFile file = new MockMultipartFile( "fileInput", "input.pdf", MediaType.APPLICATION_PDF_VALUE, content); @@ -131,7 +131,7 @@ class PdfVectorExportControllerTest { } @Test - void convertGhostscript_unsupportedFormatThrows() throws Exception { + void convertGhostscript_unsupportedFormatThrows() { when(endpointConfiguration.isGroupEnabled("Ghostscript")).thenReturn(false); MockMultipartFile file = new MockMultipartFile( diff --git a/app/core/src/test/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessorTest.java b/app/core/src/test/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessorTest.java index fd6f7cca0..5f3b56357 100644 --- a/app/core/src/test/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessorTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessorTest.java @@ -49,13 +49,7 @@ class PipelineProcessorTest { PipelineConfig config = new PipelineConfig(); config.setOperations(List.of(op)); - Resource file = - new ByteArrayResource("data".getBytes()) { - @Override - public String getFilename() { - return "test.pdf"; - } - }; + Resource file = new MyFileByteArrayResource(); List files = List.of(file); @@ -77,4 +71,15 @@ class PipelineProcessorTest { assertFalse(result.isHasErrors(), "No errors should occur"); assertTrue(result.getOutputFiles().isEmpty(), "Filtered file list should be empty"); } + + private static class MyFileByteArrayResource extends ByteArrayResource { + public MyFileByteArrayResource() { + super("data".getBytes()); + } + + @Override + public String getFilename() { + return "test.pdf"; + } + } } diff --git a/app/core/src/test/java/stirling/software/SPDF/controller/api/security/RedactControllerTest.java b/app/core/src/test/java/stirling/software/SPDF/controller/api/security/RedactControllerTest.java index ee7aa8970..75f1b8d01 100644 --- a/app/core/src/test/java/stirling/software/SPDF/controller/api/security/RedactControllerTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/controller/api/security/RedactControllerTest.java @@ -69,61 +69,45 @@ class RedactControllerTest { private PDDocument realDocument; private PDPage realPage; - // Helpers - private void testAutoRedaction( - String searchText, - boolean useRegex, - boolean wholeWordSearch, - String redactColor, - float padding, - boolean convertToImage, - boolean expectSuccess) - throws Exception { - RedactPdfRequest request = createRedactPdfRequest(); - request.setListOfText(searchText); - request.setUseRegex(useRegex); - request.setWholeWordSearch(wholeWordSearch); - request.setRedactColor(redactColor); - request.setCustomPadding(padding); - request.setConvertPDFToImage(convertToImage); - - try { - ResponseEntity response = redactController.redactPdf(request); - - if (expectSuccess && response != null) { - assertNotNull(response); - assertEquals(200, response.getStatusCode().value()); - assertNotNull(response.getBody()); - assertTrue(response.getBody().length > 0); - verify(mockDocument, times(1)).save(any(ByteArrayOutputStream.class)); - verify(mockDocument, times(1)).close(); - } - } catch (Exception e) { - if (expectSuccess) { - log.info("Redaction test completed with graceful handling: {}", e.getMessage()); - } else { - assertNotNull(e.getMessage()); + private static byte[] createSimplePdfContent() throws IOException { + try (PDDocument doc = new PDDocument()) { + PDPage page = new PDPage(PDRectangle.A4); + doc.addPage(page); + try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) { + contentStream.beginText(); + contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA), 12); + contentStream.newLineAtOffset(100, 700); + contentStream.showText("This is a simple PDF."); + contentStream.endText(); } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + doc.save(baos); + return baos.toByteArray(); } } - private void testManualRedaction(List redactionAreas, boolean convertToImage) - throws Exception { - ManualRedactPdfRequest request = createManualRedactPdfRequest(); - request.setRedactions(redactionAreas); - request.setConvertPDFToImage(convertToImage); + private static List createValidRedactionAreas() { + List areas = new ArrayList<>(); - try { - ResponseEntity response = redactController.redactPDF(request); + RedactionArea area1 = new RedactionArea(); + area1.setPage(1); + area1.setX(100.0); + area1.setY(100.0); + area1.setWidth(200.0); + area1.setHeight(50.0); + area1.setColor("000000"); + areas.add(area1); - if (response != null) { - assertNotNull(response); - assertEquals(200, response.getStatusCode().value()); - verify(mockDocument, times(1)).save(any(ByteArrayOutputStream.class)); - } - } catch (Exception e) { - log.info("Manual redaction test completed with graceful handling: {}", e.getMessage()); - } + RedactionArea area2 = new RedactionArea(); + area2.setPage(1); + area2.setX(300.0); + area2.setY(200.0); + area2.setWidth(150.0); + area2.setHeight(30.0); + area2.setColor("FF0000"); + areas.add(area2); + + return areas; } @BeforeEach @@ -189,16 +173,18 @@ class RedactControllerTest { setupRealDocument(); } - private void setupRealDocument() throws IOException { - realDocument = new PDDocument(); - realPage = new PDPage(PDRectangle.A4); - realDocument.addPage(realPage); + private static List createInvalidRedactionAreas() { + List areas = new ArrayList<>(); - // Set up basic page resources - PDResources resources = new PDResources(); - resources.put( - COSName.getPDFName("F1"), new PDType1Font(Standard14Fonts.FontName.HELVETICA)); - realPage.setResources(resources); + RedactionArea invalidArea = new RedactionArea(); + invalidArea.setPage(null); // Invalid - null page + invalidArea.setX(100.0); + invalidArea.setY(100.0); + invalidArea.setWidth(200.0); + invalidArea.setHeight(50.0); + areas.add(invalidArea); + + return areas; } @AfterEach @@ -607,13 +593,266 @@ class RedactControllerTest { } } + private static List createMultipleRedactionAreas() { + List areas = new ArrayList<>(); + + for (int i = 0; i < 5; i++) { + RedactionArea area = new RedactionArea(); + area.setPage(1); + area.setX(50.0 + (i * 60)); + area.setY(50.0 + (i * 40)); + area.setWidth(50.0); + area.setHeight(30.0); + area.setColor(String.format("%06X", i * 0x333333)); + areas.add(area); + } + + return areas; + } + + private static List createOverlappingRedactionAreas() { + List areas = new ArrayList<>(); + + RedactionArea area1 = new RedactionArea(); + area1.setPage(1); + area1.setX(100.0); + area1.setY(100.0); + area1.setWidth(200.0); + area1.setHeight(100.0); + area1.setColor("FF0000"); + areas.add(area1); + + RedactionArea area2 = new RedactionArea(); + area2.setPage(1); + area2.setX(150.0); // Overlaps with area1 + area2.setY(150.0); // Overlaps with area1 + area2.setWidth(200.0); + area2.setHeight(100.0); + area2.setColor("00FF00"); + areas.add(area2); + + return areas; + } + + // Helper for token creation + private static List createSampleTokenList() { + return List.of( + Operator.getOperator("BT"), + COSName.getPDFName("F1"), + new COSFloat(12), + Operator.getOperator("Tf"), + new COSString("Sample text"), + Operator.getOperator("Tj"), + Operator.getOperator("ET")); + } + + private RedactPdfRequest createRedactPdfRequest() { + RedactPdfRequest request = new RedactPdfRequest(); + request.setFileInput(mockPdfFile); + return request; + } + + private ManualRedactPdfRequest createManualRedactPdfRequest() { + ManualRedactPdfRequest request = new ManualRedactPdfRequest(); + request.setFileInput(mockPdfFile); + return request; + } + + private static String extractTextFromTokens(List tokens) { + StringBuilder text = new StringBuilder(); + for (Object token : tokens) { + if (token instanceof COSString cosString) { + text.append(cosString.getString()); + } else if (token instanceof COSArray array) { + for (int i = 0; i < array.size(); i++) { + if (array.getObject(i) instanceof COSString cosString) { + text.append(cosString.getString()); + } + } + } + } + return text.toString(); + } + + private static byte[] readAllBytes(InputStream inputStream) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int nRead; + byte[] data = new byte[1024]; + while ((nRead = inputStream.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + return buffer.toByteArray(); + } + + // Helpers + private void testAutoRedaction( + String searchText, + boolean useRegex, + boolean wholeWordSearch, + String redactColor, + float padding, + boolean convertToImage, + boolean expectSuccess) { + RedactPdfRequest request = createRedactPdfRequest(); + request.setListOfText(searchText); + request.setUseRegex(useRegex); + request.setWholeWordSearch(wholeWordSearch); + request.setRedactColor(redactColor); + request.setCustomPadding(padding); + request.setConvertPDFToImage(convertToImage); + + try { + ResponseEntity response = redactController.redactPdf(request); + + if (expectSuccess && response != null) { + assertNotNull(response); + assertEquals(200, response.getStatusCode().value()); + assertNotNull(response.getBody()); + assertTrue(response.getBody().length > 0); + verify(mockDocument, times(1)).save(any(ByteArrayOutputStream.class)); + verify(mockDocument, times(1)).close(); + } + } catch (Exception e) { + if (expectSuccess) { + log.info("Redaction test completed with graceful handling: {}", e.getMessage()); + } else { + assertNotNull(e.getMessage()); + } + } + } + + private void testManualRedaction(List redactionAreas, boolean convertToImage) { + ManualRedactPdfRequest request = createManualRedactPdfRequest(); + request.setRedactions(redactionAreas); + request.setConvertPDFToImage(convertToImage); + + try { + ResponseEntity response = redactController.redactPDF(request); + + if (response != null) { + assertNotNull(response); + assertEquals(200, response.getStatusCode().value()); + verify(mockDocument, times(1)).save(any(ByteArrayOutputStream.class)); + } + } catch (Exception e) { + log.info("Manual redaction test completed with graceful handling: {}", e.getMessage()); + } + } + + private void setupRealDocument() { + realDocument = new PDDocument(); + realPage = new PDPage(PDRectangle.A4); + realDocument.addPage(realPage); + + // Set up basic page resources + PDResources resources = new PDResources(); + resources.put( + COSName.getPDFName("F1"), new PDType1Font(Standard14Fonts.FontName.HELVETICA)); + realPage.setResources(resources); + } + + // Helper methods for real PDF content creation + private void createRealPageWithSimpleText(String text) throws IOException { + realPage = new PDPage(PDRectangle.A4); + while (realDocument.getNumberOfPages() > 0) { + realDocument.removePage(0); + } + realDocument.addPage(realPage); + realPage.setResources(new PDResources()); + realPage.getResources() + .put(COSName.getPDFName("F1"), new PDType1Font(Standard14Fonts.FontName.HELVETICA)); + + try (PDPageContentStream contentStream = new PDPageContentStream(realDocument, realPage)) { + contentStream.beginText(); + contentStream.setFont(realPage.getResources().getFont(COSName.getPDFName("F1")), 12); + contentStream.newLineAtOffset(50, 750); + contentStream.showText(text); + contentStream.endText(); + } + } + + private void createRealPageWithTJArrayText() throws IOException { + realPage = new PDPage(PDRectangle.A4); + while (realDocument.getNumberOfPages() > 0) { + realDocument.removePage(0); + } + realDocument.addPage(realPage); + realPage.setResources(new PDResources()); + realPage.getResources() + .put(COSName.getPDFName("F1"), new PDType1Font(Standard14Fonts.FontName.HELVETICA)); + + try (PDPageContentStream contentStream = new PDPageContentStream(realDocument, realPage)) { + contentStream.beginText(); + contentStream.setFont(realPage.getResources().getFont(COSName.getPDFName("F1")), 12); + contentStream.newLineAtOffset(50, 750); + + contentStream.showText("This is "); + contentStream.newLineAtOffset(-10, 0); // Simulate positioning + contentStream.showText("secret"); + contentStream.newLineAtOffset(10, 0); // Reset positioning + contentStream.showText(" information"); + contentStream.endText(); + } + } + + private void createRealPageWithMixedContent() throws IOException { + realPage = new PDPage(PDRectangle.A4); + while (realDocument.getNumberOfPages() > 0) { + realDocument.removePage(0); + } + realDocument.addPage(realPage); + realPage.setResources(new PDResources()); + realPage.getResources() + .put(COSName.getPDFName("F1"), new PDType1Font(Standard14Fonts.FontName.HELVETICA)); + + try (PDPageContentStream contentStream = new PDPageContentStream(realDocument, realPage)) { + contentStream.setLineWidth(2); + contentStream.moveTo(100, 100); + contentStream.lineTo(200, 200); + contentStream.stroke(); + + contentStream.beginText(); + contentStream.setFont(realPage.getResources().getFont(COSName.getPDFName("F1")), 12); + contentStream.newLineAtOffset(50, 750); + contentStream.showText("Please redact this content"); + contentStream.endText(); + } + } + + private void createRealPageWithSpecificOperator(String operatorName) throws IOException { + createRealPageWithSimpleText("sensitive data"); + } + + private void createRealPageWithPositionedText() throws IOException { + realPage = new PDPage(PDRectangle.A4); + while (realDocument.getNumberOfPages() > 0) { + realDocument.removePage(0); + } + realDocument.addPage(realPage); + realPage.setResources(new PDResources()); + realPage.getResources() + .put(COSName.getPDFName("F1"), new PDType1Font(Standard14Fonts.FontName.HELVETICA)); + + try (PDPageContentStream contentStream = new PDPageContentStream(realDocument, realPage)) { + contentStream.beginText(); + contentStream.setFont(realPage.getResources().getFont(COSName.getPDFName("F1")), 12); + contentStream.newLineAtOffset(50, 750); + contentStream.showText("Normal text "); + contentStream.newLineAtOffset(100, 0); + contentStream.showText("confidential"); + contentStream.newLineAtOffset(100, 0); + contentStream.showText(" more text"); + contentStream.endText(); + } + } + @Nested @DisplayName("Error Handling and Edge Cases") class ErrorHandlingTests { @Test @DisplayName("Should handle null file input gracefully") - void handleNullFileInput() throws Exception { + void handleNullFileInput() { RedactPdfRequest request = new RedactPdfRequest(); request.setFileInput(null); request.setListOfText("test"); @@ -630,7 +869,7 @@ class RedactControllerTest { @Test @DisplayName("Should handle malformed PDF gracefully") - void handleMalformedPdfGracefully() throws Exception { + void handleMalformedPdfGracefully() { MockMultipartFile malformedFile = new MockMultipartFile( "fileInput", @@ -674,7 +913,7 @@ class RedactControllerTest { @Test @DisplayName("Should handle null redact color gracefully") - void handleNullRedactColor() throws Exception { + void handleNullRedactColor() { RedactPdfRequest request = createRedactPdfRequest(); request.setListOfText("test"); request.setRedactColor(null); @@ -722,34 +961,50 @@ class RedactControllerTest { } } + private List getOriginalTokens() throws Exception { + // Create a new page to avoid side effects from other tests + PDPage pageForTokenExtraction = new PDPage(PDRectangle.A4); + pageForTokenExtraction.setResources(realPage.getResources()); + try (PDPageContentStream contentStream = + new PDPageContentStream(realDocument, pageForTokenExtraction)) { + contentStream.beginText(); + contentStream.setFont(realPage.getResources().getFont(COSName.getPDFName("F1")), 12); + contentStream.newLineAtOffset(50, 750); + contentStream.showText("Original content"); + contentStream.endText(); + } + return redactController.createTokensWithoutTargetText( + realDocument, pageForTokenExtraction, Collections.emptySet(), false, false); + } + @Nested @DisplayName("Color Decoding Utility Tests") class ColorDecodingTests { @Test @DisplayName("Should decode valid hex color with hash") - void decodeValidHexColorWithHash() throws Exception { + void decodeValidHexColorWithHash() { Color result = redactController.decodeOrDefault("#FF0000"); assertEquals(Color.RED, result); } @Test @DisplayName("Should decode valid hex color without hash") - void decodeValidHexColorWithoutHash() throws Exception { + void decodeValidHexColorWithoutHash() { Color result = redactController.decodeOrDefault("FF0000"); assertEquals(Color.RED, result); } @Test @DisplayName("Should default to black for null color") - void defaultToBlackForNullColor() throws Exception { + void defaultToBlackForNullColor() { Color result = redactController.decodeOrDefault(null); assertEquals(Color.BLACK, result); } @Test @DisplayName("Should default to black for invalid color") - void defaultToBlackForInvalidColor() throws Exception { + void defaultToBlackForInvalidColor() { Color result = redactController.decodeOrDefault("invalid-color"); assertEquals(Color.BLACK, result); } @@ -761,7 +1016,7 @@ class RedactControllerTest { "0000FF" }) @DisplayName("Should handle various valid color formats") - void handleVariousValidColorFormats(String colorInput) throws Exception { + void handleVariousValidColorFormats(String colorInput) { Color result = redactController.decodeOrDefault(colorInput); assertNotNull(result); assertTrue( @@ -777,7 +1032,7 @@ class RedactControllerTest { @Test @DisplayName("Should handle short hex codes appropriately") - void handleShortHexCodes() throws Exception { + void handleShortHexCodes() { Color result1 = redactController.decodeOrDefault("123"); Color result2 = redactController.decodeOrDefault("#12"); @@ -786,6 +1041,15 @@ class RedactControllerTest { } } + private String extractTextFromModifiedPage(PDPage page) throws IOException { + if (page.getContents() != null) { + try (InputStream inputStream = page.getContents()) { + return new String(readAllBytes(inputStream)); + } + } + return ""; + } + @Nested @DisplayName("Content Stream Unit Tests") class ContentStreamUnitTests { @@ -974,7 +1238,7 @@ class RedactControllerTest { @Test @DisplayName("Placeholder creation should maintain text width") - void shouldCreateWidthMatchingPlaceholder() throws Exception { + void shouldCreateWidthMatchingPlaceholder() { String originalText = "confidential"; String placeholder = redactController.createPlaceholderWithFont( @@ -988,7 +1252,7 @@ class RedactControllerTest { @Test @DisplayName("Placeholder should handle special characters") - void shouldHandleSpecialCharactersInPlaceholder() throws Exception { + void shouldHandleSpecialCharactersInPlaceholder() { String originalText = "café naïve"; String placeholder = redactController.createPlaceholderWithFont( @@ -1163,270 +1427,4 @@ class RedactControllerTest { assertTrue(response.getBody().length > 0); } } - - private RedactPdfRequest createRedactPdfRequest() { - RedactPdfRequest request = new RedactPdfRequest(); - request.setFileInput(mockPdfFile); - return request; - } - - private ManualRedactPdfRequest createManualRedactPdfRequest() { - ManualRedactPdfRequest request = new ManualRedactPdfRequest(); - request.setFileInput(mockPdfFile); - return request; - } - - private byte[] createSimplePdfContent() throws IOException { - try (PDDocument doc = new PDDocument()) { - PDPage page = new PDPage(PDRectangle.A4); - doc.addPage(page); - try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) { - contentStream.beginText(); - contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA), 12); - contentStream.newLineAtOffset(100, 700); - contentStream.showText("This is a simple PDF."); - contentStream.endText(); - } - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - doc.save(baos); - return baos.toByteArray(); - } - } - - private List createValidRedactionAreas() { - List areas = new ArrayList<>(); - - RedactionArea area1 = new RedactionArea(); - area1.setPage(1); - area1.setX(100.0); - area1.setY(100.0); - area1.setWidth(200.0); - area1.setHeight(50.0); - area1.setColor("000000"); - areas.add(area1); - - RedactionArea area2 = new RedactionArea(); - area2.setPage(1); - area2.setX(300.0); - area2.setY(200.0); - area2.setWidth(150.0); - area2.setHeight(30.0); - area2.setColor("FF0000"); - areas.add(area2); - - return areas; - } - - private List createInvalidRedactionAreas() { - List areas = new ArrayList<>(); - - RedactionArea invalidArea = new RedactionArea(); - invalidArea.setPage(null); // Invalid - null page - invalidArea.setX(100.0); - invalidArea.setY(100.0); - invalidArea.setWidth(200.0); - invalidArea.setHeight(50.0); - areas.add(invalidArea); - - return areas; - } - - private List createMultipleRedactionAreas() { - List areas = new ArrayList<>(); - - for (int i = 0; i < 5; i++) { - RedactionArea area = new RedactionArea(); - area.setPage(1); - area.setX(50.0 + (i * 60)); - area.setY(50.0 + (i * 40)); - area.setWidth(50.0); - area.setHeight(30.0); - area.setColor(String.format("%06X", i * 0x333333)); - areas.add(area); - } - - return areas; - } - - private List createOverlappingRedactionAreas() { - List areas = new ArrayList<>(); - - RedactionArea area1 = new RedactionArea(); - area1.setPage(1); - area1.setX(100.0); - area1.setY(100.0); - area1.setWidth(200.0); - area1.setHeight(100.0); - area1.setColor("FF0000"); - areas.add(area1); - - RedactionArea area2 = new RedactionArea(); - area2.setPage(1); - area2.setX(150.0); // Overlaps with area1 - area2.setY(150.0); // Overlaps with area1 - area2.setWidth(200.0); - area2.setHeight(100.0); - area2.setColor("00FF00"); - areas.add(area2); - - return areas; - } - - // Helper methods for real PDF content creation - private void createRealPageWithSimpleText(String text) throws IOException { - realPage = new PDPage(PDRectangle.A4); - while (realDocument.getNumberOfPages() > 0) { - realDocument.removePage(0); - } - realDocument.addPage(realPage); - realPage.setResources(new PDResources()); - realPage.getResources() - .put(COSName.getPDFName("F1"), new PDType1Font(Standard14Fonts.FontName.HELVETICA)); - - try (PDPageContentStream contentStream = new PDPageContentStream(realDocument, realPage)) { - contentStream.beginText(); - contentStream.setFont(realPage.getResources().getFont(COSName.getPDFName("F1")), 12); - contentStream.newLineAtOffset(50, 750); - contentStream.showText(text); - contentStream.endText(); - } - } - - private void createRealPageWithTJArrayText() throws IOException { - realPage = new PDPage(PDRectangle.A4); - while (realDocument.getNumberOfPages() > 0) { - realDocument.removePage(0); - } - realDocument.addPage(realPage); - realPage.setResources(new PDResources()); - realPage.getResources() - .put(COSName.getPDFName("F1"), new PDType1Font(Standard14Fonts.FontName.HELVETICA)); - - try (PDPageContentStream contentStream = new PDPageContentStream(realDocument, realPage)) { - contentStream.beginText(); - contentStream.setFont(realPage.getResources().getFont(COSName.getPDFName("F1")), 12); - contentStream.newLineAtOffset(50, 750); - - contentStream.showText("This is "); - contentStream.newLineAtOffset(-10, 0); // Simulate positioning - contentStream.showText("secret"); - contentStream.newLineAtOffset(10, 0); // Reset positioning - contentStream.showText(" information"); - contentStream.endText(); - } - } - - private void createRealPageWithMixedContent() throws IOException { - realPage = new PDPage(PDRectangle.A4); - while (realDocument.getNumberOfPages() > 0) { - realDocument.removePage(0); - } - realDocument.addPage(realPage); - realPage.setResources(new PDResources()); - realPage.getResources() - .put(COSName.getPDFName("F1"), new PDType1Font(Standard14Fonts.FontName.HELVETICA)); - - try (PDPageContentStream contentStream = new PDPageContentStream(realDocument, realPage)) { - contentStream.setLineWidth(2); - contentStream.moveTo(100, 100); - contentStream.lineTo(200, 200); - contentStream.stroke(); - - contentStream.beginText(); - contentStream.setFont(realPage.getResources().getFont(COSName.getPDFName("F1")), 12); - contentStream.newLineAtOffset(50, 750); - contentStream.showText("Please redact this content"); - contentStream.endText(); - } - } - - private void createRealPageWithSpecificOperator(String operatorName) throws IOException { - createRealPageWithSimpleText("sensitive data"); - } - - private void createRealPageWithPositionedText() throws IOException { - realPage = new PDPage(PDRectangle.A4); - while (realDocument.getNumberOfPages() > 0) { - realDocument.removePage(0); - } - realDocument.addPage(realPage); - realPage.setResources(new PDResources()); - realPage.getResources() - .put(COSName.getPDFName("F1"), new PDType1Font(Standard14Fonts.FontName.HELVETICA)); - - try (PDPageContentStream contentStream = new PDPageContentStream(realDocument, realPage)) { - contentStream.beginText(); - contentStream.setFont(realPage.getResources().getFont(COSName.getPDFName("F1")), 12); - contentStream.newLineAtOffset(50, 750); - contentStream.showText("Normal text "); - contentStream.newLineAtOffset(100, 0); - contentStream.showText("confidential"); - contentStream.newLineAtOffset(100, 0); - contentStream.showText(" more text"); - contentStream.endText(); - } - } - - // Helper for token creation - private List createSampleTokenList() { - return List.of( - Operator.getOperator("BT"), - COSName.getPDFName("F1"), - new COSFloat(12), - Operator.getOperator("Tf"), - new COSString("Sample text"), - Operator.getOperator("Tj"), - Operator.getOperator("ET")); - } - - private List getOriginalTokens() throws Exception { - // Create a new page to avoid side effects from other tests - PDPage pageForTokenExtraction = new PDPage(PDRectangle.A4); - pageForTokenExtraction.setResources(realPage.getResources()); - try (PDPageContentStream contentStream = - new PDPageContentStream(realDocument, pageForTokenExtraction)) { - contentStream.beginText(); - contentStream.setFont(realPage.getResources().getFont(COSName.getPDFName("F1")), 12); - contentStream.newLineAtOffset(50, 750); - contentStream.showText("Original content"); - contentStream.endText(); - } - return redactController.createTokensWithoutTargetText( - realDocument, pageForTokenExtraction, Collections.emptySet(), false, false); - } - - private String extractTextFromTokens(List tokens) { - StringBuilder text = new StringBuilder(); - for (Object token : tokens) { - if (token instanceof COSString cosString) { - text.append(cosString.getString()); - } else if (token instanceof COSArray array) { - for (int i = 0; i < array.size(); i++) { - if (array.getObject(i) instanceof COSString cosString) { - text.append(cosString.getString()); - } - } - } - } - return text.toString(); - } - - private String extractTextFromModifiedPage(PDPage page) throws IOException { - if (page.getContents() != null) { - try (InputStream inputStream = page.getContents()) { - return new String(readAllBytes(inputStream)); - } - } - return ""; - } - - private byte[] readAllBytes(InputStream inputStream) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - int nRead; - byte[] data = new byte[1024]; - while ((nRead = inputStream.read(data, 0, data.length)) != -1) { - buffer.write(data, 0, nRead); - } - return buffer.toByteArray(); - } } diff --git a/app/core/src/test/java/stirling/software/SPDF/controller/web/UploadLimitServiceTest.java b/app/core/src/test/java/stirling/software/SPDF/controller/web/UploadLimitServiceTest.java index 49ca634a6..219affcd3 100644 --- a/app/core/src/test/java/stirling/software/SPDF/controller/web/UploadLimitServiceTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/controller/web/UploadLimitServiceTest.java @@ -16,35 +16,8 @@ import stirling.software.common.model.ApplicationProperties; class UploadLimitServiceTest { private UploadLimitService uploadLimitService; - private ApplicationProperties applicationProperties; private ApplicationProperties.System systemProps; - @BeforeEach - void setUp() { - applicationProperties = mock(ApplicationProperties.class); - systemProps = mock(ApplicationProperties.System.class); - when(applicationProperties.getSystem()).thenReturn(systemProps); - - uploadLimitService = new UploadLimitService(); - // inject mock - try { - var field = UploadLimitService.class.getDeclaredField("applicationProperties"); - field.setAccessible(true); - field.set(uploadLimitService, applicationProperties); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - @ParameterizedTest(name = "getUploadLimit case #{index}: input={0}, expected={1}") - @MethodSource("uploadLimitParams") - void shouldComputeUploadLimitCorrectly(String input, long expected) { - when(systemProps.getFileUploadLimit()).thenReturn(input); - - long result = uploadLimitService.getUploadLimit(); - assertEquals(expected, result); - } - static Stream uploadLimitParams() { return Stream.of( // empty or null input yields 0 @@ -56,11 +29,37 @@ class UploadLimitServiceTest { // valid formats Arguments.of("10KB", 10 * 1024L), Arguments.of("2MB", 2 * 1024 * 1024L), - Arguments.of("1GB", 1L * 1024 * 1024 * 1024), + Arguments.of("1GB", (long) 1024 * 1024 * 1024), Arguments.of("5mb", 5 * 1024 * 1024L), Arguments.of("0MB", 0L)); } + @ParameterizedTest(name = "getUploadLimit case #{index}: input={0}, expected={1}") + @MethodSource("uploadLimitParams") + void shouldComputeUploadLimitCorrectly(String input, long expected) { + when(systemProps.getFileUploadLimit()).thenReturn(input); + + long result = uploadLimitService.getUploadLimit(); + assertEquals(expected, result); + } + + @BeforeEach + void setUp() { + ApplicationProperties applicationProperties = mock(ApplicationProperties.class); + systemProps = mock(ApplicationProperties.System.class); + when(applicationProperties.getSystem()).thenReturn(systemProps); + + uploadLimitService = new UploadLimitService(); + // inject mock + try { + var field = UploadLimitService.class.getDeclaredField("applicationProperties"); + field.setAccessible(true); + field.set(uploadLimitService, applicationProperties); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + @ParameterizedTest(name = "getReadableUploadLimit case #{index}: rawValue={0}, expected={1}") @MethodSource("readableLimitParams") void shouldReturnReadableFormat(String rawValue, String expected) { diff --git a/app/core/src/test/java/stirling/software/SPDF/service/LanguageServiceBasicTest.java b/app/core/src/test/java/stirling/software/SPDF/service/LanguageServiceBasicTest.java index f351abc8e..5bd2cb188 100644 --- a/app/core/src/test/java/stirling/software/SPDF/service/LanguageServiceBasicTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/service/LanguageServiceBasicTest.java @@ -5,7 +5,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.Set; @@ -33,12 +32,19 @@ class LanguageServiceBasicTest { languageService = new LanguageServiceForTest(applicationProperties); } + // Helper methods + private static Resource createMockResource(String filename) { + Resource mockResource = mock(Resource.class); + when(mockResource.getFilename()).thenReturn(filename); + return mockResource; + } + @Test - void testGetSupportedLanguages_BasicFunctionality() throws IOException { + void testGetSupportedLanguages_BasicFunctionality() { // Set up mocked resources Resource enResource = createMockResource("messages_en_US.properties"); Resource frResource = createMockResource("messages_fr_FR.properties"); - Resource[] mockResources = new Resource[] {enResource, frResource}; + Resource[] mockResources = {enResource, frResource}; // Configure the test service ((LanguageServiceForTest) languageService).setMockResources(mockResources); @@ -53,14 +59,13 @@ class LanguageServiceBasicTest { } @Test - void testGetSupportedLanguages_FilteringInvalidFiles() throws IOException { + void testGetSupportedLanguages_FilteringInvalidFiles() { // Set up mocked resources with invalid files - Resource[] mockResources = - new Resource[] { - createMockResource("messages_en_US.properties"), // Valid - createMockResource("invalid_file.properties"), // Invalid - createMockResource(null) // Null filename - }; + Resource[] mockResources = { + createMockResource("messages_en_US.properties"), // Valid + createMockResource("invalid_file.properties"), // Invalid + createMockResource(null) // Null filename + }; // Configure the test service ((LanguageServiceForTest) languageService).setMockResources(mockResources); @@ -77,15 +82,14 @@ class LanguageServiceBasicTest { } @Test - void testGetSupportedLanguages_WithRestrictions() throws IOException { + void testGetSupportedLanguages_WithRestrictions() { // Set up test resources - Resource[] mockResources = - new Resource[] { - createMockResource("messages_en_US.properties"), - createMockResource("messages_fr_FR.properties"), - createMockResource("messages_de_DE.properties"), - createMockResource("messages_en_GB.properties") - }; + Resource[] mockResources = { + createMockResource("messages_en_US.properties"), + createMockResource("messages_fr_FR.properties"), + createMockResource("messages_de_DE.properties"), + createMockResource("messages_en_GB.properties") + }; // Configure the test service ((LanguageServiceForTest) languageService).setMockResources(mockResources); @@ -104,13 +108,6 @@ class LanguageServiceBasicTest { assertFalse(supportedLanguages.contains("de_DE"), "Restricted language should be excluded"); } - // Helper methods - private Resource createMockResource(String filename) { - Resource mockResource = mock(Resource.class); - when(mockResource.getFilename()).thenReturn(filename); - return mockResource; - } - // Test subclass private static class LanguageServiceForTest extends LanguageService { private Resource[] mockResources; @@ -124,7 +121,7 @@ class LanguageServiceBasicTest { } @Override - protected Resource[] getResourcesFromPattern(String pattern) throws IOException { + protected Resource[] getResourcesFromPattern(String pattern) { return mockResources; } } diff --git a/app/core/src/test/java/stirling/software/SPDF/service/LanguageServiceTest.java b/app/core/src/test/java/stirling/software/SPDF/service/LanguageServiceTest.java index 24685e3b7..b6587cd28 100644 --- a/app/core/src/test/java/stirling/software/SPDF/service/LanguageServiceTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/service/LanguageServiceTest.java @@ -15,7 +15,6 @@ import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Ui; @@ -24,10 +23,15 @@ class LanguageServiceTest { private LanguageService languageService; private ApplicationProperties applicationProperties; - private PathMatchingResourcePatternResolver mockedResolver; + + private static Resource createMockResource(String filename) { + Resource mockResource = mock(Resource.class); + when(mockResource.getFilename()).thenReturn(filename); + return mockResource; + } @BeforeEach - void setUp() throws Exception { + void setUp() { // Mock ApplicationProperties applicationProperties = mock(ApplicationProperties.class); Ui ui = mock(Ui.class); @@ -38,7 +42,7 @@ class LanguageServiceTest { } @Test - void testGetSupportedLanguages_NoRestrictions() throws IOException { + void testGetSupportedLanguages_NoRestrictions() { // Setup Set expectedLanguages = new HashSet<>(Arrays.asList("en_US", "fr_FR", "de_DE", "en_GB")); @@ -61,7 +65,7 @@ class LanguageServiceTest { } @Test - void testGetSupportedLanguages_WithRestrictions() throws IOException { + void testGetSupportedLanguages_WithRestrictions() { // Setup Set expectedLanguages = new HashSet<>(Arrays.asList("en_US", "fr_FR", "de_DE", "en_GB")); @@ -87,7 +91,7 @@ class LanguageServiceTest { } @Test - void testGetSupportedLanguages_ExceptionHandling() throws IOException { + void testGetSupportedLanguages_ExceptionHandling() { // Setup - make resolver throw an exception ((LanguageServiceForTest) languageService).setShouldThrowException(true); @@ -98,19 +102,24 @@ class LanguageServiceTest { assertTrue(supportedLanguages.isEmpty(), "Should return empty set on exception"); } + // Helper methods to create mock resources + private Resource[] createMockResources(Set languages) { + return languages.stream() + .map(lang -> createMockResource("messages_" + lang + ".properties")) + .toArray(Resource[]::new); + } + @Test - void testGetSupportedLanguages_FilteringNonMatchingFiles() throws IOException { + void testGetSupportedLanguages_FilteringNonMatchingFiles() { // Setup with some valid and some invalid filenames - Resource[] mixedResources = - new Resource[] { - createMockResource("messages_en_US.properties"), - createMockResource( - "messages_en_GB.properties"), // Explicitly add en_GB resource - createMockResource("messages_fr_FR.properties"), - createMockResource("not_a_messages_file.properties"), - createMockResource("messages_.properties"), // Invalid format - createMockResource(null) // Null filename - }; + Resource[] mixedResources = { + createMockResource("messages_en_US.properties"), + createMockResource("messages_en_GB.properties"), // Explicitly add en_GB resource + createMockResource("messages_fr_FR.properties"), + createMockResource("not_a_messages_file.properties"), + createMockResource("messages_.properties"), // Invalid format + createMockResource(null) // Null filename + }; ((LanguageServiceForTest) languageService).setMockResources(mixedResources); when(applicationProperties.getUi().getLanguages()).thenReturn(Collections.emptyList()); @@ -132,19 +141,6 @@ class LanguageServiceTest { // language codes } - // Helper methods to create mock resources - private Resource[] createMockResources(Set languages) { - return languages.stream() - .map(lang -> createMockResource("messages_" + lang + ".properties")) - .toArray(Resource[]::new); - } - - private Resource createMockResource(String filename) { - Resource mockResource = mock(Resource.class); - when(mockResource.getFilename()).thenReturn(filename); - return mockResource; - } - // Test subclass that allows us to control the resource resolver private static class LanguageServiceForTest extends LanguageService { private Resource[] mockResources; diff --git a/app/core/src/test/java/stirling/software/SPDF/service/PdfImageRemovalServiceTest.java b/app/core/src/test/java/stirling/software/SPDF/service/PdfImageRemovalServiceTest.java index be19e9c2f..f237f2f0f 100644 --- a/app/core/src/test/java/stirling/software/SPDF/service/PdfImageRemovalServiceTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/service/PdfImageRemovalServiceTest.java @@ -24,6 +24,24 @@ class PdfImageRemovalServiceTest { service = new PdfImageRemovalService(); } + // Helper method for matching COSName in verification + private static COSName eq(final COSName value) { + return Mockito.argThat( + new org.mockito.ArgumentMatcher<>() { + @Override + public boolean matches(COSName argument) { + if (argument == null && value == null) return true; + if (argument == null || value == null) return false; + return argument.getName().equals(value.getName()); + } + + @Override + public String toString() { + return "eq(" + (value != null ? value.getName() : "null") + ")"; + } + }); + } + @Test void testRemoveImagesFromPdf_WithImages() throws IOException { // Mock PDF document and its components @@ -54,7 +72,7 @@ class PdfImageRemovalServiceTest { when(resources.isImageXObject(nonImg)).thenReturn(false); // Execute the method - PDDocument result = service.removeImagesFromPdf(document); + service.removeImagesFromPdf(document); // Verify that images were removed verify(resources, times(1)).put(eq(img1), Mockito.isNull()); @@ -83,7 +101,7 @@ class PdfImageRemovalServiceTest { when(resources.getXObjectNames()).thenReturn(emptyList); // Execute the method - PDDocument result = service.removeImagesFromPdf(document); + service.removeImagesFromPdf(document); // Verify that no modifications were made verify(resources, never()).put(any(COSName.class), any(PDXObject.class)); @@ -119,28 +137,10 @@ class PdfImageRemovalServiceTest { when(resources2.isImageXObject(img2)).thenReturn(true); // Execute the method - PDDocument result = service.removeImagesFromPdf(document); + service.removeImagesFromPdf(document); // Verify that images were removed from both pages verify(resources1, times(1)).put(eq(img1), Mockito.isNull()); verify(resources2, times(1)).put(eq(img2), Mockito.isNull()); } - - // Helper method for matching COSName in verification - private static COSName eq(final COSName value) { - return Mockito.argThat( - new org.mockito.ArgumentMatcher() { - @Override - public boolean matches(COSName argument) { - if (argument == null && value == null) return true; - if (argument == null || value == null) return false; - return argument.getName().equals(value.getName()); - } - - @Override - public String toString() { - return "eq(" + (value != null ? value.getName() : "null") + ")"; - } - }); - } } diff --git a/app/core/src/test/java/stirling/software/SPDF/service/PdfMetadataServiceBasicTest.java b/app/core/src/test/java/stirling/software/SPDF/service/PdfMetadataServiceBasicTest.java index ffdaf6e2f..c4713fb13 100644 --- a/app/core/src/test/java/stirling/software/SPDF/service/PdfMetadataServiceBasicTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/service/PdfMetadataServiceBasicTest.java @@ -26,19 +26,17 @@ import stirling.software.common.service.UserServiceInterface; class PdfMetadataServiceBasicTest { - private ApplicationProperties applicationProperties; - private UserServiceInterface userService; private PdfMetadataService pdfMetadataService; private final String STIRLING_PDF_LABEL = "Stirling PDF"; @BeforeEach void setUp() { // Set up mocks for application properties' nested objects - applicationProperties = mock(ApplicationProperties.class); + ApplicationProperties applicationProperties = mock(ApplicationProperties.class); Premium premium = mock(Premium.class); ProFeatures proFeatures = mock(ProFeatures.class); CustomMetadata customMetadata = mock(CustomMetadata.class); - userService = mock(UserServiceInterface.class); + UserServiceInterface userService = mock(UserServiceInterface.class); when(applicationProperties.getPremium()).thenReturn(premium); when(premium.getProFeatures()).thenReturn(proFeatures); diff --git a/app/core/src/test/java/stirling/software/SPDF/service/SignatureServiceTest.java b/app/core/src/test/java/stirling/software/SPDF/service/SignatureServiceTest.java index 5161e82ea..8f072e1fe 100644 --- a/app/core/src/test/java/stirling/software/SPDF/service/SignatureServiceTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/service/SignatureServiceTest.java @@ -24,16 +24,14 @@ class SignatureServiceTest { @TempDir Path tempDir; private SignatureService signatureService; - private Path personalSignatureFolder; - private Path sharedSignatureFolder; - private final String ALL_USERS_FOLDER = "ALL_USERS"; private final String TEST_USER = "testUser"; @BeforeEach void setUp() throws IOException { // Set up our test directory structure - personalSignatureFolder = tempDir.resolve(TEST_USER); - sharedSignatureFolder = tempDir.resolve(ALL_USERS_FOLDER); + Path personalSignatureFolder = tempDir.resolve(TEST_USER); + String ALL_USERS_FOLDER = "ALL_USERS"; + Path sharedSignatureFolder = tempDir.resolve(ALL_USERS_FOLDER); Files.createDirectories(personalSignatureFolder); Files.createDirectories(sharedSignatureFolder); @@ -239,7 +237,7 @@ class SignatureServiceTest { } @Test - void testGetAvailableSignatures_EmptyUsername() throws IOException { + void testGetAvailableSignatures_EmptyUsername() { // Mock static method for each test try (MockedStatic mockedConfig = mockStatic(InstallationPathConfig.class)) { @@ -265,7 +263,7 @@ class SignatureServiceTest { } @Test - void testGetAvailableSignatures_NonExistentUser() throws IOException { + void testGetAvailableSignatures_NonExistentUser() { // Mock static method for each test try (MockedStatic mockedConfig = mockStatic(InstallationPathConfig.class)) { diff --git a/app/core/src/test/java/stirling/software/common/controller/JobControllerTest.java b/app/core/src/test/java/stirling/software/common/controller/JobControllerTest.java index 1fa23b2cf..5a802c53f 100644 --- a/app/core/src/test/java/stirling/software/common/controller/JobControllerTest.java +++ b/app/core/src/test/java/stirling/software/common/controller/JobControllerTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import java.util.Map; +import java.util.Objects; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -80,7 +81,7 @@ class JobControllerTest { @SuppressWarnings("unchecked") Map responseBody = (Map) response.getBody(); - assertEquals(mockResult, responseBody.get("jobResult")); + assertEquals(mockResult, Objects.requireNonNull(responseBody).get("jobResult")); @SuppressWarnings("unchecked") Map queueInfo = (Map) responseBody.get("queueInfo"); @@ -145,7 +146,8 @@ class JobControllerTest { assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(contentType, response.getHeaders().getFirst("Content-Type")); assertTrue( - response.getHeaders().getFirst("Content-Disposition").contains(originalFileName)); + Objects.requireNonNull(response.getHeaders().getFirst("Content-Disposition")) + .contains(originalFileName)); assertEquals(fileContent, response.getBody()); } @@ -166,7 +168,7 @@ class JobControllerTest { // Assert assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); - assertTrue(response.getBody().toString().contains(errorMessage)); + assertTrue(Objects.requireNonNull(response.getBody()).toString().contains(errorMessage)); } @Test @@ -185,7 +187,7 @@ class JobControllerTest { // Assert assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); - assertTrue(response.getBody().toString().contains("not complete")); + assertTrue(Objects.requireNonNull(response.getBody()).toString().contains("not complete")); } @Test @@ -221,7 +223,10 @@ class JobControllerTest { // Assert assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); - assertTrue(response.getBody().toString().contains("Error retrieving file")); + assertTrue( + Objects.requireNonNull(response.getBody()) + .toString() + .contains("Error retrieving file")); } /* @@ -285,7 +290,8 @@ class JobControllerTest { @SuppressWarnings("unchecked") Map responseBody = (Map) response.getBody(); - assertEquals("Job cancelled successfully", responseBody.get("message")); + assertEquals( + "Job cancelled successfully", Objects.requireNonNull(responseBody).get("message")); assertTrue((Boolean) responseBody.get("wasQueued")); assertEquals(2, responseBody.get("queuePosition")); @@ -317,7 +323,8 @@ class JobControllerTest { @SuppressWarnings("unchecked") Map responseBody = (Map) response.getBody(); - assertEquals("Job cancelled successfully", responseBody.get("message")); + assertEquals( + "Job cancelled successfully", Objects.requireNonNull(responseBody).get("message")); assertFalse((Boolean) responseBody.get("wasQueued")); assertEquals("n/a", responseBody.get("queuePosition")); @@ -369,7 +376,9 @@ class JobControllerTest { @SuppressWarnings("unchecked") Map responseBody = (Map) response.getBody(); - assertEquals("Cannot cancel job that is already complete", responseBody.get("message")); + assertEquals( + "Cannot cancel job that is already complete", + Objects.requireNonNull(responseBody).get("message")); } @Test @@ -391,7 +400,9 @@ class JobControllerTest { @SuppressWarnings("unchecked") Map responseBody = (Map) response.getBody(); - assertEquals("You are not authorized to cancel this job", responseBody.get("message")); + assertEquals( + "You are not authorized to cancel this job", + Objects.requireNonNull(responseBody).get("message")); // Verify no cancellation attempts were made verify(jobQueue, never()).isJobQueued(anyString()); diff --git a/app/proprietary/src/test/java/stirling/software/proprietary/security/CustomLogoutSuccessHandlerTest.java b/app/proprietary/src/test/java/stirling/software/proprietary/security/CustomLogoutSuccessHandlerTest.java index 7a4076260..08f96af4e 100644 --- a/app/proprietary/src/test/java/stirling/software/proprietary/security/CustomLogoutSuccessHandlerTest.java +++ b/app/proprietary/src/test/java/stirling/software/proprietary/security/CustomLogoutSuccessHandlerTest.java @@ -14,7 +14,6 @@ import org.springframework.security.oauth2.client.authentication.OAuth2Authentic import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import stirling.software.common.configuration.AppConfig; import stirling.software.common.model.ApplicationProperties; import stirling.software.proprietary.security.service.JwtServiceInterface; @@ -23,8 +22,6 @@ class CustomLogoutSuccessHandlerTest { @Mock private ApplicationProperties.Security securityProperties; - @Mock private AppConfig appConfig; - @Mock private JwtServiceInterface jwtService; @InjectMocks private CustomLogoutSuccessHandler customLogoutSuccessHandler; diff --git a/app/proprietary/src/test/java/stirling/software/proprietary/security/configuration/ee/LicenseKeyCheckerTest.java b/app/proprietary/src/test/java/stirling/software/proprietary/security/configuration/ee/LicenseKeyCheckerTest.java index 4a6e7ad65..26f137b73 100644 --- a/app/proprietary/src/test/java/stirling/software/proprietary/security/configuration/ee/LicenseKeyCheckerTest.java +++ b/app/proprietary/src/test/java/stirling/software/proprietary/security/configuration/ee/LicenseKeyCheckerTest.java @@ -55,7 +55,7 @@ class LicenseKeyCheckerTest { ApplicationProperties props = new ApplicationProperties(); props.getPremium().setEnabled(true); - props.getPremium().setKey("file:" + file.toString()); + props.getPremium().setKey("file:" + file); when(verifier.verifyLicense("filekey")).thenReturn(License.ENTERPRISE); LicenseKeyChecker checker = new LicenseKeyChecker(verifier, props); @@ -69,7 +69,7 @@ class LicenseKeyCheckerTest { Path file = temp.resolve("missing.txt"); ApplicationProperties props = new ApplicationProperties(); props.getPremium().setEnabled(true); - props.getPremium().setKey("file:" + file.toString()); + props.getPremium().setKey("file:" + file); LicenseKeyChecker checker = new LicenseKeyChecker(verifier, props); diff --git a/app/proprietary/src/test/java/stirling/software/proprietary/security/filter/JwtAuthenticationFilterTest.java b/app/proprietary/src/test/java/stirling/software/proprietary/security/filter/JwtAuthenticationFilterTest.java index d3f484486..916bd3721 100644 --- a/app/proprietary/src/test/java/stirling/software/proprietary/security/filter/JwtAuthenticationFilterTest.java +++ b/app/proprietary/src/test/java/stirling/software/proprietary/security/filter/JwtAuthenticationFilterTest.java @@ -35,11 +35,9 @@ import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import stirling.software.common.model.ApplicationProperties; import stirling.software.proprietary.security.model.exception.AuthenticationFailureException; import stirling.software.proprietary.security.service.CustomUserDetailsService; import stirling.software.proprietary.security.service.JwtServiceInterface; -import stirling.software.proprietary.security.service.UserService; @Disabled @ExtendWith(MockitoExtension.class) @@ -49,10 +47,6 @@ class JwtAuthenticationFilterTest { @Mock private CustomUserDetailsService userDetailsService; - @Mock private UserService userService; - - @Mock private ApplicationProperties.Security securityProperties; - @Mock private HttpServletRequest request; @Mock private HttpServletResponse response; diff --git a/app/proprietary/src/test/java/stirling/software/proprietary/security/saml2/JwtSaml2AuthenticationRequestRepositoryTest.java b/app/proprietary/src/test/java/stirling/software/proprietary/security/saml2/JwtSaml2AuthenticationRequestRepositoryTest.java index 1aa083cc0..8eac18d04 100644 --- a/app/proprietary/src/test/java/stirling/software/proprietary/security/saml2/JwtSaml2AuthenticationRequestRepositoryTest.java +++ b/app/proprietary/src/test/java/stirling/software/proprietary/security/saml2/JwtSaml2AuthenticationRequestRepositoryTest.java @@ -62,7 +62,6 @@ class JwtSaml2AuthenticationRequestRepositoryTest { String id = "testId"; String relayState = "testRelayState"; String authnRequestUri = "example.com/authnRequest"; - Map claims = Map.of(); String samlRequest = "testSamlRequest"; String relyingPartyRegistrationId = "stirling-pdf"; diff --git a/app/proprietary/src/test/java/stirling/software/proprietary/security/service/EmailServiceTest.java b/app/proprietary/src/test/java/stirling/software/proprietary/security/service/EmailServiceTest.java index b1cd5a8dd..8ca8208c9 100644 --- a/app/proprietary/src/test/java/stirling/software/proprietary/security/service/EmailServiceTest.java +++ b/app/proprietary/src/test/java/stirling/software/proprietary/security/service/EmailServiceTest.java @@ -63,7 +63,7 @@ public class EmailServiceTest { } @Test - void testSendEmailWithAttachmentThrowsExceptionForMissingFilename() throws MessagingException { + void testSendEmailWithAttachmentThrowsExceptionForMissingFilename() { Email email = new Email(); email.setTo("test@example.com"); email.setSubject("Test Email"); @@ -82,8 +82,7 @@ public class EmailServiceTest { } @Test - void testSendEmailWithAttachmentThrowsExceptionForMissingFilenameNull() - throws MessagingException { + void testSendEmailWithAttachmentThrowsExceptionForMissingFilenameNull() { Email email = new Email(); email.setTo("test@example.com"); email.setSubject("Test Email"); @@ -102,7 +101,7 @@ public class EmailServiceTest { } @Test - void testSendEmailWithAttachmentThrowsExceptionForMissingFile() throws MessagingException { + void testSendEmailWithAttachmentThrowsExceptionForMissingFile() { Email email = new Email(); email.setTo("test@example.com"); email.setSubject("Test Email"); @@ -120,7 +119,7 @@ public class EmailServiceTest { } @Test - void testSendEmailWithAttachmentThrowsExceptionForMissingFileNull() throws MessagingException { + void testSendEmailWithAttachmentThrowsExceptionForMissingFileNull() { Email email = new Email(); email.setTo("test@example.com"); email.setSubject("Test Email"); @@ -136,8 +135,7 @@ public class EmailServiceTest { } @Test - void testSendEmailWithAttachmentThrowsExceptionForInvalidAddressNull() - throws MessagingException { + void testSendEmailWithAttachmentThrowsExceptionForInvalidAddressNull() { Email email = new Email(); email.setTo(null); // Invalid address email.setSubject("Test Email"); @@ -153,8 +151,7 @@ public class EmailServiceTest { } @Test - void testSendEmailWithAttachmentThrowsExceptionForInvalidAddressEmpty() - throws MessagingException { + void testSendEmailWithAttachmentThrowsExceptionForInvalidAddressEmpty() { Email email = new Email(); email.setTo(""); // Invalid address email.setSubject("Test Email"); diff --git a/app/proprietary/src/test/java/stirling/software/proprietary/security/service/JwtServiceTest.java b/app/proprietary/src/test/java/stirling/software/proprietary/security/service/JwtServiceTest.java index 6f9af4c54..09229b9f6 100644 --- a/app/proprietary/src/test/java/stirling/software/proprietary/security/service/JwtServiceTest.java +++ b/app/proprietary/src/test/java/stirling/software/proprietary/security/service/JwtServiceTest.java @@ -138,9 +138,7 @@ class JwtServiceTest { assertThrows( AuthenticationFailureException.class, - () -> { - jwtService.validateToken("invalid-token"); - }); + () -> jwtService.validateToken("invalid-token")); } @Test @@ -152,9 +150,7 @@ class JwtServiceTest { AuthenticationFailureException exception = assertThrows( AuthenticationFailureException.class, - () -> { - jwtService.validateToken("malformed.token"); - }); + () -> jwtService.validateToken("malformed.token")); assertTrue(exception.getMessage().contains("Invalid")); } @@ -167,10 +163,7 @@ class JwtServiceTest { AuthenticationFailureException exception = assertThrows( - AuthenticationFailureException.class, - () -> { - jwtService.validateToken(""); - }); + AuthenticationFailureException.class, () -> jwtService.validateToken("")); assertTrue( exception.getMessage().contains("Claims are empty") @@ -296,7 +289,7 @@ class JwtServiceTest { } @Test - void testGenerateTokenWithKeyId() throws Exception { + void testGenerateTokenWithKeyId() { String username = "testuser"; Map claims = new HashMap<>(); diff --git a/app/proprietary/src/test/java/stirling/software/proprietary/security/service/KeyPersistenceServiceInterfaceTest.java b/app/proprietary/src/test/java/stirling/software/proprietary/security/service/KeyPersistenceServiceInterfaceTest.java index 3852a2600..56e145634 100644 --- a/app/proprietary/src/test/java/stirling/software/proprietary/security/service/KeyPersistenceServiceInterfaceTest.java +++ b/app/proprietary/src/test/java/stirling/software/proprietary/security/service/KeyPersistenceServiceInterfaceTest.java @@ -7,7 +7,6 @@ import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.when; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.security.KeyPair; @@ -84,7 +83,7 @@ class KeyPersistenceServiceInterfaceTest { String privateKeyBase64 = Base64.getEncoder().encodeToString(testKeyPair.getPrivate().getEncoded()); - JwtVerificationKey existingKey = new JwtVerificationKey(keyId, publicKeyBase64); + new JwtVerificationKey(keyId, publicKeyBase64); Path keyFile = tempDir.resolve(keyId + ".key"); Files.writeString(keyFile, privateKeyBase64); @@ -129,6 +128,7 @@ class KeyPersistenceServiceInterfaceTest { .getDeclaredField("verifyingKeyCache") .setAccessible(true); var cache = cacheManager.getCache("verifyingKeys"); + assertNotNull(cache); cache.put(keyId, signingKey); Optional result = keyPersistenceService.getKeyPair(keyId); @@ -174,7 +174,7 @@ class KeyPersistenceServiceInterfaceTest { } @Test - void testInitializeKeystoreCreatesDirectory() throws IOException { + void testInitializeKeystoreCreatesDirectory() { try (MockedStatic mockedStatic = mockStatic(InstallationPathConfig.class)) { mockedStatic @@ -189,12 +189,12 @@ class KeyPersistenceServiceInterfaceTest { } @Test - void testLoadExistingKeypairWithMissingPrivateKeyFile() throws Exception { + void testLoadExistingKeypairWithMissingPrivateKeyFile() { String keyId = "test-key-missing-file"; String publicKeyBase64 = Base64.getEncoder().encodeToString(testKeyPair.getPublic().getEncoded()); - JwtVerificationKey existingKey = new JwtVerificationKey(keyId, publicKeyBase64); + new JwtVerificationKey(keyId, publicKeyBase64); try (MockedStatic mockedStatic = mockStatic(InstallationPathConfig.class)) { diff --git a/app/proprietary/src/test/java/stirling/software/proprietary/security/service/UserServiceTest.java b/app/proprietary/src/test/java/stirling/software/proprietary/security/service/UserServiceTest.java index 667b9c408..aa742c0e4 100644 --- a/app/proprietary/src/test/java/stirling/software/proprietary/security/service/UserServiceTest.java +++ b/app/proprietary/src/test/java/stirling/software/proprietary/security/service/UserServiceTest.java @@ -133,10 +133,9 @@ class UserServiceTest { AuthenticationType authType = AuthenticationType.WEB; // When & Then - IllegalArgumentException exception = - assertThrows( - IllegalArgumentException.class, - () -> userService.saveUser(invalidUsername, authType)); + assertThrows( + IllegalArgumentException.class, + () -> userService.saveUser(invalidUsername, authType)); verify(userRepository, never()).save(any(User.class)); verify(databaseService, never()).exportDatabase(); @@ -208,10 +207,9 @@ class UserServiceTest { AuthenticationType authType = AuthenticationType.WEB; // When & Then - IllegalArgumentException exception = - assertThrows( - IllegalArgumentException.class, - () -> userService.saveUser(reservedUsername, authType)); + assertThrows( + IllegalArgumentException.class, + () -> userService.saveUser(reservedUsername, authType)); verify(userRepository, never()).save(any(User.class)); verify(databaseService, never()).exportDatabase(); @@ -224,10 +222,9 @@ class UserServiceTest { AuthenticationType authType = AuthenticationType.WEB; // When & Then - IllegalArgumentException exception = - assertThrows( - IllegalArgumentException.class, - () -> userService.saveUser(anonymousUsername, authType)); + assertThrows( + IllegalArgumentException.class, + () -> userService.saveUser(anonymousUsername, authType)); verify(userRepository, never()).save(any(User.class)); verify(databaseService, never()).exportDatabase();