Lay out the test tiers: unit, database and API - #38
Merged
Conversation
The suite was one domain project against the whole codebase, with nowhere to put a test that needs a database or the host. Three tiers now, as agreed in #37: - `Ssabba.TestSupport` holds `PostgresFixture`, a Testcontainers Postgres migrated once per collection, plus the `Category=Integration` trait so `dotnet test --filter "Category!=Integration"` still works without a container runtime. - `Ssabba.Infrastructure.Tests` proves the migrations apply cleanly and leave no pending model changes. - `Ssabba.Web.Tests` boots the real host through `WebApplicationFactory<Program>` against the same container, with `TestAuthHandler` standing in for the Keycloak handshake — the only substitute in the suite. No mocking library. Booting the host turned up a real defect: `UseStatusCodePagesWithReExecute` re-executes with the original method, so an unauthorized API POST came back as the Blazor page's 400 instead of 401. The UI keeps the re-execution; `/api` no longer does. CI runs the two tiers as separate steps so a failure names the tier. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9TP5WEbVsmAWQS4uAds3Q
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Puts the three test tiers from #37 in place, with a working example in each. No feature coverage
yet — that is #34 and the tiers it now has somewhere to live in.
Layout
tests/Ssabba.TestSupportPostgresFixture— a Testcontainerspostgres:18-alpine, migrated once per collection, plusResetAsyncand theCategory=Integrationtrait constantstests/Ssabba.Infrastructure.TestsSsabbaDbContextand the migrations against the real providertests/Ssabba.Web.TestsWebApplicationFactory<Program>against the same containerEach test assembly declares its own
PostgresDatabasecollection: xUnit requires the collectiondefinition to live in the assembly that uses it.
No mocking library is added. The only substitute in the suite is
TestAuthHandler, a hand-writtenstand-in for the Keycloak handshake; requests opt into a signed-in identity with
factory.CreateClientAs("ada").Running it
CI runs the two tiers as separate steps so a failure names the tier.
A defect the API tier found
UseStatusCodePagesWithReExecutere-executes with the original request method, so an unauthorizedPOST /api/matcheswas re-run against the Blazor/not-foundpage and came back as 400 "Therequest has an incorrect Content-type." instead of 401 — any API client would have seen the wrong
status. The re-execution is now scoped to non-
/apipaths. Written up in #39; #40 covers the structural follow-up.Program.csalso gainedpublic partial class Program;so the factory can name the host.Verification
dotnet build Ssabba.slnx -c Release— clean, warnings-as-errorsdotnet test Ssabba.slnx -c Release— 22 domain, 2 infrastructure, 3 API, all greendotnet format Ssabba.slnx --verify-no-changes— cleanPart of #37.
🤖 Generated with Claude Code
https://claude.ai/code/session_01F9TP5WEbVsmAWQS4uAds3Q