high priority high complexity testing pending testing specialist Tier 8

Acceptance Criteria

Widget test: DuplicateWarningBottomSheet renders correctly with duplicate activity data — title, dates, participants all displayed
Widget test: Tapping 'Proceed' calls the proceed callback, dismisses the sheet, and verifies no merge state is set
Widget test: Tapping 'Merge' calls the merge callback, dismisses the sheet, and verifies merged activity data is passed correctly
Widget test: Tapping 'Cancel' dismisses the sheet without triggering proceed or merge callbacks
Widget test: BLoC/Riverpod state is verified after each resolution path — correct state transitions emitted
Widget test: Accessibility — all interactive elements have semanticsLabel, focus order is correct, VoiceOver announces action results
Integration test: DeduplicationQueueScreen renders a paginated list of duplicate groups with correct item count
Integration test: Filter controls (by date range, organization, activity type) update the displayed list correctly
Integration test: Sort controls (by date, severity, organization) reorder the list correctly
Integration test: Tapping a duplicate group navigates to detail view with correct data pre-populated
Integration test: Coordinator resolves a duplicate via the detail view — queue list updates and removes resolved item
Integration test: Badge count on the navigation tab decrements correctly after each resolution
Integration test: Badge count remains accurate after navigating away and returning to the screen
All tests pass in CI with flutter_test runner — no flaky async assertions
Test coverage for DuplicateWarningBottomSheet widget: 100% of interactive paths covered
Test coverage for DeduplicationQueueScreen: all happy paths and key error states covered

Technical Requirements

frameworks
Flutter
flutter_test
BLoC
Riverpod
apis
Supabase realtime subscription (for badge count reactivity tests using mock)
data models
DuplicateActivityGroup
ActivityRecord
ResolutionAction
performance requirements
Widget tests must complete in under 2 seconds each
Integration tests must complete in under 30 seconds total
No real network calls — all Supabase interactions mocked
security requirements
No real personal data (names, activity details) in test fixtures — use anonymized mock data
Tests must not write to any real Supabase instance
ui components
DuplicateWarningBottomSheet
DeduplicationQueueScreen
DeduplicationQueueListItem
DuplicateDetailView
NavigationBadge

Execution Context

Execution Tier
Tier 8

Tier 8 - 48 tasks

Can start after Tier 7 completes

Implementation Notes

Structure tests in two files: `duplicate_warning_bottom_sheet_test.dart` (widget) and `deduplication_queue_screen_test.dart` (integration). Use a shared `test/fixtures/duplicate_activity_fixtures.dart` file for reusable mock data — this prevents drift between widget and integration tests. For BLoC state verification after bottom sheet actions, wrap the widget under test in a `BlocProvider` with a `MockBloc` and use `verify(() => mockBloc.add(ProceedResolutionEvent()))`. For badge count reactivity, simulate a Supabase realtime event by emitting a new state from the mock provider rather than connecting to a real stream.

Pay attention to async gaps when the bottom sheet dismisses — use `await tester.pumpAndSettle()` only after `Navigator.pop` completes. For the pagination integration test, inject a mock repository that returns two pages of data and assert the 'Load more' trigger fires at scroll bottom.

Testing Requirements

Use flutter_test for all widget tests with `testWidgets()`. Use `WidgetTester.pump()` and `pumpAndSettle()` appropriately — avoid over-relying on `pumpAndSettle` for BLoC streams; use `pump(Duration)` to advance specific timers. Mock the BLoC/Riverpod providers using `MockBloc` (bloc_test package) or `ProviderScope` overrides. For integration tests, use flutter_test integration_test package with a fake Supabase client.

Verify state transitions with `expect(bloc.state, isA())`. Test accessibility with `tester.getSemantics()` checks. Aim for zero test-order dependencies — each test must be independently runnable.

Component
Duplicate Resolution Handler
service medium
Epic Risks (3)
high impact medium prob technical

The merge resolution path requires identifying which fields from the draft differ from the existing record, applying those differences to the existing record, and cancelling the draft — all as an atomic operation. Partial failures (e.g., update succeeds but draft cancellation fails) could leave the system in an inconsistent state.

Mitigation & Contingency

Mitigation: Implement the merge path as a Supabase RPC transaction that updates the existing record and soft-deletes the draft in a single atomic call. The DuplicateResolutionHandler should never attempt field-level merge at the application layer.

Contingency: If the atomic RPC approach proves too complex for the initial release, simplify the merge path to: mark existing record as the canonical record and cancel the new submission without field merging, displaying a message to the user to manually verify the existing record's fields. Log a follow-up ticket for full field-merge in a later sprint.

medium impact medium prob integration

The DuplicateWarningBottomSheet must intercept the activity wizard's save action without disrupting the wizard's existing navigation stack. If the bottom sheet is implemented as a separate route rather than an overlay, back navigation could break the wizard's step state.

Mitigation & Contingency

Mitigation: Use a `showModalBottomSheet` overlay pattern so the bottom sheet sits above the wizard route without pushing a new route onto the Navigator stack. The wizard's CuBit/BLoC retains all draft state while the sheet is visible. Test this integration with the existing activity-registration-cubit before merging.

Contingency: If the overlay approach causes Z-order or focus issues with the wizard's keyboard-aware layout, route the duplicate check result back to the wizard as a state event (DuplicateDetected), and let the wizard render a local inline warning banner instead of a bottom sheet.

medium impact medium prob technical

The bottom sheet and comparison panel involve complex layouts with multiple interactive elements. Screen reader users (particularly relevant for Blindeforbundet) may struggle with the side-by-side comparison layout if semantics are not carefully ordered.

Mitigation & Contingency

Mitigation: Design the comparison panel with a single-column semantic order (read record A fully, then record B fully) regardless of visual layout. Use Flutter's `Semantics` widget with `sortKey` to enforce correct traversal order. Test with TalkBack and VoiceOver against the WCAG 2.2 AA reading order criteria.

Contingency: If side-by-side layout cannot achieve acceptable screen reader ordering, switch to a stacked tab layout (Tab A / Tab B) for the comparison panel that is semantically simple even if less visually immediate for sighted users.