From 7acd5252058ddf9c6c9b71693a49a440e02a3500 Mon Sep 17 00:00:00 2001 From: sechmachine <97589681+sechmachine727@users.noreply.github.com> Date: Sat, 15 Aug 2026 00:27:35 +0700 Subject: [PATCH] docs(project): record feature JPA milestone evidence --- docs/tests/integration/projects-workflows.md | 75 ++++++++++++++++++++ docs/tests/unit/projects-domain.md | 10 +-- docs/tests/unit/projects-layer-structure.md | 75 ++++++++++++++++++++ docs/tests/web/projects-pages.md | 73 +++++++++++++++++++ 4 files changed, 228 insertions(+), 5 deletions(-) create mode 100644 docs/tests/integration/projects-workflows.md create mode 100644 docs/tests/unit/projects-layer-structure.md create mode 100644 docs/tests/web/projects-pages.md diff --git a/docs/tests/integration/projects-workflows.md b/docs/tests/integration/projects-workflows.md new file mode 100644 index 0000000..dd985a1 --- /dev/null +++ b/docs/tests/integration/projects-workflows.md @@ -0,0 +1,75 @@ +# Test Evidence: Atomic Project workflows + +- **Test type:** Integration +- **Requirement IDs:** `PRJ-001`–`PRJ-007`, `PRJ-017`, `AUTH-001`–`AUTH-004`, `DB-003`, `DB-007` +- **Scenario IDs:** `AC-PRJ-001`–`AC-PRJ-003`, `AC-PRJ-009` +- **Test class/method:** `com.lab.labtimesheet.feature.project.service.ProjectServiceIntegrationTest` +- **Implementation commit:** `25a855e` + +## Protected behavior + +PostgreSQL transactions persist a planned Project with its initial membership and leadership term, reject unauthorized or duplicate direct additions, change exactly one Leader without moving Task assignments, and enforce role/membership visibility without ID disclosure. + +## Test method + +A Spring Boot integration test uses the platform-owned PostgreSQL 18.4 Testcontainer and Flyway V1 schema. It calls the public Project service and verifies committed-shape rows and negative-case non-mutation with independent SQL. + +## Hand-derived expected result + +Creation yields one Project, one active membership, and one current leadership term. Direct addition yields one membership per Project/Intern pair while allowing the same Intern in a second Project. Leader change yields one closed and one current term while the Task assignee ID remains unchanged. Admin, owner, and historical member visibility is allowed; unrelated IDs are denied uniformly. + +## RED + +**Command** + +```text +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=ProjectServiceIntegrationTest test +``` + +**Observed result** + +```text +[ERROR] cannot find symbol: class CreateProjectCommand +[ERROR] cannot find symbol: class ProjectService +[INFO] BUILD FAILURE +``` + +## GREEN + +**Command** + +```text +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=ProjectServiceIntegrationTest test +``` + +**Observed result** + +```text +[INFO] Running com.lab.labtimesheet.feature.project.service.ProjectServiceIntegrationTest +[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0 +[INFO] BUILD SUCCESS +``` + +## Affected suite + +**Command and result** + +```text +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 test + +[INFO] Tests run: 25, Failures: 0, Errors: 0, Skipped: 0 +[INFO] BUILD SUCCESS +``` + +## External-test boundaries + +This test does not prove MockMvc authorization, Thymeleaf rendering, browser accessibility, real concurrent transaction races, Iteration 2 invitations/removals/completion, or Task-module business rules beyond preserving stored assignment IDs. `I1-PRJ-04` remains `IN_PROGRESS`: the activation Task-assignee guard will be implemented only after the Task feature exposes its concrete query service. diff --git a/docs/tests/unit/projects-domain.md b/docs/tests/unit/projects-domain.md index 18e5512..27467e4 100644 --- a/docs/tests/unit/projects-domain.md +++ b/docs/tests/unit/projects-domain.md @@ -3,8 +3,8 @@ - **Test type:** Unit - **Requirement IDs:** `PRJ-001`–`PRJ-007`, `PRJ-012`, `PRJ-017`, `AUTH-001`–`AUTH-004` - **Scenario IDs:** `AC-PRJ-001`, `AC-PRJ-003`, `AC-PRJ-006`, `AC-PRJ-009` -- **Test class/method:** `com.lab.labtimesheet.projects.domain.ProjectTest` -- **Implementation commit:** `3483347` +- **Test class/method:** `com.lab.labtimesheet.feature.project.model.entity.ProjectEntityTest` +- **Implementation commit:** `25a855e` ## Protected behavior @@ -43,13 +43,13 @@ export PATH="$JAVA_HOME/bin:$PATH" ```text export JAVA_HOME=/opt/homebrew/opt/openjdk@25 export PATH="$JAVA_HOME/bin:$PATH" -./mvnw -Dtest=ProjectTest test +./mvnw -Dtest=ProjectEntityTest test ``` **Observed result** ```text -[INFO] Running com.lab.labtimesheet.projects.domain.ProjectTest +[INFO] Running com.lab.labtimesheet.feature.project.model.entity.ProjectEntityTest [INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESS ``` @@ -61,7 +61,7 @@ export PATH="$JAVA_HOME/bin:$PATH" ```text export JAVA_HOME=/opt/homebrew/opt/openjdk@25 export PATH="$JAVA_HOME/bin:$PATH" -./mvnw -Dtest=ProjectTest test +./mvnw -Dtest=ProjectEntityTest test [INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESS diff --git a/docs/tests/unit/projects-layer-structure.md b/docs/tests/unit/projects-layer-structure.md new file mode 100644 index 0000000..e27ad70 --- /dev/null +++ b/docs/tests/unit/projects-layer-structure.md @@ -0,0 +1,75 @@ +# Test Evidence: Project layer and JPA structure + +- **Test type:** Unit +- **Requirement IDs:** `ARC-002`, `ARC-005`–`ARC-007`, `OPS-018`–`OPS-020`, `TST-001`–`TST-010` +- **Scenario IDs:** `I1-PRJ-01`–`I1-PRJ-05` +- **Test class/method:** `com.lab.labtimesheet.feature.project.repository.ProjectPersistenceStructureTest#projectPersistenceUsesTheRequiredLayerPackagesAndSpringDataJpa` +- **Implementation commit:** `25a855e` + +## Protected behavior + +Project-owned production code follows the authoritative feature-first package layout, persists aggregate entities through Spring Data JPA, keeps JDBC operations out of Project business services, and does not shadow Account or Task persistence. + +## Test method + +Plain JUnit inspects the public Project entity, repository, and service types. It verifies their exact feature/layer packages, the entity's JPA mapping, the repository's `JpaRepository` contract, the absence of JDBC service dependencies, and the absence of foreign-table Account/Task shadow entities. + +## Hand-derived expected result + +The Project aggregate is under `feature.project.model.entity`, persistence under `feature.project.repository`, business logic under `feature.project.service`, the service has zero JDBC collaborators, and Account/Task persistence remains owned by those features. + +## RED + +**Command** + +```text +export JAVA_HOME=/opt/homebrew/opt/openjdk@25 +export PATH="$JAVA_HOME/bin:$PATH" +./mvnw -Dtest=ProjectPersistenceStructureTest test +``` + +**Observed result** + +```text +[ERROR] cannot find symbol: class ProjectUserRepository +[ERROR] cannot find symbol: class ProjectInternProfileRepository +[ERROR] cannot find symbol: class ProjectTaskRepository +[INFO] BUILD FAILURE +``` + +The RED was observed after removing Project-owned shadow mappings of Account and Task tables. It proves the service still required cross-feature dependencies and could not be made green by retaining forbidden repositories. + +## GREEN + +**Command** + +```text +export JAVA_HOME=/opt/homebrew/opt/openjdk@25 +export PATH="$JAVA_HOME/bin:$PATH" +./mvnw -Dtest=ProjectPersistenceStructureTest test +``` + +**Observed result** + +```text +[INFO] Running com.lab.labtimesheet.feature.project.repository.ProjectPersistenceStructureTest +[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +[INFO] BUILD SUCCESS +``` + +## Affected suite + +**Command and result** + +```text +export JAVA_HOME=/opt/homebrew/opt/openjdk@25 +export PATH="$JAVA_HOME/bin:$PATH" +./mvnw -Dtest=LayerStructureTest,ProjectPersistenceStructureTest,ProjectEntityTest test + +[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0 +[INFO] BUILD SUCCESS +``` + +## External-test boundaries + +This check does not prove database mappings, transaction behavior, MVC routing, or runtime authorization; those remain covered by PostgreSQL and MockMvc tests. diff --git a/docs/tests/web/projects-pages.md b/docs/tests/web/projects-pages.md new file mode 100644 index 0000000..df25b1f --- /dev/null +++ b/docs/tests/web/projects-pages.md @@ -0,0 +1,73 @@ +# Test Evidence: Authorized Project pages + +- **Test type:** Web +- **Requirement IDs:** `AUTH-001`, `AUTH-002`, `AUTH-006`, `PRJ-001`, `PRJ-004`–`PRJ-006`, `SEC-001`, `ERR-001` +- **Scenario IDs:** `AC-AUTH-001`, `AC-AUTH-002`, `AC-AUTH-007`, `I1-PRJ-05` +- **Test class/method:** `com.lab.labtimesheet.feature.project.controller.ProjectControllerTest` +- **Implementation commit:** `25a855e` + +## Protected behavior + +Authenticated users receive only authorized Project routes; guessed IDs return a non-disclosing not-found response; valid Mentor create requests use the authenticated identity; invalid forms do not mutate; state changes require CSRF. + +## Test method + +MockMvc exercises the real controller, binding, Bean Validation, exception mapping, view selection, redirect, Spring Security authentication, and CSRF filter. Only application/query services are mocked. + +## Hand-derived expected result + +An authorized list request renders `projects/list`. An unauthorized direct ID returns 404. Member and leadership routes authorize through actor plus Project ID. A valid create redirects to the created detail ID; a blank name and zero Leader ID render field errors and make no service call. POST without CSRF returns 403. + +## RED + +**Command** + +```text +export JAVA_HOME=/opt/homebrew/opt/openjdk@25 +export PATH="$JAVA_HOME/bin:$PATH" +./mvnw -Dtest=ProjectControllerTest test +``` + +**Observed result** + +```text +[ERROR] cannot find symbol: class ProjectController +[ERROR] cannot find symbol: class ProjectPageService +[INFO] BUILD FAILURE +``` + +## GREEN + +**Command** + +```text +export JAVA_HOME=/opt/homebrew/opt/openjdk@25 +export PATH="$JAVA_HOME/bin:$PATH" +./mvnw -Dtest=ProjectControllerTest test +``` + +**Observed result** + +```text +[INFO] Running com.lab.labtimesheet.feature.project.controller.ProjectControllerTest +[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0 +[INFO] BUILD SUCCESS +``` + +## Affected suite + +**Command and result** + +```text +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 test + +[INFO] Tests run: 25, Failures: 0, Errors: 0, Skipped: 0 +[INFO] BUILD SUCCESS +``` + +## External-test boundaries + +This slice does not prove PostgreSQL query correctness, a real login flow, shared-shell navigation, browser accessibility, or Iteration 2 invitation/exit/completion pages. The activation route remains deferred with `I1-PRJ-04` until the Task feature query dependency is available.