Skip to content

Run DownloadURL conformance in Python, Ruby, and TypeScript#280

Merged
jeremy merged 6 commits intomainfrom
download-conformance
Apr 24, 2026
Merged

Run DownloadURL conformance in Python, Ruby, and TypeScript#280
jeremy merged 6 commits intomainfrom
download-conformance

Conversation

@jeremy
Copy link
Copy Markdown
Member

@jeremy jeremy commented Apr 23, 2026

Summary

  • Dispatch DownloadURL in the Python, Ruby, and TypeScript conformance runners; route the mock catch-all so the relative second hop matches.
  • Three of the five downloads.json cases now run live in those runners (302 → signed URL, direct 2xx body, no-Location protocol error).
  • Two retry cases stay skipped, with capability-based reasons reflecting each SDK's download path (Python get_no_retry, Ruby http.get_no_retry, TS raw fetch bypassing the retry middleware). Unskipping today would guarantee red.
  • Go runner is unchanged (still 5/5).

Notes

  • Stacked on Fix 401 on file downloads #278 (fix-uploads-download-auth). downloads.json and the previous "runner does not yet dispatch" skip stubs were introduced there. Base is set accordingly; once Fix 401 on file downloads #278 lands, this can rebase onto main automatically.
  • TypeScript body.cancel() deviation: fire-and-forget, not awaited. Awaiting MSW's mocked ReadableStream.cancel() hangs past vitest's 5s test timeout. Matches the TS SDK's own download tests at typescript/tests/download.test.ts. Comment in place at conformance/runner/typescript/runner.test.ts:223.
  • Retry parity in the three SDK download paths is out of scope here; when each SDK grows it, the corresponding two skips flip live in a follow-up.

Test plan

  • Go: cd conformance/runner/go && go run . — 66 pass / 0 fail / 0 skip (5 download cases live)
  • Python: cd conformance/runner/python && uv sync && uv run python runner.py — 63 pass / 0 fail / 3 skip (3 download live, 2 retry capability skip + 1 unrelated maxItems)
  • Ruby: cd conformance/runner/ruby && bundle install && ruby runner.rb — 58 pass / 0 fail / 8 skip (3 download live, 2 retry capability skip + 6 unrelated)
  • TypeScript: cd conformance/runner/typescript && npm ci && npm test — 62 pass / 0 fail / 4 skip (3 download live, 2 retry capability skip + 2 unrelated)
  • CI conformance job in .github/workflows/test.yml invokes all four runners green

Copilot AI review requested due to automatic review settings April 23, 2026 20:13
@github-actions github-actions Bot added the conformance Conformance test suite label Apr 23, 2026
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the conformance runners (Python, Ruby, TypeScript) to execute the DownloadURL operation live, aligning those runners with the Go runner’s existing coverage and ensuring the mock infrastructure can handle the redirect “second hop” behavior.

Changes:

  • Add DownloadURL dispatch to the TypeScript runner and wire it to the SDK’s downloadURL API.
  • Add DownloadURL dispatch to the Ruby and Python runners, passing through the raw path from each conformance test case.
  • Update runner skip lists/reasons so the non-retry downloads.json cases run live while the retry semantics remain capability-skipped.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
conformance/runner/typescript/runner.test.ts Dispatches DownloadURL and updates TypeScript skip reasons to only skip retry-specific cases.
conformance/runner/ruby/runner.rb Dispatches DownloadURL, threads path through the operation mapper, and adjusts mocking to accommodate redirect hop behavior.
conformance/runner/python/runner.py Dispatches DownloadURL, threads path through the operation mapper, and adjusts respx routing to accommodate redirect hop behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread conformance/runner/ruby/runner.rb
Comment thread conformance/runner/python/runner.py
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bbf4da994a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread conformance/runner/python/runner.py Outdated
Comment thread conformance/runner/ruby/runner.rb Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread conformance/runner/typescript/runner.test.ts
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="conformance/runner/python/runner.py">

<violation number="1" location="conformance/runner/python/runner.py:194">
P2: The DownloadURL mock is pinned to `https://3.basecampapi.com`, which breaks matching for DownloadURL tests that use `configOverrides.baseUrl`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread conformance/runner/python/runner.py Outdated
@jeremy jeremy requested a review from Copilot April 23, 2026 20:52
@github-actions github-actions Bot added the enhancement New feature or request label Apr 23, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3ddb5f7541

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread conformance/runner/python/runner.py
Comment thread conformance/runner/ruby/runner.rb
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Base automatically changed from fix-uploads-download-auth to main April 23, 2026 22:53
@jeremy jeremy force-pushed the download-conformance branch from 580ce47 to 3c3603a Compare April 23, 2026 22:55
@jeremy jeremy requested a review from Copilot April 23, 2026 22:55
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread conformance/runner/typescript/runner.test.ts Outdated
Comment thread conformance/runner/ruby/runner.rb
Comment thread conformance/runner/python/runner.py
@jeremy jeremy requested a review from Copilot April 23, 2026 23:07
@jeremy jeremy added this to the v0.8.0 milestone Apr 23, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

jeremy added 6 commits April 23, 2026 17:02
Wire DownloadURL dispatch into the three non-Go runners and route the
mock catch-all so the relative second hop matches. Three of the five
downloads.json cases now run live (302 to signed URL, direct 2xx body,
no-Location protocol error). Two retry cases stay skipped, but with
capability-based reasons: each SDK's download path (Python's
get_no_retry, Ruby's http.get_no_retry, TS's raw fetch bypassing the
retry middleware) doesn't yet implement 5xx / Retry-After retry, so
unskipping would guarantee red.

Go runner is unchanged.
Tighten Python and Ruby DownloadURL mock routes from "any URL on this
method" to "any URL on https://3.basecampapi.com". The catch-all has to
remain path-flexible because hop 2 lands on a relative Location resolved
against the rewritten first-hop URL, but it doesn't have to be host-flexible.
A misroute to a different origin now fails instead of silently consuming a
queued response.
Address review feedback on the catch-all routing and the TS dispatcher:

- Python and Ruby DownloadURL routes now derive their host from the
  active test client's base URL (configOverrides.baseUrl when set, else
  the default https://3.basecampapi.com). A future DownloadURL case with
  configOverrides would otherwise route through a different origin and
  the mock would silently not match.

- TypeScript DownloadURL dispatch now throws if tc.path is empty rather
  than silently concatenating "undefined" into the synthetic URL. The
  TestCase interface marks path as optional, so the type system doesn't
  catch this.
The base branch added a headerAbsent assertion type with an optional
index field (0-based; negative counts from end), so the happy-path
DownloadURL case can now assert Authorization is present on the auth'd
hop and absent on the unauthenticated signed-URL hop. Mirror the Go
runner: thread index through headerPresent/headerInjected (default 0
preserves prior behavior) and add headerAbsent in Python, Ruby, and
TypeScript.
The DownloadURL mock route is origin-wide so hop 2's relative-resolved
URL is served, but a regression that misroutes hop 1 to a different
path on the same origin would otherwise pass silently — downloads.json
doesn't have a requestPath assertion.

Add a runner-level invariant in Python, Ruby, and TypeScript: for the
DownloadURL operation, the first captured request's path must equal
tc.path. Path correctness on hop 1 is implicit to the operation, so it
belongs in the runner rather than the shared spec.
- Python and Ruby DownloadURL dispatch now raises if path is empty,
  matching the TypeScript runner. An empty path would silently produce
  the bare host URL "https://storage.3.basecamp.com" and fail later in
  a less obvious way.
- TypeScript: explicitly void result.body.cancel() and attach a no-op
  .catch() to suppress any unhandled-promise-rejection from the
  discarded Promise. Fire-and-forget semantics are unchanged.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jeremy jeremy merged commit 9bf63cf into main Apr 24, 2026
48 checks passed
@jeremy jeremy deleted the download-conformance branch April 24, 2026 00:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conformance Conformance test suite enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants