Write Unit Tests for CertificationBLoC
epic-certification-management-automation-task-009 — Write comprehensive unit tests for CertificationBLoC covering all event-to-state transitions using the bloc_test package. Mock CertificationManagementService with Mockito. Test loading, success, error, and reload flows. Test that concurrent events are handled correctly and that state invalidation triggers a fresh load. Achieve minimum 80% branch coverage.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Use `mocktail` if the project already uses it (check pubspec.yaml); otherwise use Mockito with `@GenerateMocks([CertificationManagementService])` and run `flutter pub run build_runner build`. Prefer `mocktail` for zero-codegen ergonomics. `blocTest` signature reminder: `blocTest
Verify with `verify(() => mockService.getCertification(any())).called(1)`. Create a `certificationFixture({String? id, String status = 'active'})` factory method to keep test data DRY.
Testing Requirements
This task IS the testing requirement. All tests use flutter_test and bloc_test packages. Create a `CertificationFixtures` helper class in `test/fixtures/certification_fixtures.dart` that returns pre-built `Certification` objects for reuse across tests. Use `setUp` to initialise a fresh BLoC and mock before each test.
Use `tearDown` to call `bloc.close()`. Group tests by event type using `group()`. Run `flutter test --coverage` and verify lcov report shows ≥80% line coverage on `lib/features/certification/bloc/`. Include a brief comment above each test group explaining what scenario is covered.
Regression: after implementing all tests, run them against the unimplemented stub BLoC to confirm they all fail (red phase), then run against the real implementation to confirm they all pass (green phase).
Supabase Edge Functions can have cold-start latency that causes the nightly cron to time out when processing large cohorts of expiring certifications, resulting in partial reminder dispatches.
Mitigation & Contingency
Mitigation: Batch the cron processing in chunks of 50 mentors per iteration. Use pagination with a cursor to resume processing if the function is re-invoked. Keep total invocation time well under the Edge Function timeout limit.
Contingency: If timeouts occur in production, split the cron into two separate functions: one for reminders and one for auto-pauses, each with its own schedule offset to reduce peak load.
Certification BLoC covers three distinct workflows (view, renew, enrol) which may lead to an overly complex state machine that is hard to test and maintain, particularly when error states from multiple concurrent operations need to be differentiated in the UI.
Mitigation & Contingency
Mitigation: Use separate sealed state classes per workflow (CertificationViewState, RenewalState, EnrolmentState) composed into a single BLoC state wrapper. Follow the existing BLoC patterns established in the codebase for consistency.
Contingency: If the BLoC grows too complex, split into two BLoCs: CertificationBLoC (view/load) and CertificationActionBLoC (mutations), connected via a shared stream.