Files
curo1305 f0ba9e6d8e docs(07.2-01): complete Wave 0 test scaffolding plan — SUMMARY
- FakeRedis mounted on test_auth_deps and admin_client fixtures
- 9 xfail(strict=False) stubs covering all Phase 7.2 behaviors
- 73 baseline tests pass, zero regressions
2026-06-05 19:10:03 +02:00

7.1 KiB
Raw Permalink Blame History

phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
phase plan subsystem tags dependency_graph tech_stack key_files decisions metrics
07.2-security-jti-claim-redis-access-token-revocation-inserted 01 testing
security
jwt
testing
nyquist
wave-0
requires provides affects
FakeRedis on test_auth_deps app.state.redis (Pitfall 4 guard)
FakeRedis on admin_client fixture app.state.redis (Pitfall 4 guard)
Wave 0 xfail stub: jti claim in create_access_token
Wave 0 xfail stubs: NBF check accept/reject/fail-open in get_current_user
Wave 0 xfail stubs: user_nbf write on change_password/enable_totp/disable_totp/admin-deactivation
backend/tests/test_auth_deps.py
backend/tests/test_task2_auth_service.py
backend/tests/test_auth_api.py
backend/tests/test_admin_api.py
added patterns
Wave 0 xfail(strict=False) scaffolding — stubs flip to xpass when Wave 1/2 implementation lands
FakeRedis imported from tests.test_auth_api (single canonical definition, never redefined)
app.state.redis = FakeRedis() set in fixture before yield, reset to None in teardown
created modified
backend/tests/test_auth_deps.py
backend/tests/test_task2_auth_service.py
backend/tests/test_auth_api.py
backend/tests/test_admin_api.py
Import FakeRedis from tests.test_auth_api — no redefinition in any file
FakeRedis instantiated inside make_test_app() so each test invocation gets fresh state
admin_client teardown resets app.state.redis = None to mirror authed_client convention
Wave 0 stubs use pytest.xfail() call inside body (not just marker) for the three NBF-write tests, consistent with minimal-body convention
test_activate_user_does_not_write_user_nbf added as negative-guard (mirrors RESEARCH.md anti-pattern)
duration completed_date tasks_completed tasks_total files_changed
450s (7m) 2026-06-05T17:08:58Z 4 4 4

Phase 07.2 Plan 01: Wave 0 Test Scaffolding Summary

One-liner: FakeRedis mounted on two test fixtures + 9 xfail stubs covering every Phase 7.2 behavior (jti, NBF check × 3, NBF write × 4, negative-guard × 1).

What Was Built

This plan is the Nyquist Wave 0 scaffolding for Phase 7.2. It creates no implementation code — only test stubs that define the expected behaviors before any code in services/auth.py, deps/auth.py, api/auth.py, or api/admin.py is modified.

Task 1: FakeRedis on test_auth_deps + NBF-check stubs

  • test_auth_deps.py: added from tests.test_auth_api import FakeRedis import
  • make_test_app(): now sets test_app.state.redis = FakeRedis() before returning
  • Added 3 xfail stubs with @pytest.mark.xfail(strict=False):
    • test_get_current_user_rejects_token_when_iat_before_user_nbf
    • test_get_current_user_allows_token_when_iat_after_user_nbf
    • test_get_current_user_failopen_on_redis_error (uses inline _BrokenRedis class)

Task 2: JTI presence stub in test_task2_auth_service.py

  • Added test_create_access_token_includes_jti_claim decorated with xfail(strict=False)
  • Calls create_access_token + decode_access_token, asserts "jti" key present and parseable as uuid.UUID

Task 3: NBF-write stubs for change_password/enable_totp/disable_totp

  • Added 3 xfail stubs to test_auth_api.py:
    • test_change_password_writes_user_nbf_to_redis
    • test_enable_totp_writes_user_nbf_to_redis
    • test_disable_totp_writes_user_nbf_to_redis
  • Each test exercises the full auth flow then calls pytest.xfail() as the Wave 0 body

Task 4: FakeRedis on admin_client + deactivation NBF-write stubs

  • test_admin_api.py: added from tests.test_auth_api import FakeRedis
  • admin_client fixture: sets app.state.redis = FakeRedis() before client yield, resets to None after
  • Added 2 xfail stubs:
    • test_deactivate_user_writes_user_nbf_to_redis (positive case)
    • test_activate_user_does_not_write_user_nbf (negative-guard — activation must NOT write user_nbf)

Verification

Baseline container test run: 73 passed (across the 4 modified test files) — zero new failures.

Full project baseline: 373 passed (Phase 7.1 complete state) — confirmed unaffected.

Acceptance criteria checks:

  • grep -c "FakeRedis" test_auth_deps.py → 6 (import + assignment + stubs)
  • grep -c "test_app.state.redis" test_auth_deps.py → 1
  • 3 new NBF-check test functions in test_auth_deps.py
  • 3 xfail markers in test_auth_deps.py
  • test_create_access_token_includes_jti_claim in test_task2_auth_service.py
  • 3 NBF-write test functions in test_auth_api.py
  • from tests.test_auth_api import FakeRedis in test_admin_api.py
  • app.state.redis = FakeRedis() in admin_client fixture
  • 2 deactivation NBF stubs in test_admin_api.py

Commits

Task Commit Description
1 49c6333 test(07.2-01): mount FakeRedis on test_auth_deps app + add NBF-check xfail stubs
2 c686d90 test(07.2-01): add JTI claim xfail stub to test_task2_auth_service.py
3 097cdca test(07.2-01): add NBF-write xfail stubs for change_password/enable_totp/disable_totp
4 eb16472 test(07.2-01): add FakeRedis to admin_client + NBF-write xfail stubs for deactivation

Deviations from Plan

None — plan executed exactly as written.

Known Stubs

All 9 new test functions are intentional Wave 0 stubs. They are xfailed with strict=False and carry assert False, "stub" or pytest.xfail() in their bodies. Wave 1 (Plan 02) and Wave 2 (Plan 03) will promote them to passing assertions by replacing the stub bodies with real assertion logic. These are tracked in the plan and are the intended output of this wave.

Patterns Established

  • FakeRedis import pattern: always from tests.test_auth_api import FakeRedis — never redefine in another file
  • FakeRedis on test_auth_deps: test_app.state.redis = FakeRedis() inside make_test_app() — fresh instance per test invocation
  • FakeRedis teardown: app.state.redis = None after fixture yield — prevents state leak across test files
  • Wave 0 body convention: assert False, "stub — Wave N will fill in: <target assertion>" or pytest.xfail("stub") — no real assertion logic

Patterns to Avoid

  • Do NOT redefine FakeRedis in test_auth_deps.py, test_admin_api.py, or any other file — import from tests.test_auth_api only
  • Do NOT add app.state.redis = None reset inside the fixture loop — only in teardown after yield

Threat Flags

None — this plan only modifies test files and introduces no new network endpoints, auth paths, or schema changes.

Self-Check: PASSED

  • backend/tests/test_auth_deps.py modified and committed (49c6333)
  • backend/tests/test_task2_auth_service.py modified and committed (c686d90)
  • backend/tests/test_auth_api.py modified and committed (097cdca)
  • backend/tests/test_admin_api.py modified and committed (eb16472)
  • All 4 commits exist: git log --oneline -4 confirms eb16472, 097cdca, c686d90, 49c6333
  • 73 baseline tests pass in container (zero regressions)
  • All 9 Wave 0 stubs present and correctly decorated with xfail(strict=False)