Tracking ticket for the Lessons + code-execution/grading integration test expansion (see lessons_integration_tests plan; spikersoft-issues#448 for Phase 0-2, spikersoft-issues#449 for Phase 3).
Shipped in spikersoft-backend#176 (merged):
Phase 4: POST /{n}/complete-tutorial covered end-to-end for Tutorial-kind lessons (records progress directly, no worker needed) vs Challenge-kind lessons (400 - must go through /CodeRunner/lesson); a re-click on an already-completed tutorial with a stale/forged token is an idempotent 200 no-op rather than 410; a forged token on a never-completed lesson is hard-rejected with 410 and writes zero progress state. Anti-spoof: an otherwise-correct C# solution submitted against an expired (Redis-deleted) or foreign (issued for a different lesson) attempt token is accepted with 202 but the worker's own attempt-cache lookup rejects it before grading runs, so CompletedAt never advances - proving the token check is enforced by the worker itself, not just the controller.
Side finding: discovered and filed spikersoft-issues#450 for a pre-existing (not introduced by this work) test-host teardown flake where dotnet test reports every test as Passed but exits non-zero once 3+ Lessons integration test classes share the TestContainers collection in one run.
Still to come (follow-up PR, same plan):
Phase 5: capability-gated Python/Node/C/C++ grading loop with controller-level 202+publish fallback.
Definition of green: full integration suite passes locally (Docker up), no regressions to the pre-existing tests.
Tracking ticket for the Lessons + code-execution/grading integration test expansion (see `lessons_integration_tests` plan; spikersoft-issues#448 for Phase 0-2, spikersoft-issues#449 for Phase 3).
**Shipped** in spikersoft-backend#176 (merged):
- Phase 4: `POST /{n}/complete-tutorial` covered end-to-end for Tutorial-kind lessons (records progress directly, no worker needed) vs Challenge-kind lessons (400 - must go through `/CodeRunner/lesson`); a re-click on an already-completed tutorial with a stale/forged token is an idempotent 200 no-op rather than 410; a forged token on a never-completed lesson is hard-rejected with 410 and writes zero progress state. Anti-spoof: an otherwise-correct C# solution submitted against an expired (Redis-deleted) or foreign (issued for a different lesson) attempt token is accepted with 202 but the worker's own attempt-cache lookup rejects it before grading runs, so `CompletedAt` never advances - proving the token check is enforced by the worker itself, not just the controller.
**Side finding**: discovered and filed spikersoft-issues#450 for a pre-existing (not introduced by this work) test-host teardown flake where `dotnet test` reports every test as `Passed` but exits non-zero once 3+ Lessons integration test classes share the `TestContainers` collection in one run.
**Still to come** (follow-up PR, same plan):
- Phase 5: capability-gated Python/Node/C/C++ grading loop with controller-level 202+publish fallback.
Definition of green: full integration suite passes locally (Docker up), no regressions to the pre-existing tests.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Tracking ticket for the Lessons + code-execution/grading integration test expansion (see
lessons_integration_testsplan; spikersoft-issues#448 for Phase 0-2, spikersoft-issues#449 for Phase 3).Shipped in spikersoft-backend#176 (merged):
POST /{n}/complete-tutorialcovered end-to-end for Tutorial-kind lessons (records progress directly, no worker needed) vs Challenge-kind lessons (400 - must go through/CodeRunner/lesson); a re-click on an already-completed tutorial with a stale/forged token is an idempotent 200 no-op rather than 410; a forged token on a never-completed lesson is hard-rejected with 410 and writes zero progress state. Anti-spoof: an otherwise-correct C# solution submitted against an expired (Redis-deleted) or foreign (issued for a different lesson) attempt token is accepted with 202 but the worker's own attempt-cache lookup rejects it before grading runs, soCompletedAtnever advances - proving the token check is enforced by the worker itself, not just the controller.Side finding: discovered and filed spikersoft-issues#450 for a pre-existing (not introduced by this work) test-host teardown flake where
dotnet testreports every test asPassedbut exits non-zero once 3+ Lessons integration test classes share theTestContainerscollection in one run.Still to come (follow-up PR, same plan):
Definition of green: full integration suite passes locally (Docker up), no regressions to the pre-existing tests.