Skip to content

feat(supabase_test): stub failures, stalls, status sequences and text bodies - #1825

Merged
spydon merged 1 commit into
mainfrom
feat/supabase-test-stub-helpers
Sep 10, 2026
Merged

feat(supabase_test): stub failures, stalls, status sequences and text bodies#1825
spydon merged 1 commit into
mainfrom
feat/supabase-test-stub-helpers

Conversation

@spydon

@spydon spydon commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Adds the stubbing pieces that the package suites of this repo still hand-roll a BaseClient for. Each one comes from a test that could not be expressed with the current surface.

What is new

Helper Replaces
stubError(error, {times}) clients that throw ClientException('Offline') for the first N requests
stubStall() clients that never answer, so a timeout or an abort ends the request
stubStatuses([503, 503, 200]) clients that walk a retry through a sequence of statuses
stubText(body, {statusCode, contentType, reasonPhrase}) clients returning a non-JSON body, an HTML gateway error for example
RecordedRequest.request assertions on what does not survive the wire format, such as MultipartRequest.files

Two smaller changes in the same vein:

  • The auth shorthands (stubSignIn, stubSignUp, stubSignOut, stubUser) now answer their endpoint at the root too, where a bare AuthClient addresses it, and not only under the /auth/v1 prefix a SupabaseClient uses. The bare path is matched exactly, so a table named user is not caught by stubUser.
  • getSessionData in the internal library takes the user the session belongs to, instead of being pinned to one id.

Also in here

test/typed_api_test.dart still used TableColumn, which #1796 removed, so dart analyze and dart test were failing on main for this package. It now uses PostgrestColumn, which is what the rest of the repo moved to.

Notes

  • Everything is additive except the auth shorthand matching, which widens what those four stubs answer.
  • supabase_test is in .sdk-parse-ignore, so none of the new symbols need registering in sdk-compliance.yaml.
  • test: run the package suites on the supabase_test helpers #1827, stacked on this one, moves the package suites onto these helpers and deletes the hand-rolled clients.

Test plan

  • dart test in packages/supabase_test: 88 pass, with new groups covering each helper.
  • dart test in packages/supabase_auth (549) and packages/supabase (170) pass, covering the getSessionData and shorthand matching changes.
  • dart analyze and dart format clean.

… 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.
@spydon
spydon requested a review from a team as a code owner September 10, 2026 12:41
@spydon
spydon merged commit e16317a into main Sep 10, 2026
44 checks passed
@spydon
spydon deleted the feat/supabase-test-stub-helpers branch September 10, 2026 13:16
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 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants