Merge commit '692b23e9b9891d360882671d8247965b44920b2f' into work/reports-ui

# Conflicts:
#	src/main/resources/templates/accounts/activate.html
#	src/main/resources/templates/accounts/new.html
#	src/main/resources/templates/bootstrap/form.html
This commit is contained in:
sechmachine
2026-08-15 03:32:40 +07:00
81 changed files with 2595 additions and 130 deletions
+4 -4
View File
@@ -2,9 +2,9 @@
- **Test type:** Web
- **Requirement IDs:** `ACC-008ACC-011, ACC-014, ACC-019, AUTH-001AUTH-002, SEC-002SEC-004`
- **Scenario IDs:** `AC-ACC-005, AC-ACC-007, AC-AUTH-001`
- **Scenario IDs:** `AC-ACC-005` (Mentor/Intern browser paths), `AC-ACC-007`
- **Test class/method:** `com.lab.labtimesheet.feature.account.controller.AccountWebIntegrationTest.adminCreatesMentorAndInternThenMentorActivatesAuthenticatesAndLogsOut`
- **Implementation commit:** `this milestone commit`
- **Implementation commit:** `8e786ba37ba7fcff09cf88d5951acb21fbb36ea8`; validation/additional-Admin coverage added in `17fa25bb0921718f780037cd8c55a956bbdf6b19`
## Protected behavior
@@ -62,7 +62,7 @@ export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock
**Observed result**
```text
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
```
@@ -82,4 +82,4 @@ BUILD SUCCESS
## External-test boundaries
This test does not contact Mailpit or an external SMTP server and is not a real browser/accessibility test. It does not cover activation resend, password reset, account lock/deactivation, session invalidation after credential/state changes, production origin configuration, containerization, CI, or deployment.
This test does not contact Mailpit or an external SMTP server and is not a real browser/accessibility test. Hash-only persistence and exact expiry are covered by the integration test. It does not cover activation resend, password reset, account lock/deactivation, session invalidation after credential/state changes, production origin configuration, containerization, CI, or deployment.
@@ -0,0 +1,75 @@
# Test Evidence: Constraint-specific account uniqueness feedback
- **Test type:** Web
- **Requirement IDs:** `ACC-019`, `DB-003`
- **Scenario IDs:** `AC-ACC-005` (Intern creation uniqueness boundary)
- **Test class/method:** `com.lab.labtimesheet.feature.account.controller.AccountWebIntegrationTest#duplicateNormalizedStudentCodeIsReportedOnStudentCodeRatherThanEmail`
- **Implementation commit:** `06dba4fb13eed675cc08ff8c00fe3e3650468c3b`
## Protected behavior
A case- and whitespace-normalized duplicate Intern student code is reported on the student-code field. A distinct
email is not falsely labeled as duplicate, and unknown uniqueness constraints fall back to a non-specific conflict.
## Test method
MockMvc creates one Intern through the authenticated CSRF-protected production form and then submits a second Intern
with a distinct email and the same student code in different case with surrounding whitespace. PostgreSQL 18.4
enforces the real Flyway expression index; the controller maps Hibernate's known constraint name to the form field.
## Hand-derived expected result
The second request returns HTTP 200 on `accounts/new`, retains the safe display name, shows the student-code conflict,
and does not claim that the distinct email already exists.
## 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=AccountWebIntegrationTest#duplicateNormalizedStudentCodeIsReportedOnStudentCodeRatherThanEmail test
```
**Observed result**
```text
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
PostgreSQL reported uq_intern_profiles_student_code_ci, but the form displayed "this email already exists".
BUILD FAILURE
PostgreSQL: 18.4
```
## GREEN
**Command**
```text
./mvnw -Dtest=AccountWebIntegrationTest#duplicateNormalizedStudentCodeIsReportedOnStudentCodeRatherThanEmail test
```
**Observed result**
```text
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
PostgreSQL: 18.4
```
## Affected suite
**Command and result**
```text
./mvnw -Dtest=TimeConfigurationTest,BootstrapIntegrationTest,SmtpOnboardingWebIntegrationTest,AccountActivationIntegrationTest,AccountWebIntegrationTest,BootstrapOnboardingWebIntegrationTest,JavaMailSmtpProbeTest,SecurityResponseIntegrationTest test
Tests run: 22, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
PostgreSQL: 18.4
```
## External-test boundaries
The test covers the two Platform-owned normalized identity constraints. It does not enumerate later-iteration feature
constraints or perform a real-browser accessibility pass.
@@ -4,7 +4,7 @@
- **Requirement IDs:** `I1-UI-03, I1-UI-04`
- **Scenario IDs:** `I1-UI-04 authentication integration follow-up`
- **Test class/method:** `com.lab.labtimesheet.feature.account.controller.AuthenticationWebIntegrationTest.projectLoginPageSupportsFailureNormalizedSuccessAndLogout`
- **Implementation commit:** `this milestone commit`
- **Implementation commit:** `c4656a88806a92cb59b2e588035a4124854feb92`
## Protected behavior
@@ -0,0 +1,94 @@
# Test Evidence: Validated bootstrap, SMTP, and account onboarding
- **Test type:** Web
- **Requirement IDs:** `ACC-005ACC-012`, `INT-004`, `INT-006INT-008`, `SEC-001`
- **Scenario IDs:** `AC-ACC-003`; `AC-INT-002` (Admin browser boundary)
- **Test class/method:** `com.lab.labtimesheet.feature.account.controller.BootstrapOnboardingWebIntegrationTest`, `com.lab.labtimesheet.feature.integration.controller.SmtpOnboardingWebIntegrationTest`, `com.lab.labtimesheet.feature.account.controller.AccountWebIntegrationTest#invalidAndDuplicateAccountFormsReturnActionableErrorsWithoutCreatingAnotherAccount`
- **Implementation commit:** `17fa25bb0921718f780037cd8c55a956bbdf6b19`; SMTP failure feedback added in `8ff6ee3d873db909b1ce9df690f7a3abb2c3c79d`
## Protected behavior
Bootstrap offers SMTP setup after creating the first Admin. The Admin can save a validated draft, test it, and
activate only a successful test; or traverse five distinct ordered deferral acknowledgements before finishing.
Restricted-installation warnings persist until activation. Invalid bootstrap/account/SMTP forms retain only safe
non-secret values and show actionable errors. All state-changing browser operations require CSRF.
## Test method
MockMvc drives the production controllers, Bean Validation, Thymeleaf rendering, Spring Security filter chain, JPA
services, and PostgreSQL 18.4. SMTP is replaced only at its network adapter. The tests inspect rendered status,
buttons, warnings, validation messages, password non-retention, CSRF denial, ordered deferral navigation, and the
failed-probe response while verifying that activation remains unavailable and raw adapter diagnostics are absent.
## Hand-derived expected result
Successful bootstrap lands on `/admin/smtp?onboarding`. A saved draft shows Test but not Activate; a successful test
shows Activate; activation clears the restricted warning. Deferral exposes warnings one through five in order, Back
and Configure on every screen, and Finish only on screen five. Invalid data returns HTTP 200 with field/global errors
and no submitted password. A failed SMTP probe displays fixed operator guidance and leaves the draft untested without
rendering the adapter's diagnostic.
## 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=BootstrapOnboardingWebIntegrationTest,SmtpOnboardingWebIntegrationTest test
```
**Observed result**
```text
Tests run: 6, Failures: 5, Errors: 1, Skipped: 0
Bootstrap redirected to /login instead of SMTP onboarding; deferral returned 404; SMTP status and warning were
absent; invalid form input raised a validation exception.
BUILD FAILURE
```
The later failure-feedback regression used this focused command:
```text
./mvnw -Dtest=SmtpOnboardingWebIntegrationTest#failedSmtpTestRendersActionableFeedbackWithoutActivatingTheDraft test
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
Expected the configured connection-refusal message, but smtp/form omitted it.
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=BootstrapOnboardingWebIntegrationTest,SmtpOnboardingWebIntegrationTest test
```
**Observed result**
```text
Tests run: 7, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
PostgreSQL: 18.4
```
## Affected suite
**Command and result**
```text
./mvnw -Dtest=BootstrapIntegrationTest,SmtpOnboardingWebIntegrationTest,AccountActivationIntegrationTest,AccountWebIntegrationTest,BootstrapOnboardingWebIntegrationTest,JavaMailSmtpProbeTest,SecurityResponseIntegrationTest test
Tests run: 20, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
PostgreSQL: 18.4
```
## External-test boundaries
The SMTP adapter is in-memory here, so this does not prove external Mailpit/server interoperability. MockMvc is not a
real browser or accessibility run. The test uses a non-secret diagnostic fixture only to prove that raw adapter text
is absent; it never exposes a password, integration secret, or activation bearer token.
@@ -0,0 +1,73 @@
# Test Evidence: Public assets and activation-safe response headers
- **Test type:** Web
- **Requirement IDs:** `ACC-001`, `SEC-001`, `SEC-003`, `SEC-009`
- **Scenario IDs:** No direct acceptance-scenario mapping (response-security regression)
- **Test class/method:** `com.lab.labtimesheet.config.SecurityResponseIntegrationTest`
- **Implementation commit:** `6181984cf85f184be39513d6313f9cbe8267add5`
## Protected behavior
Public `/assets/**` requests remain reachable before bootstrap in both the Spring Security chain and bootstrap access
filter. Responses use `Referrer-Policy: no-referrer` so an activation URL bearer token cannot be forwarded in a
same-origin Referer header when a user follows another link.
## Test method
MockMvc starts the production filter chain against PostgreSQL 18.4 before initialization. It requests a known static
test asset and the activation page, asserting successful resource delivery and the exact global response header.
## Hand-derived expected result
The known asset returns HTTP 200 before bootstrap. The activation response contains exactly
`Referrer-Policy: no-referrer`.
## 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=SecurityResponseIntegrationTest test
```
**Observed result**
```text
Tests run: 2, Failures: 2, Errors: 0, Skipped: 0
The asset request returned 404 and the activation response Referrer-Policy header was null.
BUILD FAILURE
```
## GREEN
**Command**
```text
./mvnw -Dtest=SecurityResponseIntegrationTest test
```
**Observed result**
```text
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
PostgreSQL: 18.4
```
## Affected suite
**Command and result**
```text
./mvnw -Dtest=BootstrapIntegrationTest,SmtpOnboardingWebIntegrationTest,AccountActivationIntegrationTest,AccountWebIntegrationTest,BootstrapOnboardingWebIntegrationTest,JavaMailSmtpProbeTest,SecurityResponseIntegrationTest test
Tests run: 20, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
```
## External-test boundaries
This verifies server response behavior through MockMvc, not browser enforcement of Referrer-Policy or Reporting's
integrated asset graph. It does not place a real activation token in logs, evidence, or request fixtures.
+2 -2
View File
@@ -1,10 +1,10 @@
# Test Evidence: Project-owned login flow
- **Test type:** Web
- **Requirement IDs:** `ACC-009, SEC-001, SEC-005, I1-UI-04`
- **Requirement IDs:** `ACC-009, SEC-001, I1-UI-04`
- **Scenario IDs:** `I1-UI-04 authentication integration follow-up`
- **Test class/method:** `com.lab.labtimesheet.feature.account.controller.AuthenticationWebIntegrationTest.projectLoginPageSupportsFailureNormalizedSuccessAndLogout`
- **Implementation commit:** `this milestone commit`
- **Implementation commit:** `a18d8e1d3dd02c8978033f09563d2ec9341926c7`
## Protected behavior
+75
View File
@@ -0,0 +1,75 @@
# Test Evidence: Sanitized SMTP failure feedback
- **Test type:** Web
- **Requirement IDs:** `INT-005`, `INT-008`
- **Scenario IDs:** `AC-INT-002` (failed-draft browser boundary)
- **Test class/method:** `com.lab.labtimesheet.feature.integration.controller.SmtpOnboardingWebIntegrationTest#failedSmtpTestRendersActionableFeedbackWithoutActivatingTheDraft`
- **Implementation commit:** `06dba4fb13eed675cc08ff8c00fe3e3650468c3b`
## Protected behavior
An SMTP test failure renders fixed actionable guidance but never renders the external adapter's arbitrary diagnostic.
The failed draft remains untested and cannot be activated.
## Test method
MockMvc saves a valid SMTP draft, configures the in-memory network adapter to throw a distinctive non-secret raw
diagnostic, and submits the authenticated CSRF-protected test action. It checks the production controller and
Thymeleaf response for the fixed message, absence of the raw diagnostic, and absence of the activation action.
## Hand-derived expected result
The response is HTTP 200 on `smtp/form`, contains the fixed operator message, omits the adapter diagnostic, and does
not offer Activate SMTP.
## 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=SmtpOnboardingWebIntegrationTest#failedSmtpTestRendersActionableFeedbackWithoutActivatingTheDraft test
```
**Observed result**
```text
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
The fixed guidance was absent and the rendered smtpActionError contained the adapter's distinctive diagnostic.
BUILD FAILURE
PostgreSQL: 18.4
```
## GREEN
**Command**
```text
./mvnw -Dtest=SmtpOnboardingWebIntegrationTest#failedSmtpTestRendersActionableFeedbackWithoutActivatingTheDraft test
```
**Observed result**
```text
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
PostgreSQL: 18.4
```
## Affected suite
**Command and result**
```text
./mvnw -Dtest=TimeConfigurationTest,BootstrapIntegrationTest,SmtpOnboardingWebIntegrationTest,AccountActivationIntegrationTest,AccountWebIntegrationTest,BootstrapOnboardingWebIntegrationTest,JavaMailSmtpProbeTest,SecurityResponseIntegrationTest test
Tests run: 22, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
PostgreSQL: 18.4
```
## External-test boundaries
The SMTP adapter is in-memory, so this does not prove live server interoperability. The diagnostic is a deterministic
non-secret fixture; no password, credential, or activation token is logged or recorded.
@@ -0,0 +1,76 @@
# Test Evidence: Sanitized production mail exception feedback
- **Test type:** Web
- **Requirement IDs:** `INT-005`, `INT-008`
- **Scenario IDs:** `AC-INT-002` (production mail-failure boundary)
- **Test class/method:** `com.lab.labtimesheet.feature.integration.controller.SmtpOnboardingWebIntegrationTest#failedSmtpTestRendersActionableFeedbackWithoutActivatingTheDraft`
- **Implementation commit:** `bf6f9af78b42151f2c26ef206978e3a55f75594a`
## Protected behavior
Spring Mail delivery failures from the production SMTP adapter return the fixed Admin guidance instead of escaping
the MVC request or exposing provider diagnostics. A failed probe does not mark the draft tested or enable activation.
## Test method
MockMvc saves a valid draft, then the test SMTP boundary throws Spring's production-shaped `MailSendException` with a
distinctive deterministic diagnostic. The authenticated CSRF-protected request crosses the real controller and SMTP
configuration service, and the rendered Thymeleaf response is inspected for the fixed message, raw-text absence, and
absence of the activation action.
## Hand-derived expected result
The response is HTTP 200 on `smtp/form`, contains the fixed operator guidance, omits the exception diagnostic, and
does not offer Activate SMTP because `markTested` was never reached.
## 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=SmtpOnboardingWebIntegrationTest#failedSmtpTestRendersActionableFeedbackWithoutActivatingTheDraft test
```
**Observed result**
```text
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
MailSendException escaped as ServletException with the distinctive diagnostic instead of rendering smtp/form.
BUILD FAILURE
PostgreSQL: 18.4
```
## GREEN
**Command**
```text
./mvnw -Dtest=SmtpOnboardingWebIntegrationTest#failedSmtpTestRendersActionableFeedbackWithoutActivatingTheDraft test
```
**Observed result**
```text
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
PostgreSQL: 18.4
```
## Affected suite
**Command and result**
```text
./mvnw -Dtest=TimeConfigurationTest,BootstrapIntegrationTest,SmtpOnboardingWebIntegrationTest,AccountActivationIntegrationTest,AccountWebIntegrationTest,BootstrapOnboardingWebIntegrationTest,JavaMailSmtpProbeTest,SecurityResponseIntegrationTest test
Tests run: 22, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
PostgreSQL: 18.4
```
## External-test boundaries
The test exercises the production Spring Mail exception type without contacting an external SMTP server. It does not
prove live Mailpit/provider interoperability and contains no real credential or activation token.