Introduce new package org.egothor.methodatlas.ai providing AI-assisted classification of JUnit tests for security relevance. Key changes: - add AI suggestion engine, provider abstraction, and provider clients (OpenAI-compatible, Ollama, Anthropic) - implement strict JSON prompt/response contract and taxonomy handling - integrate AI enrichment into MethodAtlas CLI output (CSV and plain modes) - add configuration via AiOptions and CLI flags - add comprehensive JUnit + Mockito test coverage for AI components and CLI integration scenarios - add realistic test fixtures for security-related test classes - update Gradle configuration for Mockito agent support on JDK 21+ - provide complete Javadoc for the AI module The AI layer is optional and degrades gracefully when providers are unavailable or responses fail.
63 lines
1.9 KiB
Plaintext
63 lines
1.9 KiB
Plaintext
package com.acme.storage;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
|
|
import java.nio.file.Path;
|
|
|
|
import org.junit.jupiter.api.Tag;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
public class PathTraversalValidationTest {
|
|
|
|
@Test
|
|
@Tag("security")
|
|
@Tag("validation")
|
|
void shouldRejectRelativePathTraversalSequence() {
|
|
String userInput = "../secrets.txt";
|
|
|
|
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> {
|
|
if (userInput.contains("..")) {
|
|
throw new IllegalArgumentException("Path traversal attempt detected");
|
|
}
|
|
});
|
|
|
|
assertEquals("Path traversal attempt detected", ex.getMessage());
|
|
}
|
|
|
|
@Test
|
|
@Tag("security")
|
|
@Tag("validation")
|
|
void shouldRejectNestedTraversalAfterNormalization() {
|
|
String userInput = "reports/../../admin/keys.txt";
|
|
Path normalized = Path.of("/srv/app/uploads").resolve(userInput).normalize();
|
|
|
|
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> {
|
|
if (!normalized.startsWith(Path.of("/srv/app/uploads"))) {
|
|
throw new IllegalArgumentException("Escaped upload root");
|
|
}
|
|
});
|
|
|
|
assertEquals("Escaped upload root", ex.getMessage());
|
|
}
|
|
|
|
@Test
|
|
@Tag("security")
|
|
@Tag("validation")
|
|
void shouldAllowSafePathInsideUploadRoot() {
|
|
String userInput = "reports/2026/statement.pdf";
|
|
Path normalized = Path.of("/srv/app/uploads").resolve(userInput).normalize();
|
|
|
|
boolean allowed = normalized.startsWith(Path.of("/srv/app/uploads"));
|
|
|
|
assertEquals(true, allowed);
|
|
}
|
|
|
|
@Test
|
|
void shouldBuildDownloadFileName() {
|
|
String accountId = "ACC-42";
|
|
String fileName = accountId + "-statement.pdf";
|
|
|
|
assertEquals("ACC-42-statement.pdf", fileName);
|
|
}
|
|
} |