# Sprint 11 Testplan — Verifying the Test Suite Quality

**Date:** 2026-06-15
**Sprint Theme:** Quality Foundation — Backend Test Coverage
**Author:** Patrick Plate / Roo (Architect)
**Status:** Draft v1
**Basis:** cannamanage-sprint11-plan.md

---

## Overview

This is a meta-testplan: since Sprint 11's deliverable IS test code, this document defines how we verify that the test suite itself is correct, complete, and maintainable.

## Verification Strategy

```mermaid
graph TD
    A[Tests Written] --> B[All Tests Pass]
    B --> C[Coverage Threshold Met]
    C --> D[Mutation Testing Sample]
    D --> E[Test Quality Checklist]
    E --> F[Sprint 11 DONE]
```

---

## Test Quality Criteria

### QC-01: All Tests Pass

| ID | Check | Pass Condition |
|----|-------|---------------|
| QC-01a | `mvn test -pl cannamanage-service` | Exit code 0 |
| QC-01b | `mvn test -pl cannamanage-api` | Exit code 0 |
| QC-01c | `mvn verify` (full project) | Exit code 0, JaCoCo check passes |
| QC-01d | No `@Disabled` annotations | 0 disabled tests |

### QC-02: Coverage Thresholds

| ID | Package | Minimum | Measurement |
|----|---------|---------|-------------|
| QC-02a | Overall project | ≥80% lines | JaCoCo aggregate |
| QC-02b | `de.cannamanage.service.bankimport` | ≥90% lines | JaCoCo per-package |
| QC-02c | `de.cannamanage.service.FinanceService` | ≥90% lines | JaCoCo per-class |
| QC-02d | `de.cannamanage.api.security` | ≥80% lines | JaCoCo per-package |
| QC-02e | `de.cannamanage.service` (compliance classes) | ≥90% lines | JaCoCo per-class |
| QC-02f | `de.cannamanage.service` (business logic) | ≥75% lines | JaCoCo per-package |

### QC-03: Test Isolation

| ID | Check | Pass Condition |
|----|-------|---------------|
| QC-03a | Tests run in any order | `mvn test -Dsurefire.runOrder=random` passes |
| QC-03b | Tests are independent | No shared mutable state between tests |
| QC-03c | No external dependencies in unit tests | Unit tests pass without Docker/network |
| QC-03d | Integration tests use Testcontainers | No hardcoded DB connection strings |

### QC-04: Test Quality (Structural)

| ID | Check | Pass Condition |
|----|-------|---------------|
| QC-04a | Meaningful assertions | No `assertTrue(true)` or bare `assertNotNull` |
| QC-04b | Each test has exactly one reason to fail | One logical assertion per test |
| QC-04c | Test naming follows convention | `test<Method>_<Scenario>_<Expected>` or `@DisplayName` |
| QC-04d | Given-When-Then structure | Clear arrange/act/assert sections |
| QC-04e | Edge cases covered | Null, empty, boundary, error paths |
| QC-04f | No hardcoded UUIDs shared between tests | Each test creates its own test data |

### QC-05: Financial Precision

| ID | Check | Pass Condition |
|----|-------|---------------|
| QC-05a | All amounts tested in cents (Integer) | No floating-point in financial assertions |
| QC-05b | Rounding edge cases covered | e.g., 1/3 split, odd-cent distribution |
| QC-05c | Ledger entries always sum to zero | Every credit has offsetting debit |
| QC-05d | Void operation creates exact reversal | Original + reversal = 0 |

### QC-06: Security Test Completeness

| ID | Check | Pass Condition |
|----|-------|---------------|
| QC-06a | XXE attack rejected | Camt053Parser doesn't process external entities |
| QC-06b | Path traversal sanitized | `../` removed from filenames |
| QC-06c | Token expiry enforced | Expired JWT returns 401 |
| QC-06d | Tenant isolation holds | Cross-club access returns 403 |
| QC-06e | Rate limiter blocks after threshold | 6th attempt blocked |

---

## Mutation Testing (Spot-Check)

To verify tests actually catch bugs (not just increase coverage), run mutation testing on 3 critical classes:

| Class | Tool | Target Mutation Score |
|-------|------|---------------------|
| `PaymentMatchingService` | PITest (manual spot-check) | ≥70% mutants killed |
| `FinanceService` | PITest (manual spot-check) | ≥70% mutants killed |
| `Mt940Parser` | PITest (manual spot-check) | ≥70% mutants killed |

PITest command (optional — stretch goal):
```bash
mvn org.pitest:pitest-maven:mutationCoverage \
  -pl cannamanage-service \
  -DtargetClasses=de.cannamanage.service.bankimport.PaymentMatchingService \
  -DtargetTests=de.cannamanage.service.bankimport.PaymentMatchingServiceTest
```

---

## Traceability Matrix

Every plan phase maps to a verification:

| Plan Phase | Test Class | QC Checks |
|-----------|-----------|-----------|
| Phase 1 (Infrastructure) | N/A — verified by Phase 2+ tests running | QC-01c |
| Phase 2 (Financial) | FinanceServiceTest, PaymentMatchingServiceTest, Mt940ParserTest, Camt053ParserTest, CsvBankParserTest, BankImportServiceTest, RetentionServiceTest, ReportGeneratorServiceTest, EurReportGeneratorTest, AnnualAuthorityReportGeneratorTest | QC-02b, QC-02c, QC-05 |
| Phase 3 (Business) | AssemblyServiceTest, EventServiceTest, ForumServiceTest, InfoBoardServiceTest, NotificationDispatchServiceTest | QC-03, QC-04 |
| Phase 4 (Security) | JwtServiceTest, LoginRateLimiterTest, TenantFilterAspectTest, DocumentServiceTest | QC-02d, QC-06 |
| Phase 5 (Integration) | BankImportIntegrationTest, FinanceIntegrationTest, AssemblyIntegrationTest, ReportIntegrationTest | QC-01b, QC-03d |
| Phase 6 (CI) | Full `mvn verify` | QC-01c, QC-02a |

---

## Test Execution Order

```bash
# Step 1: Run unit tests only (fast feedback)
mvn test -pl cannamanage-service

# Step 2: Run API unit tests
mvn test -pl cannamanage-api -Dgroups=\!integration

# Step 3: Run integration tests (requires Docker)
mvn test -pl cannamanage-api -Dgroups=integration

# Step 4: Full verify with coverage check
mvn verify

# Step 5: Generate HTML coverage report
# → open cannamanage-service/target/site/jacoco/index.html
# → open cannamanage-api/target/site/jacoco/index.html
```

---

## Acceptance Criteria for Sprint 11 Completion

| # | Criterion | Verified By |
|---|-----------|-------------|
| 1 | `mvn verify` passes with 0 failures | CI or local run |
| 2 | JaCoCo reports ≥80% overall line coverage | JaCoCo HTML report |
| 3 | Financial/compliance packages at ≥90% | JaCoCo per-package |
| 4 | Security packages at ≥85% (incl. GlobalExceptionHandler) | JaCoCo per-package |
| 5 | Infrastructure (Schedulers + Notifications) at ≥70% | JaCoCo per-package |
| 6 | No `@Disabled` or `@Ignored` tests | grep scan |
| 7 | Tests pass in random order | `surefire.runOrder=random` |
| 8 | Integration tests work with fresh Testcontainers | Clean Docker environment |
| 9 | ≥345 total backend tests (from ~20) | Surefire report count |
| 10 | Build time stays under 7 minutes total | Maven timing output (forkCount=2) |
| 11 | Mutation testing spot-check ≥70% on 3 critical classes | PITest results |

---

## Risk Mitigation

| Risk | Mitigation | Verification |
|------|-----------|-------------|
| Flaky tests (intermittent failures) | No shared state, deterministic data | Random order pass (QC-03a) |
| Slow integration tests | Tag with `@Tag("integration")`, run separately | Split fast/slow in CI |
| Tests pass but don't catch bugs | Mutation testing spot-check | PITest on 3 classes |
| Coverage gaming (meaningless assertions) | QC-04 structural quality checks | Code review of tests |
| Docker unavailable in CI | Testcontainers cloud support OR separate CI stage | CI pipeline design |
