Files
labtimesheet/docs/tests/unit/project-task-mutation-context.md

3.1 KiB

Test Evidence: Locked Project context for Task mutations

  • Test type: Unit
  • Requirement IDs: AUTH-001, AUTH-011, PRJ-012
  • Scenario IDs: AC-AUTH-001, AC-AUTH-010, AC-PRJ-006
  • Test class/method: com.lab.labtimesheet.feature.project.service.ProjectTaskMutationContextTest#loadsTheProjectForUpdateBeforeBuildingTheTaskMutationContext
  • Implementation commit: 19a3518

Protected behavior

Task mutations obtain their Project authorization and current lifecycle, Leader, owning-Mentor, and active-member facts from a DTO-only Project service boundary after the Project row has been locked for update. Missing and unauthorized Projects retain the same non-disclosing denial behavior.

Test method

The isolated service test invokes ProjectService.taskMutationContext(actorUserId, projectId), verifies that ProjectRepository.findLockedById is used and the ordinary findById path is not used, and verifies that only the locked entity is passed to the existing Project-owned authorization and DTO mapper. The PostgreSQL integration test additionally exercises the public API with authorized, unauthorized, current-member, and former-member data.

Hand-derived expected result

Exactly one pessimistic Project lookup occurs before context evaluation. The returned ProjectTaskContext exposes scalar/DTO facts only; no Project repository or entity crosses the feature boundary. When called from Task's active transaction, Spring's default REQUIRED propagation keeps the row lock in that transaction through its commit or rollback.

RED

Command

export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -Dtest=ProjectTaskMutationContextTest test

Observed result

[ERROR] constructor ProjectService ... cannot be applied to given types
[ERROR] incompatible types: ProjectEntity cannot be converted to long
[INFO] BUILD FAILURE

The test failed to compile because Project had no mutation-context API and its context mapper accepted only an unlocked Project ID lookup.

GREEN

Command

export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -Dtest=ProjectTaskMutationContextTest test

Observed result

[INFO] Running com.lab.labtimesheet.feature.project.service.ProjectTaskMutationContextTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS

Affected suite

Command and result

export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock
./mvnw -Dtest='Project*Test' test

[INFO] Tests run: 20, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS

External-test boundaries

The unit test proves the locked repository path and DTO-only handoff, while the integration coverage proves current Project authorization/member mapping against PostgreSQL 18.4. It does not orchestrate two concurrent database transactions; the lock-retention guarantee relies on the public method's @Transactional default REQUIRED propagation and the Task caller retaining its outer transaction.