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
new file mode 100644
index 000000000..2c0e4c7ed
--- /dev/null
+++ b/app/core/src/test/java/stirling/software/SPDF/controller/api/converters/PdfVectorExportControllerTest.java
@@ -0,0 +1,146 @@
+package stirling.software.SPDF.controller.api.converters;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.AfterEach;
+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.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.mock.web.MockMultipartFile;
+
+import stirling.software.SPDF.config.EndpointConfiguration;
+import stirling.software.SPDF.model.api.converters.PdfVectorExportRequest;
+import stirling.software.common.util.ProcessExecutor;
+import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
+import stirling.software.common.util.TempFileManager;
+
+@ExtendWith(MockitoExtension.class)
+class PdfVectorExportControllerTest {
+
+ private final List
tempPaths = new ArrayList<>();
+ @Mock private TempFileManager tempFileManager;
+ @Mock private EndpointConfiguration endpointConfiguration;
+ @Mock private ProcessExecutor ghostscriptExecutor;
+ @InjectMocks private PdfVectorExportController controller;
+ private Map originalExecutors;
+
+ @BeforeEach
+ void setup() throws Exception {
+ when(tempFileManager.createTempFile(any()))
+ .thenAnswer(
+ invocation -> {
+ String suffix = invocation.getArgument(0);
+ Path path =
+ Files.createTempFile(
+ "vector_test", suffix == null ? "" : suffix);
+ tempPaths.add(path);
+ return path.toFile();
+ });
+
+ Field instancesField = ProcessExecutor.class.getDeclaredField("instances");
+ instancesField.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ Map instances =
+ (Map) instancesField.get(null);
+
+ originalExecutors = Map.copyOf(instances);
+ instances.clear();
+ instances.put(ProcessExecutor.Processes.GHOSTSCRIPT, ghostscriptExecutor);
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ Field instancesField = ProcessExecutor.class.getDeclaredField("instances");
+ instancesField.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ Map instances =
+ (Map) instancesField.get(null);
+ instances.clear();
+ if (originalExecutors != null) {
+ instances.putAll(originalExecutors);
+ }
+ reset(ghostscriptExecutor, tempFileManager, endpointConfiguration);
+ for (Path path : tempPaths) {
+ Files.deleteIfExists(path);
+ }
+ tempPaths.clear();
+ }
+
+ private ProcessExecutorResult mockResult(int rc) {
+ ProcessExecutorResult result = mock(ProcessExecutorResult.class);
+ lenient().when(result.getRc()).thenReturn(rc);
+ lenient().when(result.getMessages()).thenReturn("");
+ return result;
+ }
+
+ @Test
+ void convertGhostscript_psToPdf_success() throws Exception {
+ when(endpointConfiguration.isGroupEnabled("Ghostscript")).thenReturn(true);
+ ProcessExecutorResult result = mockResult(0);
+ when(ghostscriptExecutor.runCommandWithOutputHandling(any())).thenReturn(result);
+
+ MockMultipartFile file =
+ new MockMultipartFile(
+ "fileInput",
+ "sample.ps",
+ MediaType.APPLICATION_OCTET_STREAM_VALUE,
+ new byte[] {1});
+ PdfVectorExportRequest request = new PdfVectorExportRequest();
+ request.setFileInput(file);
+
+ ResponseEntity response = controller.convertGhostscriptInputsToPdf(request);
+
+ assertThat(response.getStatusCode()).isEqualTo(org.springframework.http.HttpStatus.OK);
+ assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_PDF);
+ }
+
+ @Test
+ void convertGhostscript_pdfPassThrough_success() throws Exception {
+ when(endpointConfiguration.isGroupEnabled("Ghostscript")).thenReturn(false);
+
+ byte[] content = new byte[] {1};
+ MockMultipartFile file =
+ new MockMultipartFile(
+ "fileInput", "input.pdf", MediaType.APPLICATION_PDF_VALUE, content);
+ PdfVectorExportRequest request = new PdfVectorExportRequest();
+ request.setFileInput(file);
+
+ ResponseEntity response = controller.convertGhostscriptInputsToPdf(request);
+
+ assertThat(response.getStatusCode()).isEqualTo(org.springframework.http.HttpStatus.OK);
+ assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_PDF);
+ assertThat(response.getBody()).contains(content);
+ }
+
+ @Test
+ void convertGhostscript_unsupportedFormatThrows() throws Exception {
+ when(endpointConfiguration.isGroupEnabled("Ghostscript")).thenReturn(false);
+ MockMultipartFile file =
+ new MockMultipartFile(
+ "fileInput", "vector.svg", MediaType.APPLICATION_XML_VALUE, new byte[] {1});
+ PdfVectorExportRequest request = new PdfVectorExportRequest();
+ request.setFileInput(file);
+
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> controller.convertGhostscriptInputsToPdf(request));
+ }
+}
diff --git a/app/core/src/test/java/stirling/software/SPDF/model/api/converters/PdfVectorExportRequestTest.java b/app/core/src/test/java/stirling/software/SPDF/model/api/converters/PdfVectorExportRequestTest.java
new file mode 100644
index 000000000..e7d609b68
--- /dev/null
+++ b/app/core/src/test/java/stirling/software/SPDF/model/api/converters/PdfVectorExportRequestTest.java
@@ -0,0 +1,47 @@
+package stirling.software.SPDF.model.api.converters;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Set;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.Validation;
+import jakarta.validation.Validator;
+import jakarta.validation.ValidatorFactory;
+
+public class PdfVectorExportRequestTest {
+
+ private static Validator validator;
+
+ @BeforeAll
+ static void setUpValidator() {
+ try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
+ validator = factory.getValidator();
+ }
+ }
+
+ @Test
+ void whenOutputFormatValid_thenNoViolations() {
+ PdfVectorExportRequest request = new PdfVectorExportRequest();
+ request.setOutputFormat("EPS");
+
+ Set> violations = validator.validate(request);
+
+ assertThat(violations).isEmpty();
+ }
+
+ @Test
+ void whenOutputFormatInvalid_thenConstraintViolation() {
+ PdfVectorExportRequest request = new PdfVectorExportRequest();
+ request.setOutputFormat("svg");
+
+ Set> violations = validator.validate(request);
+
+ assertThat(violations).hasSize(1);
+ assertThat(violations.iterator().next().getPropertyPath().toString())
+ .isEqualTo("outputFormat");
+ }
+}