high priority low complexity testing pending testing specialist Tier 8

Acceptance Criteria

Integration test file `no_access_e2e_test.dart` exists under `integration_test/`
Test authenticates as a seeded global admin account in the test Supabase project
After login, navigating programmatically to `/home` results in the app displaying the No-Access screen (not the home screen)
Attempting to deep-link to any peer-mentor route (e.g., `/contacts`, `/work`) also lands on `/no-access`
The logout button on the No-Access screen, when tapped, navigates the user to the auth/login flow
No peer-mentor data (contacts list, activities) is rendered at any point during the blocked session
Test completes successfully against the test Supabase environment with the seeded global admin credentials stored in CI environment variables
Test is runnable via `flutter test integration_test/no_access_e2e_test.dart`

Technical Requirements

frameworks
Flutter
flutter_test
integration_test package
go_router
apis
Supabase Auth API (test environment)
Supabase remote config (test environment)
data models
UserRole
AccessDenialState
performance requirements
Integration test completes within 60 seconds including Supabase auth round-trip
security requirements
Test Supabase credentials stored as CI environment variables — never hardcoded
Seeded global admin account must exist only in the test project, not in production
Test verifies that peer-mentor data endpoints return no data for the blocked role (not just that the UI is hidden)
ui components
NoAccessScreen
LogoutButton

Execution Context

Execution Tier
Tier 8

Tier 8 - 48 tasks

Can start after Tier 7 completes

Implementation Notes

The integration test environment requires a dedicated Supabase test project with a seeded `global_admin` role account. Add a `README` note in the `integration_test/` folder documenting the required environment variables (`TEST_SUPABASE_URL`, `TEST_SUPABASE_ANON_KEY`, `TEST_GLOBAL_ADMIN_EMAIL`, `TEST_GLOBAL_ADMIN_PASSWORD`). Use `setUpAll` to sign in once and `tearDownAll` to sign out, reducing auth round-trips. To verify that no peer-mentor data is accessible, check that Supabase RLS policies block the global admin role at the database level — this is more reliable than UI-only assertions.

Consider tagging this test with `@Tags(['integration'])` so it can be excluded from fast unit test runs in CI.

Testing Requirements

Integration test using Flutter's `integration_test` package and `flutter_test`. Use `WidgetTester.pumpAndSettle()` after navigation actions to allow GoRouter redirects to resolve. Authenticate via Supabase test credentials injected from environment variables (use `String.fromEnvironment` or a `test_config.dart` file gitignored from the repo). After login, use `tester.tap` on navigation triggers or programmatic `context.go('/home')` calls.

Assert screen identity by finding unique widget keys or text strings on the No-Access screen. The logout flow assertion should verify the auth screen is presented after tapping logout.

Component
No-Access Route Guard
service low
Epic Risks (2)
high impact medium prob technical

If the GoRouter redirect callback evaluates the no-access route itself as a blocked destination, it will trigger an infinite redirect loop, crashing the navigator.

Mitigation & Contingency

Mitigation: Add an explicit guard condition in the redirect callback: return null (no redirect) when the current location is already the no-access route or the logout route. Write a dedicated unit test covering this exact scenario.

Contingency: If the redirect loop is detected in production, deploy a hotfix that adds the null-return guard; the feature can be toggled off via the existing feature-flag infrastructure while the fix is prepared.

medium impact low prob integration

The access-denial-service may read role state before authentication completes (e.g. during app resume), causing a temporary false-positive block that redirects valid peer-mentor users to the no-access screen.

Mitigation & Contingency

Mitigation: Subscribe to the role-state-manager's loading/ready lifecycle and only evaluate role-based access once the RBAC state is confirmed as loaded. Return a 'pending' state that causes the guard to defer rather than redirect.

Contingency: Add a retry mechanism: if a user lands on the no-access screen but their role subsequently resolves as non-blocked, automatically navigate them to the role-based home screen.