Unit test NoAccessConfigRepository
epic-no-access-screen-foundation-task-004 — Write unit tests for NoAccessConfigRepository covering: successful remote config fetch, cache hit preventing second network call, cache expiry triggering re-fetch, and fallback to local constants on network failure. Use mocked Supabase client.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 2 - 518 tasks
Can start after Tier 1 completes
Implementation Notes
Inject the Supabase client (or a thin `NoAccessConfigDataSource` abstraction) through the constructor so tests can substitute a mock without touching global state. Model the cache as a private field holding a nullable `(NoAccessConfig, DateTime)` tuple; the TTL check is a simple `DateTime.now().isAfter(cachedAt.add(ttl))`. For the expiry test, either expose a `@visibleForTesting` clock parameter or use a `FakeClock` approach. The fallback constants should live in a separate `no_access_config_defaults.dart` file so they are easily importable by tests without pulling in the full Supabase dependency.
Avoid using `setUp`/`tearDown` for mock state if it obscures which test is asserting which behaviour—prefer self-contained `group` blocks.
Testing Requirements
Unit tests only (no widget or integration tests in this task). Use `flutter_test` with `mocktail` (preferred for null-safety ergonomics) or `mockito` with code generation. Cover four distinct branches: happy path fetch, cache hit, cache miss after expiry, and network error fallback. Assert both return values and mock interaction counts (e.g., `verify(() => mockClient.from('no_access_config')).called(1)`).
Aim for ≥90% line coverage on the repository class.
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.