high priority medium complexity testing pending testing specialist Tier 5

Acceptance Criteria

Integration test covers the full happy path: proxy mode selection → mentor selection → all wizard steps → submission; test passes in CI without manual intervention
Test verifies that recorded_by_user_id matches the authenticated coordinator's user ID and peer_mentor_id matches the selected mentor's ID in the submitted payload
Widget tests confirm the attribution banner ('Registering on behalf of [mentor name]') is present and unchanged on every wizard step (contact, date, time, duration, summary)
BLoC unit tests verify ProxyActivityCubit correctly assembles the payload with both IDs from state without mutation or loss across step transitions
Test covers the error path: if submission fails, wizard remains on the summary step with an inline error message
Test verifies that selecting a different proxy mentor mid-wizard updates the attribution banner and the peer_mentor_id in the pending payload
All tests use mocked Supabase/service dependencies — no real network calls in test suite
Tests run via flutter test and complete within 60 seconds on standard CI hardware
Test file follows the project's existing test naming conventions and is located in the test/integration/ directory

Technical Requirements

frameworks
Flutter
flutter_test
BLoC/Cubit
mocktail
apis
ActivityService.submitProxyActivity(ProxyActivityPayload)
AuthService.currentUserId()
data models
ProxyActivityPayload (recorded_by_user_id, peer_mentor_id, activity fields)
ProxyActivityCubitState
performance requirements
Individual widget tests must complete within 5 seconds
Full integration test suite for this flow must complete within 60 seconds
security requirements
Test fixtures must use synthetic UUIDs — never real user IDs or production data
Mocked AuthService returns a fixed synthetic coordinator UUID to verify payload assembly

Execution Context

Execution Tier
Tier 5

Tier 5 - 253 tasks

Can start after Tier 4 completes

Implementation Notes

Structure tests in three files: proxy_activity_cubit_test.dart, proxy_activity_wizard_widget_test.dart, and proxy_wizard_flow_integration_test.dart. Use mocktail for service mocks; register fakes for complex types like ProxyActivityPayload to avoid registration errors. For the integration test, use a test-specific ProviderScope / BlocProvider override to inject mocked services into the widget tree — do not rely on global singletons. The attribution banner persistence test should use a PageController or equivalent to navigate between wizard pages and call pumpAndSettle() after each transition before asserting banner presence.

Capture the exact argument passed to ActivityService.submitProxyActivity using mocktail's verify(mockService.submitProxyActivity(captureAny())).captured pattern. Ensure tests clean up any StreamSubscriptions from cubits in tearDown to prevent test pollution.

Testing Requirements

Three test layers required: (1) BLoC unit tests — test ProxyActivityCubit.selectMentor(mentor), navigateToNextStep(), assemblePayload() produce correct ProxyActivityPayload with both IDs; test payload is immutable across multiple step navigations; test failure state on service rejection. (2) Widget tests — mount ProxyActivityWizard with mocked cubit; navigate through all steps using WidgetTester; assert attribution banner text on each step; assert banner text updates when selectMentor emits new state. (3) Integration test — use flutter_test integration test runner; stub ActivityService at the repository layer; drive full flow from proxy mode selection to submission; capture the payload passed to ActivityService.submitProxyActivity and assert field values.

Component
Proxy Activity Wizard
ui medium
Epic Risks (3)
medium impact medium prob scope

If the batch insert RPC returns a mix of successes and failures (e.g., 3 of 10 mentors fail due to constraint violations that slipped through application-level duplicate detection), the confirmation screen result state becomes ambiguous. A coordinator who sees '7 of 10 succeeded' may not know whether to manually register the 3 failures, retry, or escalate — leading to either duplicate registrations or silent underreporting.

Mitigation & Contingency

Mitigation: Design the Bulk Registration Service to return a strongly typed BulkRegistrationResult with per-mentor RegistrationOutcome (success | duplicate_detected | constraint_violation | permission_denied). Design the result screen to list each failed mentor with a specific, plain-language reason and a one-tap 'Retry for this mentor' action that pre-fills the activity wizard with the batch template for that individual.

Contingency: If per-mentor retry UI is too complex to deliver within the epic scope, fall back to displaying failed mentors with their error codes and instructing coordinators to use single-proxy mode for the failures. Document this as a known limitation in release notes and create a follow-up ticket for per-mentor retry in the next sprint.

medium impact medium prob dependency

The Proxy Activity Wizard must reuse the existing activity wizard step widgets (type, date, duration, notes) while injecting a proxy attribution banner and a different submission payload builder. If the existing wizard is not designed for composability, the proxy variant may require forking the widget tree, creating two maintenance-diverging codebases that will drift out of sync when the base wizard is updated (e.g., new activity types added, new mandatory fields).

Mitigation & Contingency

Mitigation: Before implementing the Proxy Activity Wizard, audit the existing activity wizard's architecture. If steps are already extracted as independent StatelessWidget/ConsumerWidget classes, compose them directly with a wrapping Column that injects the attribution banner. If they are tightly coupled inside a parent widget, refactor the existing wizard to accept a nullable ProxyContext parameter before starting the proxy variant — this refactor should be a prerequisite task in this epic.

Contingency: If refactoring the base wizard is blocked by unrelated in-flight work on that component, implement the proxy wizard as a full fork but create a shared StepWidgets library file that both the base wizard and proxy wizard import. Schedule a deduplication refactor as a tech-debt ticket in the next planning cycle.

medium impact medium prob technical

The bulk registration flow spans three sequential screens (multi-select → activity form → confirmation → result) with shared mutable state: the selected mentor list, the activity template, the per-mentor duplicate warnings, and the final submission result. Managing this state across screens without a well-designed Bloc risks state leaks, stale duplicate warning data after mentor removal, and confirmation screen inconsistencies if the user navigates back and changes the mentor selection.

Mitigation & Contingency

Mitigation: Define a single BulkRegistrationBloc (or Cubit) with explicit state transitions covering: MentorsSelected → ActivityTemplateCompleted → DuplicatesChecked → ConfirmationReady → Submitting → SubmissionResult. Each backward navigation event (e.g., 'Back' from confirmation to mentor selection) dispatches a ResetToMentorSelection event that clears downstream state. Unit test every state transition with edge cases including empty mentor list, all mentors having duplicates, and network failure during submission.

Contingency: If state management complexity causes persistent bugs in testing, simplify by passing state explicitly through Navigator arguments (immutable snapshots per screen) rather than a shared Bloc. This reduces flexibility but eliminates cross-screen state mutation bugs.