feat(supabase_test): stub failures, stalls, status sequences and text bodies - #1825
Merged
Conversation
… bodies Adds the pieces a test needed a hand-rolled `BaseClient` for: - `stubError` throws instead of answering, so offline and retry handling can be exercised, and `times` limits it to the first requests. - `stubStall` never answers, so only a timeout or an abort ends the request. - `stubStatuses` answers a sequence of statuses, one per request, and repeats the last one once they run out. - `stubText` answers with a body that is not JSON, under its own content type and reason phrase. - `RecordedRequest.request` holds the request the client received, so a multipart upload can be asserted on through its `files`. - The auth shorthands now answer their endpoint at the root as well, where a bare `AuthClient` addresses it, not just under the `/auth/v1` prefix. - `getSessionData` takes the user the session belongs to. Also moves the typed api test off `TableColumn`, which was removed in #1796, so the package suite runs again.
Tr00d
approved these changes
Sep 10, 2026
spydon
added a commit
that referenced
this pull request
Sep 10, 2026
Stacked on #1825. Review that one first; this PR targets its branch. `supabase_test` tells app authors to test against a real client with a stubbed HTTP layer, while the package suites of this repo still hand-rolled a `BaseClient` per test file. This moves them onto the same helpers, which is both a smaller diff to maintain and a continuous check that the published helpers actually cover real testing needs. Net **-604 lines**. ## What changed **28 hand-rolled mock clients removed**, replaced by `MockSupabaseHttpClient`: | Package | Files | |---|---| | postgrest | `filter_escape_test`, `maybe_single_test`, `stack_trace_test`, `typed_query_test` | | supabase | `api_key_test`, `trace_propagation_test`, `postgrest_options_test` | | supabase_auth | `admin_delete_user_test`, `admin_list_users_test`, `auto_refresh_dispose_test`, `client_test`, `custom_http_client`, `fetch_test`, `get_session_test`, `header_isolation_test`, `mfa_challenge_mock_test`, `mfa_enroll_test`, `refresh_retry_test`, `refresh_token_race_test`, `src/set_session_test`, `sso_mock_test` | | supabase_storage | `basic_test`, `client_test`, `fetch_test`, `path_encoding_test`, `path_normalization_test`, `vector_test` | | supabase_flutter | `widget_test_stubs`, `deep_link_test`, `initialization_test` | | supabase_typegen | `generated_schema_behavior_test` | Two shared helper files are deleted outright: `supabase_storage/test/custom_http_client.dart` and `supabase_auth/test/mocks/sso_mock_client.dart`. `supabase_auth/test/custom_http_client.dart` loses `MockedHttpClient` and `RawBodyHttpClient`. **Assertions** move from per-mock `lastRequest`, `lastRequestBody`, `receivedRequests` and `requestCount` fields onto `requests`, `requestsTo` and `RecordedRequest`, so `jsonDecode((request as Request).body)` becomes `request.jsonBody`. **Fixtures replace inline copies**: `signedTestJwt` replaces `dart_jsonwebtoken` in the three tests that minted access tokens, and `testUserJson`, `testSessionResponseJson` and `getSessionData` replace hand-written user and session payloads. ## Behaviour worth a second look - `auto_refresh_dispose_test` used a client that called `fail()` on any request. It now uses a stubless mock, which throws on an unexpected request, plus an explicit `expect(httpClient.requests, isEmpty)` in `tearDown`. - `header_isolation_test` uses `stubUser`, and its admin case stubs `/admin/users/<id>` explicitly, since the admin API reads a user through its own endpoint. - `supabase_typegen` gains `supabase_test` as a dev dependency and drops `http`. ## Test plan Per package, against the local stack: supabase_test 88, supabase 170, postgrest 346, supabase_auth 549, supabase_storage 272, supabase_typegen 64, supabase_flutter 85. All pass except `client_test.dart: Signed upload URL cannot upload to a signed url twice` in supabase_storage, which fails on `main` too on a local CLI newer than the pinned 2.109.1 (`KeyAlreadyExists` instead of `Duplicate`). `dart analyze` and `dart format` clean across all packages. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Tests** - Standardized HTTP request simulation and response handling across authentication, database, storage, Flutter, and type-generation test suites. - Improved coverage and consistency for request headers, query parameters, JSON payloads, retries, errors, and authentication flows. - Preserved existing test behavior while simplifying test setup and request inspection. - **Chores** - Removed obsolete test-only HTTP helpers and unused testing dependencies. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.
Adds the stubbing pieces that the package suites of this repo still hand-roll a
BaseClientfor. Each one comes from a test that could not be expressed with the current surface.What is new
stubError(error, {times})throw ClientException('Offline')for the first N requestsstubStall()stubStatuses([503, 503, 200])stubText(body, {statusCode, contentType, reasonPhrase})RecordedRequest.requestMultipartRequest.filesTwo smaller changes in the same vein:
stubSignIn,stubSignUp,stubSignOut,stubUser) now answer their endpoint at the root too, where a bareAuthClientaddresses it, and not only under the/auth/v1prefix aSupabaseClientuses. The bare path is matched exactly, so a table nameduseris not caught bystubUser.getSessionDatain the internal library takes the user the session belongs to, instead of being pinned to one id.Also in here
test/typed_api_test.dartstill usedTableColumn, which #1796 removed, sodart analyzeanddart testwere failing onmainfor this package. It now usesPostgrestColumn, which is what the rest of the repo moved to.Notes
supabase_testis in.sdk-parse-ignore, so none of the new symbols need registering insdk-compliance.yaml.Test plan
dart testinpackages/supabase_test: 88 pass, with new groups covering each helper.dart testinpackages/supabase_auth(549) andpackages/supabase(170) pass, covering thegetSessionDataand shorthand matching changes.dart analyzeanddart formatclean.