Unit test ContactRLSQueryBuilder filter construction
epic-contact-list-management-foundation-task-004 — Write unit tests for ContactRLSQueryBuilder covering: correct filter expression for each UserRole value, organization_id always present in output, ILIKE predicate escaping edge cases (special characters, empty string, whitespace-only), and combined role+org+search filter assembly. Use mock Supabase client to assert filter chain contents without hitting the database.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
The most important design decision for this test file is the mock Supabase query builder. Supabase's Dart client uses a chainable builder where each method returns the same object (or a new modified one). Create a simple stub class that implements the same interface (or enough of it to satisfy the type checker) and stores method calls in a List
Avoid using Mockito's generated mocks for fluent builders — hand-written stubs are more maintainable here. Place the stub in test/helpers/ so it can be reused by task-010's integration tests.
Testing Requirements
All tests use flutter_test (not integration_test). Create a MockSupabaseQueryBuilder stub that records each filter method call (eq, in_, ilike, or) in an ordered list. After calling build(), assert the recorded call list matches the expected sequence. Group tests using group() blocks: 'role filter mapping', 'organisation scoping', 'search predicate construction', 'combined filter assembly'.
Use setUp() to create a fresh mock before each test. Aim for 100% statement coverage of ContactRLSQueryBuilder. Run flutter analyze on the test file itself to ensure no linting issues.
Existing Supabase RLS policies for the contacts and peer_mentors tables may not align with the application-level UserRole model, causing ContactRLSQueryBuilder to construct filter expressions that are redundant, conflicting, or that allow over-fetching. In a multi-chapter context (NHF), this could expose contacts belonging to other chapters.
Mitigation & Contingency
Mitigation: Audit and document the existing RLS policies against the UserRole enum before writing a single line of query builder code. Write integration tests asserting cross-organization data isolation using separate test user tokens for each role.
Contingency: If RLS policies are misaligned at runtime, add an explicit application-level organization_id equality check in ContactRepository as a secondary guard while the database policies are corrected in a coordinated migration.
The Supabase schema for contacts and peer_mentors tables may differ from the expected typed models — missing columns, renamed fields, or type mismatches — causing deserialization failures that surface only at runtime during integration testing.
Mitigation & Contingency
Mitigation: Document expected schema fields upfront and validate against the live Supabase schema at sprint start. Use freezed and json_serializable for compile-time-safe deserialization with explicit required/optional field declarations.
Contingency: Introduce nullable fields with safe defaults for any schema mismatches discovered in testing; log deserialization errors to the monitoring service so schema drift is caught before production deployment.