Widget tests for NotificationListItem and EmptyState
epic-in-app-notification-centre-foundation-task-012 — Write widget tests for NotificationListItem and NotificationEmptyState using flutter_test and WidgetTester. For NotificationListItem: verify correct icon and color per notification type, unread indicator visibility, relative timestamp rendering, onTap callback fires, swipe-to-dismiss triggers onDismiss, and semantics labels are present and correct. For NotificationEmptyState: verify headline and sub-message render, CTA button appears only when filter is active, and empty-state semantics are announced correctly.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Wrap each test's `pumpWidget` call in a `MaterialApp` with a test `Localizations` delegate to prevent localization lookup failures. For the swipe-to-dismiss test, ensure the `Dismissible` key is deterministic (based on notification ID) so `find.byType(Dismissible)` resolves unambiguously. For color assertions on icons, use `tester.widget
For the Semantics tests, enable semantics in the test using `tester.ensureSemantics()` before pumping and dispose it afterward.
Testing Requirements
Widget tests using flutter_test and WidgetTester. Place in `test/features/notifications/widgets/`. Create two test files: `notification_list_item_test.dart` and `notification_empty_state_test.dart`. Use `tester.pumpWidget(MaterialApp(home: Scaffold(body: widgetUnderTest)))` as the pump wrapper.
For icon/color tests, use `find.byIcon(...)` and `find.byWidgetPredicate(...)` to locate and inspect widgets. For swipe-to-dismiss, use `tester.drag(find.byType(Dismissible), const Offset(-500, 0))` followed by `pumpAndSettle()`. For semantics, use `tester.getSemantics(find.byType(...))` and assert on label and hint values. No golden files — behavioral and semantic assertions only.
Supabase Realtime channels on mobile networks can drop silently. If reconnection logic is flawed, users miss notifications without knowing it, undermining the audit-trail guarantee.
Mitigation & Contingency
Mitigation: Implement exponential-backoff reconnection with a maximum of 5 retries; expose a channel-status stream to the BLoC so it can trigger a full-fetch fallback when the channel reconnects after a gap.
Contingency: If Realtime reliability proves insufficient in production, fall back to polling the repository every 60 seconds as a background supplement to the Realtime channel.
Coordinator and org-admin RLS expansions require joining user_roles and org_memberships tables. An incorrect policy could expose notifications to wrong users or block legitimate access entirely.
Mitigation & Contingency
Mitigation: Write dedicated RLS integration tests for each role (peer mentor, coordinator, org admin) using separate Supabase test projects. Review policies with the security checklist before merging.
Contingency: If an RLS defect is discovered post-deployment, disable the expanded-scope policy and revert to user-scoped-only access while a corrected migration is prepared and tested.
JSONB payload structure may vary across notification types created by different Edge Functions (reminder, expiry, scenario, pause). Missing or renamed fields will cause runtime parse failures.
Mitigation & Contingency
Mitigation: Define a canonical NotificationPayload union type in a shared schema document. Each Edge Function must validate its payload against this schema before inserting. Add fallback parsing with default values in the domain model.
Contingency: Wrap all payload parsing in try/catch and log malformed payloads to a monitoring channel; render a generic notification item rather than crashing when the payload cannot be parsed.