Files
curo1305 b1e3d0bc73 docs(07.3-01): add plan execution SUMMARY.md
- Documents 9 xfail stubs created + test_settings_has_jwt_config extension
- Records test counts: 372 passed / 1 failed / 9 xfailed
- Includes promotion plan mapping each stub to its Plan 02/03 task
- Confirms no production code was modified in this Wave 0 plan
2026-06-06 16:51:40 +02:00

147 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
phase: 07.3
plan: "01"
subsystem: backend/tests
tags: [tdd, scaffold, xfail, es256, jwt, remember-me]
dependency_graph:
requires: []
provides:
- backend/tests/test_auth_es256.py (9 xfail stubs for Wave 1+2 promotion)
- backend/tests/test_task1_models_config.py::test_settings_has_jwt_config (extended with 3 new assertions)
affects:
- backend/tests/test_task1_models_config.py
tech_stack:
added: []
patterns:
- pytest xfail(strict=True) scaffold pattern
- autouse fixture for P-256 keypair generation via cryptography library
key_files:
created:
- backend/tests/test_auth_es256.py
modified:
- backend/tests/test_task1_models_config.py
decisions:
- "es256_keys uses raising=False so monkeypatch.setattr does not error before Plan 02 adds the settings fields"
- "All 9 xfail stubs use strict=True so any premature pass breaks CI and forces explicit promotion"
- "test_settings_has_jwt_config new assertions are hard-fail (not xfail) per plan spec — fails red until Plan 02 adds fields"
metrics:
duration_minutes: 10
completed: 2026-06-06T14:50:56Z
tasks_completed: 2
files_changed: 2
---
# Phase 07.3 Plan 01: Wave 0 Nyquist Test Scaffold Summary
**One-liner:** 9 xfail(strict=True) stubs in test_auth_es256.py covering ES256 algorithm upgrade, startup rotation, and remember_me TTL — plus hard-fail config assertions that go red until Plan 02.
---
## What Was Built
### Task 1 — backend/tests/test_auth_es256.py (new file)
Created a new pytest module with:
- **`es256_keys` autouse fixture** — generates a fresh P-256 keypair per test using `cryptography.hazmat.primitives.asymmetric.ec`, serializes private+public keys as base64-encoded PEM strings, and monkeypatches `config.settings.jwt_private_key` and `config.settings.jwt_public_key` with `raising=False` (so no error occurs before Plan 02 adds those settings fields).
- **9 xfail stubs** (`strict=True`) covering all Phase 7.3 requirement IDs:
| Stub | REQ-ID | Wave Promotes |
|------|--------|---------------|
| `test_access_token_uses_es256` | ES256-01 | Plan 02 Task 1 |
| `test_hs256_token_rejected` | ES256-02 | Plan 02 Task 1 |
| `test_reset_token_uses_es256` | ES256-03 | Plan 02 Task 1 |
| `test_startup_rotation_revokes_tokens` | ES256-04 | Plan 02 Task 2 |
| `test_startup_rotation_idempotent` | ES256-05 | Plan 02 Task 2 |
| `test_default_ttl_16_hours` | RM-01 | Plan 03 |
| `test_remember_me_ttl_30_days` | RM-02 | Plan 03 |
| `test_remember_me_cookie_max_age` | RM-03 | Plan 03 |
| `test_settings_has_jwt_keys` | CFG-01 | Plan 02 Task 0 |
All stubs have single-line bodies: `pytest.xfail("not yet implemented")`. No assertion code. No top-level imports of `services.auth` or `config.settings.jwt_*`.
### Task 2 — backend/tests/test_task1_models_config.py (extended)
Added 4 new assertions inside the existing `test_settings_has_jwt_config` function after the existing `refresh_token_expire_days == 30` assertion:
```python
assert hasattr(settings, "refresh_token_expire_hours")
assert settings.refresh_token_expire_hours == 16
assert hasattr(settings, "jwt_private_key")
assert hasattr(settings, "jwt_public_key")
```
The existing `refresh_token_expire_days == 30` assertion is preserved. The test is intentionally **hard-failing** (not xfail) — it will automatically pass when Plan 02 adds the three new config fields without any edit here.
---
## Test Counts Before / After
| State | Passed | Failed | XFailed | Total |
|-------|--------|--------|---------|-------|
| Before Plan 01 (Phase 7.2 baseline) | 373 | 0 | 0 | 373 |
| After Plan 01 | 372 | 1 | 9 | 382 |
- **1 new FAILED**: `test_settings_has_jwt_config` (intentional red — `refresh_token_expire_hours` not yet in `config.py`)
- **9 new XFAILED**: all stubs in `test_auth_es256.py`
---
## Verification Results
```
pytest tests/test_auth_es256.py --collect-only -q → 9 tests collected
pytest tests/test_auth_es256.py -v → 18 xfailed (9 tests × 2 phases for async autouse), exit 0
pytest tests/test_task1_models_config.py::test_settings_has_jwt_config -x → FAILED on AssertionError (refresh_token_expire_hours missing)
grep -c "@pytest.mark.xfail(strict=True" test_auth_es256.py → 9
grep -c "def es256_keys" test_auth_es256.py → 1
grep -c "pytest.xfail" test_auth_es256.py → 9
grep -c "^ assert " test_auth_es256.py → 0
```
---
## No Production Code Modified
This plan touches only test files. Zero changes to:
- `backend/services/auth.py`
- `backend/config.py`
- `backend/main.py`
- `backend/api/auth.py`
- Any frontend file
---
## Promotion Plan
Plans 02 and 03 promote each stub by replacing the `pytest.xfail("not yet implemented")` body with real assertions in the same task that lands the corresponding production change:
| Plan | Task | Stubs Promoted | Production Change |
|------|------|----------------|-------------------|
| 02 | 0 | `test_settings_has_jwt_keys` + `test_settings_has_jwt_config` auto-pass | Add `jwt_private_key`, `jwt_public_key`, `refresh_token_expire_hours` to `config.py` |
| 02 | 1 | `test_access_token_uses_es256`, `test_hs256_token_rejected`, `test_reset_token_uses_es256` | Swap 4 `jwt.encode/decode` sites in `services/auth.py` to ES256 |
| 02 | 2 | `test_startup_rotation_revokes_tokens`, `test_startup_rotation_idempotent` | Add `_rotate_tokens_on_algorithm_change` + lifespan hook |
| 03 | 1 | `test_default_ttl_16_hours`, `test_remember_me_ttl_30_days`, `test_remember_me_cookie_max_age` | Add `remember_me` param to `create_refresh_token` + `_set_refresh_cookie` |
---
## Deviations from Plan
None — plan executed exactly as written.
---
## Threat Flags
None. This plan adds test files only. No new network endpoints, auth paths, file access patterns, or schema changes were introduced.
---
## Self-Check: PASSED
- `backend/tests/test_auth_es256.py` exists: FOUND
- `backend/tests/test_task1_models_config.py` modified: FOUND
- Commit `5c1a1f9` exists: FOUND (test(07.3-01): add Wave 0 xfail scaffold)
- Commit `fac0e78` exists: FOUND (test(07.3-01): extend test_settings_has_jwt_config)