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 5677c26077..11073586e7 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 @@ -1,6 +1,7 @@ package stirling.software.SPDF.controller.api; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; @@ -14,19 +15,19 @@ import java.nio.file.Files; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageTree; +import org.jboss.resteasy.reactive.multipart.FileUpload; 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.io.Resource; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.mock.web.MockMultipartFile; + +import jakarta.ws.rs.core.Response; import stirling.software.SPDF.model.api.general.RotatePDFRequest; import stirling.software.common.service.CustomPDFDocumentFactory; +import stirling.software.common.testsupport.TestFileUploads; import stirling.software.common.util.TempFile; import stirling.software.common.util.TempFileManager; @@ -56,48 +57,37 @@ public class RotationControllerTest { @Test public void testRotatePDF() throws IOException { - // Create a mock file - MockMultipartFile mockFile = - new MockMultipartFile( - "file", "test.pdf", MediaType.APPLICATION_PDF_VALUE, new byte[] {1, 2, 3}); - RotatePDFRequest request = new RotatePDFRequest(); - request.setFileInput(mockFile); - request.setAngle(90); + // The controller binds @RestForm FileUpload and rebuilds the RotatePDFRequest internally. + FileUpload fileUpload = TestFileUploads.pdf(new byte[] {1, 2, 3}); PDDocument mockDocument = mock(PDDocument.class); PDPageTree mockPages = mock(PDPageTree.class); PDPage mockPage = mock(PDPage.class); - when(pdfDocumentFactory.load(request)).thenReturn(mockDocument); + when(pdfDocumentFactory.load(any(RotatePDFRequest.class))).thenReturn(mockDocument); when(mockDocument.getPages()).thenReturn(mockPages); when(mockPages.iterator()) .thenReturn(java.util.Collections.singletonList(mockPage).iterator()); when(mockPage.getRotation()).thenReturn(0); // Act - ResponseEntity response = rotationController.rotatePDF(request); + Response response = rotationController.rotatePDF(fileUpload, null, 90); // Assert verify(mockPage).setRotation(90); assertNotNull(response); - assertEquals(200, response.getStatusCode().value()); + assertEquals(200, response.getStatus()); } @Test public void testRotatePDFInvalidAngle() { - // Create a mock file - MockMultipartFile mockFile = - new MockMultipartFile( - "file", "test.pdf", MediaType.APPLICATION_PDF_VALUE, new byte[] {1, 2, 3}); - RotatePDFRequest request = new RotatePDFRequest(); - request.setFileInput(mockFile); - request.setAngle(45); // Invalid angle + FileUpload fileUpload = TestFileUploads.pdf(new byte[] {1, 2, 3}); - // Act & Assert: Controller direkt aufrufen und Exception erwarten + // Act & Assert: call the controller directly and expect the validation exception. IllegalArgumentException exception = assertThrows( IllegalArgumentException.class, - () -> rotationController.rotatePDF(request)); + () -> rotationController.rotatePDF(fileUpload, null, 45)); assertEquals("Angle must be a multiple of 90", exception.getMessage()); } } diff --git a/app/core/src/test/java/stirling/software/common/testsupport/TestFileUploads.java b/app/core/src/test/java/stirling/software/common/testsupport/TestFileUploads.java new file mode 100644 index 0000000000..56ca6875f1 --- /dev/null +++ b/app/core/src/test/java/stirling/software/common/testsupport/TestFileUploads.java @@ -0,0 +1,49 @@ +package stirling.software.common.testsupport; + +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.jboss.resteasy.reactive.multipart.FileUpload; + +/** + * Builds RESTEasy Reactive {@link FileUpload} stubs for unit tests. The migrated controllers bind + * {@code @RestForm FileUpload} and wrap it via {@code FileUploadMultipartFile.of(...)}, which reads + * {@code uploadedFile()}/{@code fileName()}/{@code size()}. This backs the mock with a real temp + * file so those reads work whether or not the collaborator (e.g. {@code CustomPDFDocumentFactory}) + * is itself mocked. All stubs are lenient so a test that never reaches a given accessor does not + * trip strict-stubbing. + */ +public final class TestFileUploads { + + private TestFileUploads() {} + + public static FileUpload of(byte[] content, String fileName, String contentType) { + try { + byte[] bytes = content == null ? new byte[0] : content; + String suffix = fileName == null ? "file" : fileName.replaceAll("[^a-zA-Z0-9._-]", "_"); + Path tmp = Files.createTempFile("test-upload-", "-" + suffix); + tmp.toFile().deleteOnExit(); + Files.write(tmp, bytes); + + FileUpload upload = mock(FileUpload.class); + lenient().when(upload.uploadedFile()).thenReturn(tmp); + lenient().when(upload.filePath()).thenReturn(tmp); + lenient().when(upload.fileName()).thenReturn(fileName); + lenient().when(upload.contentType()).thenReturn(contentType); + lenient().when(upload.size()).thenReturn((long) bytes.length); + return upload; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** Convenience for a PDF part named {@code test.pdf}. */ + public static FileUpload pdf(byte[] content) { + return of(content, "test.pdf", "application/pdf"); + } +}