Unit test pause status record repository
epic-pause-status-notifications-foundation-task-004 — Write unit tests for the pause status record repository covering: successful record fetch, coordinator resolution with single and multiple chapters, missing record handling, and RLS boundary conditions using mocked Supabase client responses.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Check whether the project already uses mockito or mocktail and use the same library — do not introduce a second mocking library. Create a MockSupabaseClient and stub the specific query chains used by the repository (e.g., `.from().select().eq().maybeSingle()`). Since Supabase Flutter SDK uses method chaining that can be difficult to mock, consider whether the repository already uses a thin wrapper/abstraction around the SDK — if so, mock the wrapper instead of the SDK directly. For stream tests, use a StreamController in the test to simulate Realtime pushes.
Fixtures for test JSON payloads should be stored in test/fixtures/pause_status/ as .json files and loaded via File.readAsStringSync to keep test data maintainable.
Testing Requirements
Pure unit tests using flutter_test and mocktail (or mockito, matching the project convention). Each test follows the Arrange-Act-Assert pattern with a single assertion per test where possible. Group tests by method using `group()` blocks. Use `setUp()` to initialize the mocked SupabaseClient and repository instance.
For stream tests, use `expectLater` with `emitsInOrder`. Ensure no test depends on execution order of other tests — each test must be fully independent. Run `flutter test --coverage` and verify the repository file reaches ≥90% line coverage.
The org membership table structure used to resolve coordinator relationships may differ from what the repository assumes, causing incorrect coordinator lookup or missing rows for mentors in multi-chapter scenarios.
Mitigation & Contingency
Mitigation: Review the existing org membership table schema and RLS policies before writing repository queries. Align query logic with the patterns already used by peer-mentor-status-repository and multi-chapter-membership-service.
Contingency: If schema differs, add an adapter layer in the repository that normalises the membership resolution and document the discrepancy for the data team. Fall back to coordinator lookup via the feature's own stored coordinator_id field if org membership join fails.
Device tokens stored in the database may be stale or unregistered, causing FCM dispatch failures that silently drop coordinator notifications — the primary coordination safeguard of this feature.
Mitigation & Contingency
Mitigation: Implement token validation on every dispatch call and handle FCM's NOT_REGISTERED error by flagging the token as invalid in the database. Reuse the token refresh pattern already established by fcm-token-manager.
Contingency: If push delivery fails after retry, ensure the in-app notification record is always written regardless of push outcome so coordinators can still see the event in the notification centre.
The optional reason field may contain special characters, emoji, or non-Latin scripts that exceed the 200-character byte limit when FCM encodes the payload, causing delivery failures.
Mitigation & Contingency
Mitigation: Enforce the 200-character limit on Unicode code point count, not byte count, in the payload builder. Add a unit test with multi-byte input strings.
Contingency: If an oversized payload is detected at dispatch time, strip the reason field from the push notification body and note 'See in-app notification for full reason' to preserve delivery.