Files
Stirling-PDF/src/test/java/stirling/software/SPDF/service/SignatureServiceTest.java
T
Dario Ghunney WareandGitHub bedc3d02d7 New common module (#3573)
# Description of Changes

Introduced a new `common` module for shared libs and commonly used
classes. See the screenshot below for the file structure and classes
that have been moved.

---
<img width="452" alt="Screenshot 2025-05-22 at 11 46 56"
src="https://github.com/user-attachments/assets/c9badabc-48f9-4079-b83e-7cfde0fb840f"
/>
<img width="470" alt="Screenshot 2025-05-22 at 11 47 30"
src="https://github.com/user-attachments/assets/e8315b09-2e78-4c50-b9de-4dd9b9b0ecb1"
/>

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [x] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] 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/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [x] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing)
for more details.
2025-05-27 13:01:52 +01:00

294 lines
11 KiB
Java

package stirling.software.SPDF.service;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mockStatic;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.MockedStatic;
import stirling.software.SPDF.model.SignatureFile;
import stirling.software.common.configuration.InstallationPathConfig;
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);
Files.createDirectories(personalSignatureFolder);
Files.createDirectories(sharedSignatureFolder);
// Create test signature files
Files.write(
personalSignatureFolder.resolve("personal.png"),
"personal signature content".getBytes());
Files.write(
sharedSignatureFolder.resolve("shared.jpg"), "shared signature content".getBytes());
// Use try-with-resources for mockStatic
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Initialize the service with our temp directory
signatureService = new SignatureService();
}
}
@Test
void testHasAccessToFile_PersonalFileExists() throws IOException {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test
boolean hasAccess = signatureService.hasAccessToFile(TEST_USER, "personal.png");
// Verify
assertTrue(hasAccess, "User should have access to their personal file");
}
}
@Test
void testHasAccessToFile_SharedFileExists() throws IOException {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test
boolean hasAccess = signatureService.hasAccessToFile(TEST_USER, "shared.jpg");
// Verify
assertTrue(hasAccess, "User should have access to shared files");
}
}
@Test
void testHasAccessToFile_FileDoesNotExist() throws IOException {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test
boolean hasAccess = signatureService.hasAccessToFile(TEST_USER, "nonexistent.png");
// Verify
assertFalse(hasAccess, "User should not have access to non-existent files");
}
}
@Test
void testHasAccessToFile_InvalidFileName() {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test and verify
assertThrows(
IllegalArgumentException.class,
() -> signatureService.hasAccessToFile(TEST_USER, "../invalid.png"),
"Should throw exception for file names with directory traversal");
assertThrows(
IllegalArgumentException.class,
() -> signatureService.hasAccessToFile(TEST_USER, "invalid/file.png"),
"Should throw exception for file names with paths");
}
}
@Test
void testGetAvailableSignatures() {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test
List<SignatureFile> signatures = signatureService.getAvailableSignatures(TEST_USER);
// Verify
assertEquals(2, signatures.size(), "Should return both personal and shared signatures");
// Check that we have one of each type
boolean hasPersonal =
signatures.stream()
.anyMatch(
sig ->
"personal.png".equals(sig.getFileName())
&& "Personal".equals(sig.getCategory()));
boolean hasShared =
signatures.stream()
.anyMatch(
sig ->
"shared.jpg".equals(sig.getFileName())
&& "Shared".equals(sig.getCategory()));
assertTrue(hasPersonal, "Should include personal signature");
assertTrue(hasShared, "Should include shared signature");
}
}
@Test
void testGetSignatureBytes_PersonalFile() throws IOException {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test
byte[] bytes = signatureService.getSignatureBytes(TEST_USER, "personal.png");
// Verify
assertEquals(
"personal signature content",
new String(bytes),
"Should return the correct content for personal file");
}
}
@Test
void testGetSignatureBytes_SharedFile() throws IOException {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test
byte[] bytes = signatureService.getSignatureBytes(TEST_USER, "shared.jpg");
// Verify
assertEquals(
"shared signature content",
new String(bytes),
"Should return the correct content for shared file");
}
}
@Test
void testGetSignatureBytes_FileNotFound() {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test and verify
assertThrows(
FileNotFoundException.class,
() -> signatureService.getSignatureBytes(TEST_USER, "nonexistent.png"),
"Should throw exception for non-existent files");
}
}
@Test
void testGetSignatureBytes_InvalidFileName() {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test and verify
assertThrows(
IllegalArgumentException.class,
() -> signatureService.getSignatureBytes(TEST_USER, "../invalid.png"),
"Should throw exception for file names with directory traversal");
}
}
@Test
void testGetAvailableSignatures_EmptyUsername() throws IOException {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test
List<SignatureFile> signatures = signatureService.getAvailableSignatures("");
// Verify - should only have shared signatures
assertEquals(
1,
signatures.size(),
"Should return only shared signatures for empty username");
assertEquals(
"shared.jpg",
signatures.get(0).getFileName(),
"Should have the shared signature");
assertEquals(
"Shared", signatures.get(0).getCategory(), "Should be categorized as shared");
}
}
@Test
void testGetAvailableSignatures_NonExistentUser() throws IOException {
// Mock static method for each test
try (MockedStatic<InstallationPathConfig> mockedConfig =
mockStatic(InstallationPathConfig.class)) {
mockedConfig
.when(InstallationPathConfig::getSignaturesPath)
.thenReturn(tempDir.toString());
// Test
List<SignatureFile> signatures =
signatureService.getAvailableSignatures("nonExistentUser");
// Verify - should only have shared signatures
assertEquals(
1,
signatures.size(),
"Should return only shared signatures for non-existent user");
assertEquals(
"shared.jpg",
signatures.get(0).getFileName(),
"Should have the shared signature");
assertEquals(
"Shared", signatures.get(0).getCategory(), "Should be categorized as shared");
}
}
}