docs(project): record feature JPA milestone evidence
This commit is contained in:
@@ -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.
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
- **Test type:** Unit
|
- **Test type:** Unit
|
||||||
- **Requirement IDs:** `PRJ-001`–`PRJ-007`, `PRJ-012`, `PRJ-017`, `AUTH-001`–`AUTH-004`
|
- **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`
|
- **Scenario IDs:** `AC-PRJ-001`, `AC-PRJ-003`, `AC-PRJ-006`, `AC-PRJ-009`
|
||||||
- **Test class/method:** `com.lab.labtimesheet.projects.domain.ProjectTest`
|
- **Test class/method:** `com.lab.labtimesheet.feature.project.model.entity.ProjectEntityTest`
|
||||||
- **Implementation commit:** `3483347`
|
- **Implementation commit:** `25a855e`
|
||||||
|
|
||||||
## Protected behavior
|
## Protected behavior
|
||||||
|
|
||||||
@@ -43,13 +43,13 @@ export PATH="$JAVA_HOME/bin:$PATH"
|
|||||||
```text
|
```text
|
||||||
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"
|
||||||
./mvnw -Dtest=ProjectTest test
|
./mvnw -Dtest=ProjectEntityTest test
|
||||||
```
|
```
|
||||||
|
|
||||||
**Observed result**
|
**Observed result**
|
||||||
|
|
||||||
```text
|
```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] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
|
||||||
[INFO] BUILD SUCCESS
|
[INFO] BUILD SUCCESS
|
||||||
```
|
```
|
||||||
@@ -61,7 +61,7 @@ export PATH="$JAVA_HOME/bin:$PATH"
|
|||||||
```text
|
```text
|
||||||
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"
|
||||||
./mvnw -Dtest=ProjectTest test
|
./mvnw -Dtest=ProjectEntityTest test
|
||||||
|
|
||||||
[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
|
[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
|
||||||
[INFO] BUILD SUCCESS
|
[INFO] BUILD SUCCESS
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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.
|
||||||
Reference in New Issue
Block a user