Skip to content

test(utils): add unit tests, coverage in CI and a README - #1982

Merged
spydon merged 2 commits into
mainfrom
lukasklingsbo/sdk-2706-utils-tests-ci-readme
Nov 5, 2026
Merged

spydon merged 2 commits into
mainfrom
lukasklingsbo/sdk-2706-utils-tests-ci-readme

Conversation

@spydon

@spydon spydon commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Resolves SDK-2706.

supabase_utils is the shared HTTP layer every v3 package builds on. Before this change it had no tests, its CI job only ran pyrefly, and its README was empty.

Changes

  • Tests in src/utils/tests, covering 100% of the package:
    • Headers: case insensitivity, repeated values, override, update, immutability and X-Client-Info.
    • URLQuery: repeated values, merge, immutability and encoding into a yarl.URL.
    • Request builders: URL and header merging, default and explicit Content-Type, JSON bodies from dicts and pydantic models (exclude_none), text, multipart encoding, and Response.is_success / is_error bounds.
    • Executor: SyncHttpIO and AsyncHttpIO with multi-request generators, delay, methods that send no request and error propagation. handle_http_io with both executors and its preserved name, docstring and signature.
    • Adapters: httpx through httpx.MockTransport (sync and async) and aiohttp against a local aiohttp.test_utils.TestServer, including closing the client when the context manager exits.
  • CI: utils was already in the matrix, but make utils.tests only ran pyrefly. It now runs pytest with coverage like the other packages, and the Coveralls upload no longer skips utils (PACKAGES_WITHOUT_COVERAGE is removed from ci_matrix.py).
  • Packaging: a tests dependency group (pytest, pytest-cov, pytest-asyncio), pytest configuration, and pyrefly now checks tests as well.
  • README: what the package is for, which extra to install, how the generator based executor works, and how to write an adapter, with a requests example.

Found while testing, not changed here

  • QueryValue includes bool, but yarl raises TypeError for bool query values, so URLQuery.from_mapping({"flag": True}) fails when the request is finalized. No caller passes a bool today.
  • Headers.from_mapping keeps only the last value of a repeated response header from aiohttp (for example several Set-Cookie headers), because a multidict yields every value as its own item and from_mapping overwrites the key.

@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • Documentation
    • Added a guide to the shared HTTP utilities, including adapter usage and request handling.
  • Tests
    • Expanded coverage for HTTP adapters, requests and responses, headers, queries, and synchronous and asynchronous request flows.
  • Chores
    • Coverage reporting now includes all packages, including the utilities package.

The utility package gains tests for HTTP primitives, synchronous and asynchronous HTTP I/O, and the aiohttp and HTTPX adapters. Its development configuration adds pytest dependencies and settings, and its Makefile adds a pytest target with coverage reports. A new README documents package usage and adapter behavior. The CI matrix and workflow now include utils in coverage flags and Coveralls uploads.

Possibly related PRs

Change: Other

Merge Risk: Minimal · up to 6027e

No actionable merge-blocking issue is established. The testing, documentation, and coverage changes appear mergeable subject to normal checks.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share
Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 894d6a55-ac21-4bff-88d8-003cc8de7d3e
Commits

Reviewing files that changed from the base of the PR and between cadbdfe and 6027e61.

Files ignored due to path filters: 1
  • uv.lock is excluded by !**/*.lock
Files selected for processing: 12
  • .github/scripts/ci_matrix.py
  • .github/workflows/ci.yml
  • src/utils/Makefile
  • src/utils/README.md
  • src/utils/pyproject.toml
  • src/utils/tests/__init__.py
  • src/utils/tests/test_aiohttp_adapter.py
  • src/utils/tests/test_headers.py
  • src/utils/tests/test_httpx_adapter.py
  • src/utils/tests/test_io.py
  • src/utils/tests/test_query.py
  • src/utils/tests/test_request.py

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 3 remain after this review.

@spydon
spydon merged commit c2056b5 into main Nov 5, 2026
57 checks passed
@spydon
spydon deleted the lukasklingsbo/sdk-2706-utils-tests-ci-readme branch November 5, 2026 08:46
spydon added a commit that referenced this pull request Nov 9, 2026
…uide (#2017)

## Summary

SDK-2702 asks for SDK-owned `Request`, `Response` and `Headers` types, a
`send(request) -> Response` adapter protocol, httpx confined to its
adapter, and a README that shows how to write an adapter. All of that
already landed in #1977 (httpx only inside the adapter, guarded by the
`import-without-httpx` job in the CI workflow) and #1982 (the README).
This finishes the ticket by bringing the adapter guide up to date with
the per-request `timeout` that #2010 added after the guide was written.

## Changes

- The `Request` field table lists `timeout`, and the guide says to raise
`RequestTimeoutError` when it elapses, so every adapter reports a
timeout the same way.
- The guide says what to do with credential headers on redirects,
pointing at the `keeps_credentials` and `CREDENTIAL_HEADERS` helpers the
built-in adapters use.
- The `requests` example passes the timeout through, translates
`requests.Timeout` into `RequestTimeoutError`, and does not follow
redirects.
- `supabase_utils.http.errors` and `supabase_utils.http.redirects`
appear in the module table.

## Verification

Ran the `requests` example, extracted from the README rather than
retyped, through `SyncHttpIO` against a local `http.server`: repeated
headers join to `a, b`, a 302 comes back unfollowed, and a slow endpoint
raises `RequestTimeoutError` with the `requests.Timeout` as its cause.

Linear: SDK-2702
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.

1 participant