Skip to content

test(example): claim fragment and form_post conformance on linux/windows - #447

Open
ahmednfwela wants to merge 3 commits into
mainfrom
feat/desktop-fragment-formpost-conformance
Open

test(example): claim fragment and form_post conformance on linux/windows#447
ahmednfwela wants to merge 3 commits into
mainfrom
feat/desktop-fragment-formpost-conformance

Conversation

@ahmednfwela

@ahmednfwela ahmednfwela commented Aug 1, 2026

Copy link
Copy Markdown
Member

What

Flips the last two desktop conformance gates, putting Hybrid RP, Implicit RP, and the three Form Post plans in front of the live suite on linux and windows for the first time. Five profiles that were scored "cannot be delivered on this platform" become claimable, because the claim stopped being true when oidc_loopback_listener 1.1.0 and oidc_desktop 1.1.0 shipped (#445):

  • the listener now reads an application/x-www-form-urlencoded POST body and folds it into the returned Uri — OAuth 2.0 Form Post Response Mode is deliverable to a loopback redirect
  • the listener's relay page recovers a URL-fragment response (location.hash promoted to the query string), and oidc_desktop enables it exactly when the flow's response mode needs it

The two gates went different ways

canReceiveFragmentResponse is deleted, not flipped. Every platform can receive a fragment now, and a universally-true gate is dead code. isFragmentResponsePlan goes with it — the skip block was its only production caller, and the formpost-overrides-fragment classification it encoded lives on, tested, in oidc_desktop.responseArrivesInFragment.

canReceiveFormPost stays, and gains a platform parameter. The web page and the desktop listener are both http(s), so the URI alone cannot tell "a listener that reads POST bodies" from "a static page whose script cannot see the request body that delivered it". The old single-argument signature was only answerable because the answer used to be false everywhere. Custom schemes and web remain excluded, and the skip message now states the real reason per case instead of citing the redirect scheme.

What CI on this branch is for

Local tests prove the predicates; they cannot prove the live half — a real browser executing the relay page against certification.openid.net, and the suite's form POST landing in the listener. The linux and windows jobs here are that proof. A red on them is a finding about the relay or the listener, not a reason to re-gate: the gates were removed because the capability claim is released library behaviour, and if the live run contradicts it, the library (not the harness) is what needs fixing.

Expected cost: hybrid adds 48 modules and implicit 27 per desktop job, plus the three form-post plans. The flow-timeout budget test still holds locally; if a desktop job hits its wall-clock limit, that is a legible red with an obvious remedy.

Verification

flutter analyze lib test integration_test  →  No issues found!
flutter test                               →  74 passed (was 77: 4 gate tests
                                              deleted, 1 capability test added)

🤖 Generated with Claude Code

https://claude.ai/code/session_01M6bj7Qhk5FXAkvy4HJbCER

Summary by CodeRabbit

  • New Features

    • Added platform-aware conformance requests for web and native applications.
    • Added support for form-post redirects over HTTP(S) loopback transports on Linux and Windows.
  • Bug Fixes

    • Improved handling of form-post responses by preserving submitted parameters and avoiding unnecessary fragment processing.
    • Updated conformance checks with clearer platform-specific results for unsupported web and custom-scheme redirects.
  • Tests

    • Expanded coverage for platform selection, redirect support, and form-post response handling.

oidc_loopback_listener 1.1.0 and oidc_desktop 1.1.0 are released, so the two
capability gates that scored five profiles as "cannot be delivered on this
platform" are now stale. This flips them, which puts Hybrid, Implicit, and the
three Form Post plans in front of the live suite on linux and windows for the
first time.

canReceiveFragmentResponse is deleted, not flipped: the listener's relay page
recovers a fragment on every platform now, and a universally-true gate is dead
code. isFragmentResponsePlan goes with it -- the skip block was its only
production caller, and the classification it encoded (formpost overrides the
hybrid/implicit fragment default) lives on, tested, in oidc_desktop's
responseArrivesInFragment.

canReceiveFormPost stays, with a platform parameter it previously lacked. The
web page and the desktop loopback listener are both http(s), so the URI alone
cannot tell "a listener that reads POST bodies" from "a static page whose
script cannot see the request body". The old single-argument form was only
answerable because the answer was false everywhere.

The skip message for the remaining form_post exclusions now states the actual
reason per case (custom scheme: not an HTTP endpoint; web: a page script
cannot read a POST body) instead of citing the redirect scheme, which stopped
being an explanation the moment an https page became one of the excluded
transports.

Example suite 77 -> 74 (four gate tests deleted, one capability test added),
analyzer clean, and the flow-timeout budget test still holds. What no local
test can prove is the live half: the browser executing the relay page against
certification.openid.net, and the suite's form POST landing in the listener.
That is exactly what the linux and windows CI jobs on this branch exist to
show, and a red there is a finding, not a rollback trigger.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M6bj7Qhk5FXAkvy4HJbCER
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The conformance runner now maps platforms to OIDC application types and evaluates form-post support by platform and redirect transport. Fragment responses are no longer gated. The loopback listener processes POST responses without fragment relay handling.

Changes

Conformance transport handling

Layer / File(s) Summary
Platform-specific conformance requests
packages/oidc/example/integration_test/conformance/api.dart, packages/oidc/example/integration_test/shared_e2e.dart
Conformance requests can include application_type. Platforms map to web or native.
Transport capability and skip handling
packages/oidc/example/integration_test/shared_e2e.dart
Fragment responses are no longer gated. Form-post checks accept HTTP(S) redirects for native platforms and report platform-specific skip reasons.
Conformance transport tests
packages/oidc/example/test/conformance_plan_variant_test.dart
Tests cover application type mapping, web and custom-scheme rejection, Linux and Windows loopback support, and removal of fragment gate assertions.

Loopback POST handling

Layer / File(s) Summary
POST response and fragment handling
packages/oidc_loopback_listener/lib/src/oidc_loopback_listener.dart, packages/oidc_loopback_listener/test/oidc_loopback_listener_test.dart
Fragment recovery runs only for GET requests. POST tests verify direct completion and preservation of body-derived parameters.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the example conformance test changes for fragment and form_post support on Linux and Windows.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/desktop-fragment-formpost-conformance

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

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🔥 Firebase Hosting previews

Target Preview
Example https://oidc-flutter-example--pr-447-example-mjdmt67g.web.app

Channels expire 7 days after their last deploy.

ahmednfwela and others added 2 commits August 1, 2026 21:14
The first live run of the flipped gates produced 36 suite-side rejections on
linux, one per fragment-mode module, before any browser was involved:

  [FAILURE] redirect_uri is one of the registered uris but uses http scheme
  which is not allowed when application_type is web and response type is not
  code

The harness registered no application_type at all, and OIDC Registration 1.0
section 2 defaults an omitted value to `web` -- so the suite judged a desktop
RP with a loopback redirect by web-client rules, whose implicit-grant clause
this exact shape violates. The same section sanctions it verbatim for native
clients: "Native Clients MUST only register redirect_uris using custom URI
schemes or loopback URLs using the http scheme; loopback URLs use localhost or
the IP loopback literals".

Every non-web platform in this harness is a native client, so the fix is
sending the metadata that was always true and simply never sent:
applicationTypeForPlatform maps web -> web and everything else -> native, and
prepareTestPlanRequest forwards it. Omitted still means absent -- the suite
owns the default, and the harness does not invent one silently.

This is the same defect the web job had, one layer over: web violated the
web-client rules it was correctly subject to, and desktop was subjected to
web-client rules it was never under. Both ends of the section 2 sentence have
now been hit from both sides.

macos/ios/android previously passed while implicitly defaulted to web only
because the https check ignores non-http schemes; they now declare native, and
their redirect shape is the one the native clause names. Their jobs on this PR
double as the regression check for that.

Example suite 74 -> 77.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M6bj7Qhk5FXAkvy4HJbCER
…onse

Round 2 of the desktop conformance run answered one question and asked this
one: the fragment relay works (Hybrid and Implicit pass via the relay on
windows), Form Post Basic passes (POST capture works) -- but every form_post
hybrid/implicit module died with "Couldn't resolve the response mode, make
sure the key (state) exists in the Uri".

The client had not explicitly requested response_mode=form_post, so
oidc_desktop's responseArrivesInFragment saw `code id_token` and armed the
relay. The listener then folded the POST body into the Uri correctly -- and
the relay branch discarded it and served the relay page. The page's
re-request carries location.search and location.hash; a request BODY has no
representation there, so code, id_token and state all vanished, and response
mode resolution failed on the missing state.

A fragment can only ride a GET navigation. A form POST's response is in its
body, already captured by the time the relay decision is made, so relaying a
POST destroys the very response the relay exists to recover. The relay now
fires for GET only; everything else completes immediately.

Test written first and red: captureFragment on + a form POST must complete on
the first request with the body's parameters intact. 19 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M6bj7Qhk5FXAkvy4HJbCER

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/oidc/example/test/conformance_plan_variant_test.dart (1)

186-227: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Cover the native HTTPS branch.

canReceiveFormPost now accepts HTTP(S) redirects for non-web platforms. The tests cover only http://localhost for Linux and Windows. Add a native HTTPS assertion, or narrow the contract to HTTP loopback if HTTPS is not supported.

Suggested regression assertion
       expect(
         canReceiveFormPost(Uri.parse('http://localhost:22434'), 'windows'),
         isTrue,
       );
+      expect(
+        canReceiveFormPost(Uri.parse('https://localhost:22434'), 'windows'),
+        isTrue,
+      );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/oidc/example/test/conformance_plan_variant_test.dart` around lines
186 - 227, Extend the native-platform coverage in the form_post tests around
canReceiveFormPost to assert the intended behavior for an HTTPS redirect, using
a non-web platform such as Linux or Windows. If HTTPS is not supported, instead
update canReceiveFormPost to restrict acceptance to HTTP loopback redirects and
keep the tests aligned with that contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/oidc/example/test/conformance_plan_variant_test.dart`:
- Around line 186-227: Extend the native-platform coverage in the form_post
tests around canReceiveFormPost to assert the intended behavior for an HTTPS
redirect, using a non-web platform such as Linux or Windows. If HTTPS is not
supported, instead update canReceiveFormPost to restrict acceptance to HTTP
loopback redirects and keep the tests aligned with that contract.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b2446d10-fbcf-4c29-9c77-35c472edfcaf

📥 Commits

Reviewing files that changed from the base of the PR and between 0a19c64 and db4381a.

📒 Files selected for processing (5)
  • packages/oidc/example/integration_test/conformance/api.dart
  • packages/oidc/example/integration_test/shared_e2e.dart
  • packages/oidc/example/test/conformance_plan_variant_test.dart
  • packages/oidc_loopback_listener/lib/src/oidc_loopback_listener.dart
  • packages/oidc_loopback_listener/test/oidc_loopback_listener_test.dart

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