high priority medium complexity testing pending testing specialist Tier 5

Acceptance Criteria

Unit tests cover all UserRole enum values and their JSON serialization round-trips (fromJson/toJson)
Unit tests verify RoleRepository returns cached data on second call without hitting SupabaseRoleProvider
Unit tests verify RoleRepository calls SupabaseRoleProvider exactly once per unique userId before cache is populated
Unit tests verify RoleRepository.clearCache() causes the next fetch to call SupabaseRoleProvider again
Unit tests cover SupabaseRoleProvider error paths: network error, RPC not found, empty result set, malformed JSON response
Integration tests run against a local Supabase instance (docker-compose or supabase CLI)
Integration test: user A cannot read roles belonging to user B via get_my_roles RPC (RLS isolation verified)
Integration test: coordinator role assignment returns correct orgId and chapterId scope
Integration test: user with no roles receives an empty list, not an error
Overall branch coverage on RoleRepository and SupabaseRoleProvider is 80% or above as reported by flutter test --coverage
All tests pass in CI without requiring manual Supabase credentials

Technical Requirements

frameworks
Flutter
flutter_test
Riverpod
apis
Supabase RPC get_my_roles
Supabase Auth
data models
assignment
performance requirements
Unit test suite completes in under 10 seconds
Integration tests complete in under 60 seconds against local Supabase
security requirements
Integration tests must verify RLS isolation — a test user must not be able to retrieve another user's role assignments
Test credentials must be sourced from environment variables, never hardcoded in test files

Execution Context

Execution Tier
Tier 5

Tier 5 - 253 tasks

Can start after Tier 4 completes

Implementation Notes

Structure test files to mirror source: `test/data/role/role_repository_test.dart`, `test/data/role/supabase_role_provider_test.dart`, `test/data/role/role_domain_model_test.dart`, `integration_test/role_rls_test.dart`. Use a shared `test/helpers/supabase_test_client.dart` helper that reads SUPABASE_URL and SUPABASE_ANON_KEY from environment for integration tests — do not duplicate this setup per test file. For RLS tests, create two test users via Supabase Admin API in setUpAll and assign roles only to user A. Assert user B's RPC call returns empty.

Mock the auth state stream in unit tests using a StreamController to test cache invalidation without a live Supabase connection. Document the local Supabase setup steps in a README comment at the top of the integration test file.

Testing Requirements

Unit tests (flutter_test): use mockito or mocktail to mock SupabaseRoleProvider. Test cache hit/miss logic with call count assertions. Test all enum serialization values. Test error propagation (SupabaseRoleProvider throws → RoleRepository surfaces typed exception).

Integration tests: use supabase CLI local dev stack. Seed test users with known role assignments in a beforeAll fixture. Run get_my_roles as user A and assert user B's roles are absent. Test the coordinator, peerMentor, orgAdmin, and globalAdmin role types.

Use tearDown to clean test data. Coverage: run `flutter test --coverage` and validate with lcov. Target: 80% branch coverage minimum on lib/data/role/ directory.

Component
Role Repository
data medium
Epic Risks (2)
medium impact medium prob technical

The get_my_roles RPC call adds a network round-trip immediately after login, potentially increasing the time before the home screen renders. If Supabase RPC is slow or the roles table lacks proper indexing, users with multiple org affiliations could experience noticeable delays.

Mitigation & Contingency

Mitigation: Index user_roles on user_id and org_unit_id. Use JWT claim extraction as the primary fast path; fall back to the RPC only when claims are absent or stale. Set a 3-second timeout with a fallback to cached roles.

Contingency: If RPC latency exceeds acceptable thresholds in production, pre-fetch and embed roles into the session JWT at login time via a Supabase Auth hook, eliminating the post-login RPC entirely.

high impact medium prob integration

Users who belong to multiple organizations (e.g., a coordinator in one NHF chapter who is also a peer mentor in another) may have conflicting role assignments. The repository layer must correctly scope roles to the active organization context set during the organization selection step, or it could return roles from the wrong org.

Mitigation & Contingency

Mitigation: Always filter role queries by the active org_unit_id stored in the tenant session. Write integration tests that simulate multi-org users and verify only the correct org's roles are returned.

Contingency: If org-scoping logic is found to be incorrect during QA, add an explicit org_unit_id parameter to get_my_roles RPC and require the client to always pass the active org context, making the scoping explicit rather than inferred.