Skip to content

Commit a7900ae

Browse files
authored
refactor(tests): replaced redundant setups, simplified exception handling, and optimized code readability. (Stirling-Tools#4710)
# Description of Changes This pull request primarily refactors and improves the test code across several modules, focusing on modernization, simplification, and consistency of assertions and test setup. The changes include formatting updates and improvements to utility methods. These updates help make the tests easier to maintain and read, and ensure they use current best practices. **Test code modernization and assertion improvements:** * Replaced legacy assertion methods such as `assertTrue(x instanceof Y)` with more specific `assertInstanceOf` assertions in multiple test files, improving clarity and type safety. * Updated exception assertion checks to use `assertInstanceOf` for error types instead of `assertTrue`, ensuring more precise test validation. * Refactored test setup in `ResourceMonitorTest` to use `final` for `AtomicReference` fields, clarifying intent and thread safety. * Changed some test method signatures to remove unnecessary `throws Exception` clauses, simplifying the test code. **Test code simplification and cleanup:** * Removed unused mock fields and simplified array initializations in `AutoJobPostMappingIntegrationTest`, streamlining test setup and reducing clutter. * Updated YAML string initialization in `ApplicationPropertiesDynamicYamlPropertySourceTest` to use Java text blocks for improved readability. * Improved null handling in assertions for collection validity checks. * Updated byte array encoding to use `StandardCharsets.UTF_8` for reliability and clarity. **PDF document factory test refactoring:** * Refactored `CustomPDFDocumentFactoryTest` to move helper methods for inflating PDFs and writing temp files to the top of the class, and restructured parameterized tests for better organization and maintainability. <!-- Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --> --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --------- Signed-off-by: Balázs Szücs <[email protected]>
1 parent 83922c4 commit a7900ae

File tree

46 files changed

+748
-811
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+748
-811
lines changed

app/common/src/test/java/stirling/software/common/annotations/AutoJobPostMappingIntegrationTest.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131
import stirling.software.common.model.api.PDFFile;
3232
import stirling.software.common.service.FileStorage;
3333
import stirling.software.common.service.JobExecutorService;
34-
import stirling.software.common.service.JobQueue;
35-
import stirling.software.common.service.ResourceMonitor;
3634

3735
@ExtendWith(MockitoExtension.class)
3836
class AutoJobPostMappingIntegrationTest {
@@ -45,10 +43,6 @@ class AutoJobPostMappingIntegrationTest {
4543

4644
@Mock private FileStorage fileStorage;
4745

48-
@Mock private ResourceMonitor resourceMonitor;
49-
50-
@Mock private JobQueue jobQueue;
51-
5246
@BeforeEach
5347
void setUp() {
5448
autoJobAspect = new AutoJobAspect(jobExecutorService, request, fileStorage);
@@ -73,7 +67,7 @@ void shouldExecuteWithCustomParameters() throws Throwable {
7367
// Given
7468
PDFFile pdfFile = new PDFFile();
7569
pdfFile.setFileId("test-file-id");
76-
Object[] args = new Object[] {pdfFile};
70+
Object[] args = {pdfFile};
7771

7872
when(joinPoint.getArgs()).thenReturn(args);
7973
when(request.getParameter("async")).thenReturn("true");
@@ -153,7 +147,7 @@ void shouldHandlePDFFileWithAsyncRequests() throws Throwable {
153147
// Given
154148
PDFFile pdfFile = new PDFFile();
155149
pdfFile.setFileInput(mock(MultipartFile.class));
156-
Object[] args = new Object[] {pdfFile};
150+
Object[] args = {pdfFile};
157151

158152
when(joinPoint.getArgs()).thenReturn(args);
159153
when(request.getParameter("async")).thenReturn("true");

app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesDynamicYamlPropertySourceTest.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ class ApplicationPropertiesDynamicYamlPropertySourceTest {
2020
void loads_yaml_into_environment() throws Exception {
2121
// YAML-Config in Temp-Datei schreiben
2222
String yaml =
23-
""
24-
+ "ui:\n"
25-
+ " appName: \"My App\"\n"
26-
+ "system:\n"
27-
+ " enableAnalytics: true\n";
23+
"""
24+
\
25+
ui:
26+
appName: "My App"
27+
system:
28+
enableAnalytics: true
29+
""";
2830
Path tmp = Files.createTempFile("spdf-settings-", ".yml");
2931
Files.writeString(tmp, yaml);
3032

@@ -44,7 +46,7 @@ void loads_yaml_into_environment() throws Exception {
4446
}
4547

4648
@Test
47-
void throws_when_settings_file_missing() throws Exception {
49+
void throws_when_settings_file_missing() {
4850
String missing = "/path/does/not/exist/spdf.yml";
4951
try (MockedStatic<InstallationPathConfig> mocked =
5052
Mockito.mockStatic(InstallationPathConfig.class)) {

app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesLogicTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ void collection_isValid_handles_null_and_empty() {
232232
Collection<String> nullColl = null;
233233
Collection<String> empty = List.of();
234234

235-
assertFalse(oauth2.isValid(nullColl, "scopes"));
235+
assertFalse(oauth2.isValid((Collection<String>) null, "scopes"));
236236
assertFalse(oauth2.isValid(empty, "scopes"));
237237
}
238238

app/common/src/test/java/stirling/software/common/model/ApplicationPropertiesSaml2HttpTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void spCert_else_branch_returns_FileSystemResource_for_filesystem_path() throws
6161
Resource r = s.getSpCert();
6262

6363
assertNotNull(r);
64-
assertTrue(r instanceof FileSystemResource, "Expected FileSystemResource for FS path");
64+
assertInstanceOf(FileSystemResource.class, r, "Expected FileSystemResource for FS path");
6565
assertTrue(r.exists(), "Temp file should exist");
6666
}
6767

@@ -75,7 +75,7 @@ void idpCert_else_branch_returns_FileSystemResource_even_if_missing() {
7575
Resource r = s.getIdpCert();
7676

7777
assertNotNull(r);
78-
assertTrue(r instanceof FileSystemResource, "Expected FileSystemResource for FS path");
78+
assertInstanceOf(FileSystemResource.class, r, "Expected FileSystemResource for FS path");
7979
assertFalse(r.exists(), "Resource should not exist for missing file");
8080
}
8181
}

app/common/src/test/java/stirling/software/common/model/InputStreamTemplateResourceTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.io.Reader;
88
import java.lang.reflect.Field;
99
import java.lang.reflect.Modifier;
10+
import java.nio.charset.StandardCharsets;
1011
import java.util.Arrays;
1112

1213
import org.junit.jupiter.api.Test;
@@ -47,7 +48,7 @@ void noSetterMethodsPresent() {
4748
@Test
4849
void readerReturnsCorrectContent() throws Exception {
4950
String content = "Hello, world!";
50-
InputStream is = new ByteArrayInputStream(content.getBytes("UTF-8"));
51+
InputStream is = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
5152
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
5253

5354
try (Reader reader = resource.reader()) {

app/common/src/test/java/stirling/software/common/service/CustomPDFDocumentFactoryTest.java

Lines changed: 43 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -41,31 +41,53 @@ void setup() throws IOException {
4141
}
4242
}
4343

44+
private static byte[] inflatePdf(byte[] input, int sizeInMB) throws IOException {
45+
try (PDDocument doc = Loader.loadPDF(input)) {
46+
byte[] largeData = new byte[sizeInMB * 1024 * 1024];
47+
Arrays.fill(largeData, (byte) 'A');
48+
49+
PDStream stream = new PDStream(doc, new ByteArrayInputStream(largeData));
50+
stream.getCOSObject().setItem(COSName.TYPE, COSName.XOBJECT);
51+
stream.getCOSObject().setItem(COSName.SUBTYPE, COSName.IMAGE);
52+
53+
doc.getDocumentCatalog()
54+
.getCOSObject()
55+
.setItem(COSName.getPDFName("DummyBigStream"), stream.getCOSObject());
56+
57+
ByteArrayOutputStream out = new ByteArrayOutputStream();
58+
doc.save(out);
59+
return out.toByteArray();
60+
}
61+
}
62+
63+
private static File writeTempFile(byte[] content) throws IOException {
64+
File file = Files.createTempFile("pdf-test-", ".pdf").toFile();
65+
Files.write(file.toPath(), content);
66+
return file;
67+
}
68+
4469
@ParameterizedTest
4570
@CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"})
4671
void testStrategy_FileInput(int sizeMB, StrategyType expected) throws IOException {
4772
File file = writeTempFile(inflatePdf(basePdfBytes, sizeMB));
48-
try (PDDocument doc = factory.load(file)) {
49-
Assertions.assertEquals(expected, factory.lastStrategyUsed);
50-
}
73+
factory.load(file);
74+
Assertions.assertEquals(expected, factory.lastStrategyUsed);
5175
}
5276

5377
@ParameterizedTest
5478
@CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"})
5579
void testStrategy_ByteArray(int sizeMB, StrategyType expected) throws IOException {
5680
byte[] inflated = inflatePdf(basePdfBytes, sizeMB);
57-
try (PDDocument doc = factory.load(inflated)) {
58-
Assertions.assertEquals(expected, factory.lastStrategyUsed);
59-
}
81+
factory.load(inflated);
82+
Assertions.assertEquals(expected, factory.lastStrategyUsed);
6083
}
6184

6285
@ParameterizedTest
6386
@CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"})
6487
void testStrategy_InputStream(int sizeMB, StrategyType expected) throws IOException {
6588
byte[] inflated = inflatePdf(basePdfBytes, sizeMB);
66-
try (PDDocument doc = factory.load(new ByteArrayInputStream(inflated))) {
67-
Assertions.assertEquals(expected, factory.lastStrategyUsed);
68-
}
89+
factory.load(new ByteArrayInputStream(inflated));
90+
Assertions.assertEquals(expected, factory.lastStrategyUsed);
6991
}
7092

7193
@ParameterizedTest
@@ -74,41 +96,8 @@ void testStrategy_MultipartFile(int sizeMB, StrategyType expected) throws IOExce
7496
byte[] inflated = inflatePdf(basePdfBytes, sizeMB);
7597
MockMultipartFile multipart =
7698
new MockMultipartFile("file", "doc.pdf", MediaType.APPLICATION_PDF_VALUE, inflated);
77-
try (PDDocument doc = factory.load(multipart)) {
78-
Assertions.assertEquals(expected, factory.lastStrategyUsed);
79-
}
80-
}
81-
82-
@ParameterizedTest
83-
@CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"})
84-
void testStrategy_PDFFile(int sizeMB, StrategyType expected) throws IOException {
85-
byte[] inflated = inflatePdf(basePdfBytes, sizeMB);
86-
MockMultipartFile multipart =
87-
new MockMultipartFile("file", "doc.pdf", MediaType.APPLICATION_PDF_VALUE, inflated);
88-
PDFFile pdfFile = new PDFFile();
89-
pdfFile.setFileInput(multipart);
90-
try (PDDocument doc = factory.load(pdfFile)) {
91-
Assertions.assertEquals(expected, factory.lastStrategyUsed);
92-
}
93-
}
94-
95-
private byte[] inflatePdf(byte[] input, int sizeInMB) throws IOException {
96-
try (PDDocument doc = Loader.loadPDF(input)) {
97-
byte[] largeData = new byte[sizeInMB * 1024 * 1024];
98-
Arrays.fill(largeData, (byte) 'A');
99-
100-
PDStream stream = new PDStream(doc, new ByteArrayInputStream(largeData));
101-
stream.getCOSObject().setItem(COSName.TYPE, COSName.XOBJECT);
102-
stream.getCOSObject().setItem(COSName.SUBTYPE, COSName.IMAGE);
103-
104-
doc.getDocumentCatalog()
105-
.getCOSObject()
106-
.setItem(COSName.getPDFName("DummyBigStream"), stream.getCOSObject());
107-
108-
ByteArrayOutputStream out = new ByteArrayOutputStream();
109-
doc.save(out);
110-
return out.toByteArray();
111-
}
99+
factory.load(multipart);
100+
Assertions.assertEquals(expected, factory.lastStrategyUsed);
112101
}
113102

114103
@Test
@@ -210,10 +199,16 @@ void testCreateNewBytesBasedOnOldDocument() throws IOException {
210199
assertTrue(newBytes.length > 0);
211200
}
212201

213-
private File writeTempFile(byte[] content) throws IOException {
214-
File file = Files.createTempFile("pdf-test-", ".pdf").toFile();
215-
Files.write(file.toPath(), content);
216-
return file;
202+
@ParameterizedTest
203+
@CsvSource({"5,MEMORY_ONLY", "20,MIXED", "60,TEMP_FILE"})
204+
void testStrategy_PDFFile(int sizeMB, StrategyType expected) throws IOException {
205+
byte[] inflated = inflatePdf(basePdfBytes, sizeMB);
206+
MockMultipartFile multipart =
207+
new MockMultipartFile("file", "doc.pdf", MediaType.APPLICATION_PDF_VALUE, inflated);
208+
PDFFile pdfFile = new PDFFile();
209+
pdfFile.setFileInput(multipart);
210+
factory.load(pdfFile);
211+
Assertions.assertEquals(expected, factory.lastStrategyUsed);
217212
}
218213

219214
@BeforeEach

app/common/src/test/java/stirling/software/common/service/JobExecutorServiceTest.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package stirling.software.common.service;
22

3-
import static org.junit.jupiter.api.Assertions.assertEquals;
4-
import static org.junit.jupiter.api.Assertions.assertNotNull;
5-
import static org.junit.jupiter.api.Assertions.assertTrue;
3+
import static org.junit.jupiter.api.Assertions.*;
64
import static org.mockito.ArgumentMatchers.any;
75
import static org.mockito.ArgumentMatchers.anyLong;
86
import static org.mockito.ArgumentMatchers.anyString;
@@ -63,7 +61,7 @@ void setUp() {
6361
}
6462

6563
@Test
66-
void shouldRunSyncJobSuccessfully() throws Exception {
64+
void shouldRunSyncJobSuccessfully() {
6765
// Given
6866
Supplier<Object> work = () -> "test-result";
6967

@@ -79,7 +77,7 @@ void shouldRunSyncJobSuccessfully() throws Exception {
7977
}
8078

8179
@Test
82-
void shouldRunAsyncJobSuccessfully() throws Exception {
80+
void shouldRunAsyncJobSuccessfully() {
8381
// Given
8482
Supplier<Object> work = () -> "test-result";
8583

@@ -88,7 +86,7 @@ void shouldRunAsyncJobSuccessfully() throws Exception {
8886

8987
// Then
9088
assertEquals(HttpStatus.OK, response.getStatusCode());
91-
assertTrue(response.getBody() instanceof JobResponse);
89+
assertInstanceOf(JobResponse.class, response.getBody());
9290
JobResponse<?> jobResponse = (JobResponse<?>) response.getBody();
9391
assertTrue(jobResponse.isAsync());
9492
assertNotNull(jobResponse.getJobId());
@@ -113,6 +111,7 @@ void shouldHandleSyncJobError() {
113111

114112
@SuppressWarnings("unchecked")
115113
Map<String, String> errorMap = (Map<String, String>) response.getBody();
114+
assertNotNull(errorMap);
116115
assertEquals("Job failed: Test error", errorMap.get("error"));
117116
}
118117

@@ -133,7 +132,7 @@ void shouldQueueJobWhenResourcesLimited() {
133132

134133
// Then
135134
assertEquals(HttpStatus.OK, response.getStatusCode());
136-
assertTrue(response.getBody() instanceof JobResponse);
135+
assertInstanceOf(JobResponse.class, response.getBody());
137136

138137
// Verify job was queued
139138
verify(jobQueue).queueJob(anyString(), eq(80), any(), eq(5000L));
@@ -186,7 +185,7 @@ void shouldHandleTimeout() throws Exception {
186185
try {
187186
executeMethod.invoke(jobExecutorService, work, 1L); // Very short timeout
188187
} catch (Exception e) {
189-
assertTrue(e.getCause() instanceof TimeoutException);
188+
assertInstanceOf(TimeoutException.class, e.getCause());
190189
}
191190
}
192191
}

app/common/src/test/java/stirling/software/common/service/ResourceMonitorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ class ResourceMonitorTest {
3333
@Mock private MemoryMXBean memoryMXBean;
3434

3535
@Spy
36-
private AtomicReference<ResourceStatus> currentStatus =
36+
private final AtomicReference<ResourceStatus> currentStatus =
3737
new AtomicReference<>(ResourceStatus.OK);
3838

3939
@Spy
40-
private AtomicReference<ResourceMetrics> latestMetrics =
40+
private final AtomicReference<ResourceMetrics> latestMetrics =
4141
new AtomicReference<>(new ResourceMetrics());
4242

4343
@BeforeEach

app/common/src/test/java/stirling/software/common/service/TaskManagerTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ void testGetJobStats() throws Exception {
215215
}
216216

217217
@Test
218-
void testCleanupOldJobs() throws Exception {
218+
void testCleanupOldJobs() {
219219
// Arrange
220220
// 1. Create a recent completed job
221221
String recentJobId = "recent-job";
@@ -253,6 +253,7 @@ void testCleanupOldJobs() throws Exception {
253253
taskManager.createTask(activeJobId);
254254

255255
// Verify all jobs are in the map
256+
assertNotNull(jobResultsMap);
256257
assertTrue(jobResultsMap.containsKey(recentJobId));
257258
assertTrue(jobResultsMap.containsKey(oldJobId));
258259
assertTrue(jobResultsMap.containsKey(activeJobId));
@@ -268,7 +269,7 @@ void testCleanupOldJobs() throws Exception {
268269
}
269270

270271
@Test
271-
void testShutdown() throws Exception {
272+
void testShutdown() {
272273
// This mainly tests that the shutdown method doesn't throw exceptions
273274
taskManager.shutdown();
274275

app/common/src/test/java/stirling/software/common/service/TempFileCleanupServiceTest.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,9 @@ else if (fileName.equals("empty.tmp")) {
219219
});
220220

221221
// Act - set containerMode to false for this test
222-
invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000);
223-
invokeCleanupDirectoryStreaming(customTempDir, false, 0, 3600000);
224-
invokeCleanupDirectoryStreaming(libreOfficeTempDir, false, 0, 3600000);
222+
invokeCleanupDirectoryStreaming(systemTempDir, false, 3600000);
223+
invokeCleanupDirectoryStreaming(customTempDir, false, 3600000);
224+
invokeCleanupDirectoryStreaming(libreOfficeTempDir, false, 3600000);
225225

226226
// Assert - Only old temp files and empty files should be deleted
227227
assertTrue(deletedFiles.contains(oldTempFile), "Old temp file should be deleted");
@@ -306,7 +306,7 @@ public void testContainerModeCleanup() throws IOException {
306306
});
307307

308308
// Act - set containerMode to true and maxAgeMillis to 0 for container startup cleanup
309-
invokeCleanupDirectoryStreaming(systemTempDir, true, 0, 0);
309+
invokeCleanupDirectoryStreaming(systemTempDir, true, 0);
310310

311311
// Assert - In container mode, both our temp files and system temp files should be
312312
// deleted
@@ -379,7 +379,7 @@ public void testEmptyFileHandling() throws IOException {
379379
});
380380

381381
// Act
382-
invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000);
382+
invokeCleanupDirectoryStreaming(systemTempDir, false, 3600000);
383383

384384
// Assert
385385
assertTrue(
@@ -462,7 +462,7 @@ public void testRecursiveDirectoryCleaning() throws IOException {
462462
});
463463

464464
// Act
465-
invokeCleanupDirectoryStreaming(systemTempDir, false, 0, 3600000);
465+
invokeCleanupDirectoryStreaming(systemTempDir, false, 3600000);
466466

467467
// Debug - print what was deleted
468468
System.out.println("Deleted files: " + deletedFiles);
@@ -479,8 +479,7 @@ public void testRecursiveDirectoryCleaning() throws IOException {
479479

480480
/** Helper method to invoke the private cleanupDirectoryStreaming method using reflection */
481481
private void invokeCleanupDirectoryStreaming(
482-
Path directory, boolean containerMode, int depth, long maxAgeMillis)
483-
throws IOException {
482+
Path directory, boolean containerMode, long maxAgeMillis) {
484483
try {
485484
// Create a consumer that tracks deleted files
486485
AtomicInteger deleteCount = new AtomicInteger(0);
@@ -503,7 +502,7 @@ private void invokeCleanupDirectoryStreaming(
503502
cleanupService,
504503
directory,
505504
containerMode,
506-
depth,
505+
0,
507506
maxAgeMillis,
508507
false,
509508
deleteCallback);

0 commit comments

Comments
 (0)