Integration and regression testing for hierarchy services
epic-organizational-hierarchy-management-core-services-task-020 — Write Flutter integration tests and Dart unit tests covering the full hierarchy mutation flow: validator pre-check → HierarchyService write → RLS enforcement → cache invalidation → HierarchyTreeView reactive rebuild. Test cycle prevention, orphan rejection, depth-limit rejection, and RLS cross-tenant isolation in a single end-to-end harness.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 9 - 22 tasks
Can start after Tier 8 completes
Implementation Notes
Structure tests in layers: unit tests for validators (pure Dart, no Flutter context needed, fast), widget tests for HierarchyTreeView reactivity (ProviderScope with overrides, no real Supabase), and integration tests for the full flow (real Supabase test project). For the RLS integration tests, create two test users and two test organizations in the Supabase test project as part of the test setup script. Use the integration_test package (not just flutter_test) for tests that require a real app context and Supabase connection. Seed the Supabase test database with a known fixture hierarchy before each test and clean up after — use Supabase's REST API in setUp/tearDown.
For the reactive rebuild test, use a ProviderContainer with a listener to assert state changes rather than relying on flutter_test's pumpAndSettle — this is more reliable for async Riverpod streams. Document in the test file header which environment variables are required (e.g., SUPABASE_TEST_URL, SUPABASE_TEST_ANON_KEY, TEST_USER_A_JWT, TEST_USER_B_JWT).
Testing Requirements
Dart unit tests (flutter_test): HierarchyValidator cycle detection with a fixture graph; orphan detection with a missing parent ID; depth-limit check with a 6-level path. Use fake/stub implementations of the HierarchyRepository for validator unit tests only. Flutter integration tests (integration_test package): full flow test using a real Supabase test project with seeded data; assert each validation error type, each successful mutation, cache invalidation timing, and reactive UI rebuild. RLS test: authenticate as user A, attempt to read org B's nodes via HierarchyService, assert empty result or permission error — repeat in reverse.
Separate test file per concern: hierarchy_validator_test.dart, hierarchy_service_test.dart, hierarchy_tree_view_integration_test.dart, hierarchy_rls_test.dart.
Injecting all unit assignment IDs into JWT claims for users assigned to many units (up to 5 for NHF peer mentors, many more for national coordinators) may exceed JWT size limits, causing authentication failures.
Mitigation & Contingency
Mitigation: Store unit IDs in a Supabase session variable or a dedicated Postgres function rather than embedding them directly in the JWT payload. Use set_config('app.unit_ids', ...) within RLS helper functions querying the assignments table at policy evaluation time.
Contingency: Fall back to querying the unit_assignments table directly within RLS policies using the authenticated user ID, accepting a small per-query overhead in exchange for removing the JWT size constraint.
Rendering 1,400+ nodes in a recursive Flutter tree widget may cause jank or memory pressure on lower-end devices used by field peer mentors, degrading the admin experience.
Mitigation & Contingency
Mitigation: Implement lazy tree expansion — only the root level is rendered on initial load. Child nodes are rendered on demand when the parent is expanded. Use const constructors and ListView.builder for all node lists to minimize rebuild scope.
Contingency: Add a search/filter bar that scopes the visible tree to matching nodes, reducing the visible node count. Provide a 'flat list' fallback view for administrators who prefer searching over browsing the tree.
Requirements for what constitutes a valid hierarchy structure may expand during NHF sign-off (e.g., mandatory coordinator assignments per chapter, minimum member counts per region), requiring repeated validator redesign.
Mitigation & Contingency
Mitigation: Design the validator as a pluggable rule engine where each check is a discrete, independently testable function. New rules can be added without changing the core validation orchestration. Surface all rules in a configuration table per organization.
Contingency: Defer non-blocking validation rules to warning-level feedback rather than hard blocks, allowing structural changes to proceed while flagging potential issues for admin review.
Deploying RLS policy migrations to a shared Supabase project used by multiple organizations simultaneously could lock tables or interrupt active sessions, causing downtime during production migration.
Mitigation & Contingency
Mitigation: Write all RLS policies as CREATE POLICY IF NOT EXISTS statements. Schedule migrations during off-peak hours. Use Supabase's migration preview environment to validate policies against production data shapes before applying.
Contingency: Prepare rollback migration scripts for every RLS policy. If a migration causes issues, execute the rollback immediately and re-test the policy logic in staging before reattempting.