Integration smoke test: config + URL launch pipeline
epic-no-access-screen-foundation-task-008 — Write an integration test that wires NoAccessConfigRepository and UrlLauncherUtil together: fetch the admin portal URL from the repository (using a test Supabase environment or seeded local constant) and pass it to UrlLauncherUtil, asserting the correct result type is returned. Validates the contract between the two foundational components before higher-tier components depend on them.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
The primary value of this test is verifying the data contract between the two components—specifically that the URL string format returned by the repository is compatible with what `UrlLauncherUtil` expects (valid URI, correct scheme). Use the local-constant fallback path of `NoAccessConfigRepository` to avoid Supabase dependency in CI: construct the repository with a flag or subclass that always returns the seeded constant. This makes the test deterministic and fast. Document in a comment why the Supabase real-fetch path is skipped in CI and how a developer can opt in locally by setting an environment variable.
Keep the test narrow—it should not test UI rendering (that belongs to widget tests in the UI epic). If a `testWidgets` wrapper is needed for `BuildContext`, use a minimal `MaterialApp` pump.
Testing Requirements
Integration test using the `integration_test` Flutter package (not `flutter_test` alone). Wire the real `NoAccessConfigRepository` with either a local constant seed (preferred for CI reliability) or a dedicated Supabase test table seeded before the test run. Wire the real `UrlLauncherUtil` with a mock platform interface to avoid actual browser opening. Assert the end-to-end data flow: repository returns a config, the URL field is non-empty, and passing it to the util returns a well-typed result.
Add a `group('smoke: no-access foundation pipeline')` wrapper for clear test output identification.
Supabase remote config may be unavailable at app startup (network error, cold start), causing the repository to return no blocked-role list. If the fallback is empty, blocked users could access the app.
Mitigation & Contingency
Mitigation: Define a local constants fallback list of blocked roles compiled into the app binary. Remote config enriches or overrides this list when available.
Contingency: If remote config repeatedly fails in production, pin the blocked-role list to local constants only and disable remote override until the Supabase config endpoint is stabilised.
url_launcher package behaviour differs between iOS and Android (e.g. canLaunchUrl returning false on some Android configurations), leading to silent failures when the admin portal link is tapped.
Mitigation & Contingency
Mitigation: Run canLaunchUrl check before every launch attempt and surface a descriptive inline error message (e.g. 'Could not open link — visit admin.example.org manually') when the check fails.
Contingency: If canLaunchUrl is consistently unreliable on a target platform, replace the tap-to-open pattern with a copyable text field showing the URL as a fallback.