test(task): record review fix evidence

This commit is contained in:
sechmachine
2026-08-15 02:19:20 +07:00
parent fb0ed7f12c
commit e38e2cdea9
2 changed files with 109 additions and 11 deletions
+84
View File
@@ -0,0 +1,84 @@
# Test Evidence: Task public API documentation retrofit
- **Test type:** Unit
- **Requirement IDs:** `TST-009`
- **Scenario IDs:** `Iteration 1 Task Javadoc retrofit`
- **Test class/method:** `Maven compiler and Javadoc doclint (no synthetic test)`
- **Implementation commit:** `fb0ed7f12c9d89235c102b67f2b13f786011c9ee`
## Protected behavior
Every Task-owned production type and declared public or protected API carries meaningful Javadoc for its business contract. The documented contracts include authorization and lifecycle scope, Project-first/Task-row lock order, non-disclosing HTTP behavior, fixed status transitions, empty progress, actor/history/version invariants, repository filtering and locks, DTO identifier domains and capability flags, the cross-feature activation guard, and dashboard scope/order/limit.
## Test method
This is prose and API documentation, so `TST-009` forbids an artificial unit test. Java 25 compilation checks source validity. The Maven Javadoc plugin runs standard doclint against only `com.lab.labtimesheet.feature.task`, making missing or malformed Task API documentation directly observable without treating unrelated feature retrofit work as Task-owned.
## Hand-derived expected result
The Task package contains 21 production Java types. Each type has a main description. Every declared public/protected constructor and method has a contract comment; record components document their identifier domains, null/empty meanings, and capability semantics. Task-scoped Javadoc generation completes with no warnings.
## RED
**Command**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -DskipTests -Ddoclint=all -Dsubpackages=com.lab.labtimesheet.feature.task javadoc:javadoc
```
**Observed result**
```text
[WARNING] Javadoc Warnings
[WARNING] Task.java: warning: no main description (12 accessors)
[WARNING] TaskComment.java: warning: no main description (5 accessors)
[WARNING] TaskStatus.java: warning: no comment (4 enum constants)
[WARNING] 21 warnings
[INFO] BUILD SUCCESS
```
This was a diagnostic documentation baseline rather than a failing behavioral test. The parent instruction explicitly required doclint/compile instead of a fake test.
## GREEN
**Command**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -DskipTests -Ddoclint=all -Dsubpackages=com.lab.labtimesheet.feature.task javadoc:javadoc
```
**Observed result**
```text
[INFO] --- javadoc:3.12.0:javadoc (default-cli) @ labtimesheet ---
[INFO] BUILD SUCCESS
```
No Task-scoped Javadoc warning was emitted.
## Affected suite
**Command and result**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -DskipTests compile
[INFO] Compiling 112 source files with javac [debug parameters release 25] to target/classes
[INFO] BUILD SUCCESS
export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock
./mvnw clean test
[INFO] Tests run: 113, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
## External-test boundaries
Doclint validates Javadoc structure and references, not whether prose perfectly models runtime behavior. Contract accuracy was checked by a scoped adversarial diff review against the numbered Task, authorization, Project-lifecycle, UI, and database requirements. Other feature owners retain responsibility for their own Iteration 1 Javadoc retrofits.
+25 -11
View File
@@ -1,24 +1,24 @@
# Test Evidence: Task pages and server-side request boundaries # Test Evidence: Task pages and server-side request boundaries
- **Test type:** Web - **Test type:** Web
- **Requirement IDs:** `AUTH-001`, `AUTH-002`, `AUTH-005`, `AUTH-009`, `AUTH-011`, `PRJ-015`, `TSK-003`, `TSK-007`, `TSK-011`, `TSK-012` - **Requirement IDs:** `AUTH-001`, `AUTH-002`, `AUTH-005`, `AUTH-009`, `AUTH-011`, `PRJ-015`, `TSK-003`, `TSK-005`, `TSK-007``TSK-008`, `TSK-011`, `TSK-012`, `UI-014`
- **Scenario IDs:** `I1-TSK-01`, `I1-TSK-03``I1-TSK-05`, `AC-AUTH-001`, `AC-AUTH-006`, `AC-AUTH-010`, `AC-PRJ-008`, `AC-TSK-003`, `AC-TSK-006`, `AC-TSK-010` - **Scenario IDs:** `I1-TSK-01``I1-TSK-05`, `AC-AUTH-001`, `AC-AUTH-006`, `AC-AUTH-010`, `AC-PRJ-008`, `AC-TSK-002`, `AC-TSK-003`, `AC-TSK-006`, `AC-TSK-010`
- **Test class/method:** `com.lab.labtimesheet.feature.task.controller.TaskControllerTest` - **Test class/method:** `com.lab.labtimesheet.feature.task.controller.TaskControllerTest`
- **Implementation commit:** `511ee81a91a79a61cc6afb00097e1b38577c1968` - **Implementation commit:** `fb0ed7f12c9d89235c102b67f2b13f786011c9ee`
## Protected behavior ## Protected behavior
Task list/detail/create/status/comment routes require authentication, obtain actor identity from Spring Security rather than request IDs, retain CSRF protection, convert guessed-record denial to HTTP 404, validate create input, render the actual Thymeleaf pages, show `N/A` for an empty Project, display assignees, and expose create/status/comment controls only when the service-provided capability permits them. Task list/detail/create/status/comment routes require authentication, obtain actor identity from Spring Security rather than request IDs, retain CSRF protection, convert guessed-record denial to HTTP 404, validate create input, render the actual Thymeleaf pages, show `N/A` for an empty Project, display assignees, and expose create/status/comment controls only when the service-provided capability permits them. The status form exposes only direct edges from the current fixed status graph. An authorized create request with an invalid due date returns the form with the due-date field error, retained safe input, and refreshed authorized assignees; an access failure still returns non-disclosing HTTP 404.
## Test method ## Test method
Nine `@WebMvcTest` MockMvc tests render the real Task templates and exercise the real controller, Spring Security filter chain, CSRF filter, Bean Validation binding, redirect contracts, exception-to-status mapping, assignee output, and capability-controlled actions. Only the PostgreSQL-backed Task service is replaced at the controller boundary. Fifteen `@WebMvcTest` MockMvc invocations render the real Task templates and exercise the real controller, Spring Security filter chain, CSRF filter, Bean Validation binding, redirect contracts, exception-to-status mapping, assignee output, and capability-controlled actions. A four-case parameterized test independently specifies every permitted status choice set. Dedicated create tests distinguish a due-date business validation response from a guessed-Project access response. Only the PostgreSQL-backed Task service is replaced at the controller boundary.
## Hand-derived expected result ## Hand-derived expected result
Unauthenticated list access returns 401 under the current platform security baseline. An authorized empty list returns 200 and contains `N/A`. A denied guessed Task returns 404. A valid create request passes Project 10, assignee membership 7, the supplied fields, and the authenticated email to the service, then redirects to Task 25. Blank title stays on the form with a field error and no write. Valid status/comment posts redirect to Task 25. Unauthenticated list access returns 401 under the current platform security baseline. An authorized empty list returns 200 and contains `N/A`. A denied guessed Task or Project returns 404. A valid create request passes Project 10, assignee membership 7, the supplied fields, and the authenticated email to the service, then redirects to Task 25. Blank title stays on the form with a field error and no write. An invalid due date returns 200 with the message attached to `dueDate`, keeps title, description, assignee, and date, and reloads the permitted choices. Valid status/comment posts redirect to Task 25.
When `canCreate`, `canChangeStatus`, or `canComment` is false, the corresponding control is absent. When true, it is rendered. Both list and detail output the assignee display name. When `canCreate`, `canChangeStatus`, or `canComment` is false, the corresponding control is absent. When true, it is rendered. Both list and detail output the assignee display name. The hand-derived status choices are TODO to IN_PROGRESS/BLOCKED; IN_PROGRESS to BLOCKED/DONE; BLOCKED to TODO/IN_PROGRESS; and DONE to IN_PROGRESS.
## RED ## RED
@@ -42,6 +42,15 @@ The first sandboxed GREEN attempt then exposed an environment boundary, not an a
The later view-capability increment was observed RED at test compilation because the Task DTOs did not yet provide the required capability and assignee fields. The later view-capability increment was observed RED at test compilation because the Task DTOs did not yet provide the required capability and assignee fields.
The review-fix increment used the same command and observed these additional production-shaped failures before the controller/form change:
```text
[ERROR] Tests run: 14, Failures: 5, Errors: 0, Skipped: 0
[ERROR] invalidDueDateRendersFieldErrorAndRetainsSafeInput: Status expected:<200> but was:<400>
[ERROR] taskDetailsExposeOnlyAllowedStatusTransitions: expected permitted subsets but was:<{TODO, IN_PROGRESS, BLOCKED, DONE}> for all four source states
[INFO] BUILD FAILURE
```
## GREEN ## GREEN
**Command** **Command**
@@ -57,7 +66,7 @@ Run with approved sandbox escalation for Mockito Java 25 self-attach.
**Observed result** **Observed result**
```text ```text
[INFO] Tests run: 9, Failures: 0, Errors: 0, Skipped: 0 [INFO] Tests run: 15, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS [INFO] BUILD SUCCESS
``` ```
@@ -69,9 +78,14 @@ Run with approved sandbox escalation for Mockito Java 25 self-attach.
export JAVA_HOME=/opt/homebrew/opt/openjdk@25 export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH" export PATH="$JAVA_HOME/bin:$PATH"
export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock
./mvnw test ./mvnw -Dtest=TaskDomainRulesTest,TaskPersistenceStructureTest,TaskMutationBoundaryTest,TaskQueryServiceTest,TaskDashboardServiceTest,TaskControllerTest,TaskCreationIntegrationTest test
[INFO] Tests run: 107, Failures: 0, Errors: 0, Skipped: 0 [INFO] Tests run: 57, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
./mvnw clean test
[INFO] Tests run: 113, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS [INFO] BUILD SUCCESS
``` ```
@@ -79,4 +93,4 @@ The suite ran with approved escalation for OrbStack and Mockito self-attach.
## External-test boundaries ## External-test boundaries
This slice test does not prove PostgreSQL state changes; those are covered by `TaskCreationIntegrationTest`. Shared shell styling/navigation remains owned by `work/reports-ui`. Browser journeys, notifications, Iteration 2 workflows, and narrow-screen behavior are outside this Iteration 1 Task evidence. This slice test does not prove PostgreSQL state changes; those are covered by `TaskCreationIntegrationTest` in the affected/full commands. Shared shell styling/navigation remains owned by `work/reports-ui`. Browser journeys, notifications, Iteration 2 workflows, and narrow-screen behavior are outside this Iteration 1 Task evidence.