Skip to content

Add missing tests for JobController, JwtTokenProvider, JwtAuthenticationFilter, and EncryptionService#25

Merged
MaximumTrainer merged 3 commits intomainfrom
copilot/add-unit-tests-for-services-and-controllers
Apr 1, 2026
Merged

Add missing tests for JobController, JwtTokenProvider, JwtAuthenticationFilter, and EncryptionService#25
MaximumTrainer merged 3 commits intomainfrom
copilot/add-unit-tests-for-services-and-controllers

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 1, 2026

Four backend components had zero test coverage: JobController, JwtTokenProvider, JwtAuthenticationFilter, and EncryptionService.

New test files

  • JobControllerTest@WebMvcTest covering all 6 endpoints: list, get (200 + 404), logs, cancel, and create-and-run (POST returning 201). The create endpoint test uses a nested @TestConfiguration @EnableWebSecurity with a permissive SecurityFilterChain and @WithMockUser to properly resolve @AuthenticationPrincipal; stubs userRepository.findByUsername, jobService.createJob, and jobService.runJob, and verifies both service methods are invoked.
  • JwtTokenProviderTest — token generation, subject extraction, and validation against valid/expired/tampered tokens
  • JwtAuthenticationFilterTest — filter behavior for valid ****** (sets SecurityContext), invalid token, missing header, and non-******
  • EncryptionServiceTest — AES-CBC round-trip, random IV uniqueness, and edge cases (empty string, special chars, unicode)

All tests follow existing patterns: @WebMvcTest + excludeAutoConfiguration for controllers, @ExtendWith(MockitoExtension::class) for unit tests, JUnit 5 Assertions.* throughout.

Build configuration

  • Updated build.gradle.kts JaCoCo exclusions: replaced the blanket **/config/** exclusion with per-class exclusions for SecurityConfig, GlobalExceptionHandler, and StartupSecurityValidator, so EncryptionService (which lives in com.opendatamask.config) is now included in coverage reports.
@Test
fun `validateToken returns false for an expired token`() {
    val expiredProvider = JwtTokenProvider(secret, jwtExpiration = -1L)
    val token = expiredProvider.generateToken("charlie")
    assertFalse(expiredProvider.validateToken(token))
}

@Test
fun `encrypt produces different ciphertext on each call due to random IV`() {
    val plaintext = "same input"
    assertNotEquals(encryptionService.encrypt(plaintext), encryptionService.encrypt(plaintext))
}

Copilot AI linked an issue Apr 1, 2026 that may be closed by this pull request
…nticationFilter, and EncryptionService

Agent-Logs-Url: https://github.com/MaximumTrainer/OpenDataMask/sessions/58805c8b-a639-40f3-94b0-c345d1bedbc3

Co-authored-by: MaximumTrainer <1376575+MaximumTrainer@users.noreply.github.com>
Copilot AI changed the title [WIP] Add unit tests for services and controllers with coverage Add missing tests for JobController, JwtTokenProvider, JwtAuthenticationFilter, and EncryptionService Apr 1, 2026
Copilot AI requested a review from MaximumTrainer April 1, 2026 16:47
@MaximumTrainer MaximumTrainer requested review from Copilot and removed request for MaximumTrainer April 1, 2026 17:32
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds new backend test coverage for previously untested security, crypto, and controller components to improve correctness and prevent regressions.

Changes:

  • Introduces unit tests for JwtTokenProvider token generation, parsing, and validation behavior.
  • Adds unit tests for JwtAuthenticationFilter to verify SecurityContext behavior for Bearer/invalid/missing headers.
  • Adds @WebMvcTest coverage for JobController endpoints and unit tests for EncryptionService AES round-trips and edge cases.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
backend/src/test/kotlin/com/opendatamask/security/JwtTokenProviderTest.kt Unit tests around JWT token lifecycle (generate/parse/validate).
backend/src/test/kotlin/com/opendatamask/security/JwtAuthenticationFilterTest.kt Unit tests verifying filter authentication behavior and chain continuation.
backend/src/test/kotlin/com/opendatamask/controller/JobControllerTest.kt MVC slice tests for job listing/details/logs/cancel endpoints.
backend/src/test/kotlin/com/opendatamask/config/EncryptionServiceTest.kt Crypto round-trip + IV uniqueness + edge case tests for encryption/decryption.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +24 to +29
@WebMvcTest(
JobController::class,
excludeAutoConfiguration = [SecurityAutoConfiguration::class, SecurityFilterAutoConfiguration::class]
)
@ActiveProfiles("test")
class JobControllerTest {
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JobController defines a POST /api/workspaces/{workspaceId}/jobs endpoint (createAndRunJob) returning 201, but this test class only covers list/get/logs/cancel. Either add a WebMvc test for the create endpoint (including setting an AuthenticationPrincipal and stubbing userRepository.findByUsername, plus verifying jobService.createJob and jobService.runJob are invoked) or update the PR description/claim about covering all endpoints.

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +14
class EncryptionServiceTest {

private lateinit var encryptionService: EncryptionService

@BeforeEach
fun setup() {
encryptionService = EncryptionService("0123456789abcdef")
}
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests may not affect your reported coverage metrics: backend/build.gradle.kts config excludes **/config/** from JaCoCo classDirectories, and EncryptionService lives under com.opendatamask.config. If the goal is to raise coverage for EncryptionService in CI reports, consider removing that exclusion or moving EncryptionService out of the excluded package.

Copilot uses AI. Check for mistakes.
@MaximumTrainer
Copy link
Copy Markdown
Owner

@copilot apply changes based on the comments in this thread

… coverage

Agent-Logs-Url: https://github.com/MaximumTrainer/OpenDataMask/sessions/190eb898-bd59-4574-9240-605c65c31c00

Co-authored-by: MaximumTrainer <1376575+MaximumTrainer@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 1, 2026

@copilot apply changes based on the comments in this thread

Done in commit 86a3467:

  1. Added createAndRunJob POST test — uses a nested @TestConfiguration @EnableWebSecurity with a permissive SecurityFilterChain (and excludes UserDetailsServiceAutoConfiguration) to properly activate Spring Security's MockMvcSecurityConfiguration. This enables @WithMockUser to populate the SecurityContext so @AuthenticationPrincipal UserDetails resolves correctly. The test stubs userRepository.findByUsername, jobService.createJob, and jobService.runJob, asserts a 201 response, and verifies both service methods are called.

  2. Fixed JaCoCo exclusions — replaced the blanket **/config/** exclusion in build.gradle.kts with specific per-class exclusions (SecurityConfig, GlobalExceptionHandler, StartupSecurityValidator), so EncryptionService is now included in coverage reports.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • example.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Dorg.gradle.internal.worker.tmpdir=/home/REDACTED/work/OpenDataMask/OpenDataMask/backend/build/tmp/test/work -Dorg.gradle.native=false -javaagent:/home/REDACTED/work/OpenDataMask/OpenDataMask/backend/build/tmp/.cache/expanded/zip_0bd0851504e6286cb5fc6f37a81e25cc/jacocoagent.jar=destfile=build/jacoco/test.exec,append=true,inclnolocationclasses=false,dumponexit=true,output=file,jmx=false @/home/REDACTED/.gradle/.tmp/gradle-worker-classpath7819250736097474129txt -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -ea worker.org.gradle.process.internal.worker.GradleWorkerMain &#39;Gradle Test Executor 1&#39; (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@MaximumTrainer MaximumTrainer marked this pull request as ready for review April 1, 2026 18:33
Copilot AI requested a review from MaximumTrainer April 1, 2026 18:34
@MaximumTrainer MaximumTrainer merged commit 9cc8038 into main Apr 1, 2026
8 checks passed
@MaximumTrainer MaximumTrainer deleted the copilot/add-unit-tests-for-services-and-controllers branch April 1, 2026 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test Coverage

3 participants