Unit test BufdirCategoryMapper against activity_type_configuration
epic-bufdir-report-export-foundation-task-015 — Write unit tests for BufdirCategoryMapper covering: successful mapping of all known activity types to their Bufdir codes, warning emission for unmapped activity types, batch mapping preserving input order, null safety on missing configuration rows, and audit log entry creation for unmapped types. Include a fixture of activity_type_configuration rows matching the current Bufdir category schema version.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 1 - 540 tasks
Can start after Tier 0 completes
Implementation Notes
Implement BufdirCategoryMapper with an in-memory Map
Document the schema version in a const String bufdirSchemaVersion = '2025-Q1' in the fixture file so tests self-document when they were last verified against the real schema.
Testing Requirements
Unit tests with flutter_test and mocked AuditLogger. Build fixture as a const list of ActivityTypeConfiguration objects covering all known Bufdir codes. Group tests: successful mappings (one per code), unmapped handling, batch ordering, null safety, audit logging. Use verify(mockAuditLogger.logUnmapped(any)).called(N) to assert exact audit call count.
Assert MappingWarning contains the unknown ID. Assert batch output list length equals input length. Run flutter test --coverage; confirm 100% method coverage.
NHF's three-level hierarchy (national / region / chapter) with 1,400 chapters may have edge cases such as chapters belonging to multiple regions, orphaned nodes, or missing parent links in the database. Incorrect scope expansion would silently under- or over-report activities, which could invalidate a Bufdir submission.
Mitigation & Contingency
Mitigation: Obtain a full hierarchy fixture export from NHF before implementation begins. Write exhaustive unit tests covering boundary cases: single chapter, full national roll-up, chapters with no activities, and chapters assigned to multiple regions. Validate resolver output against a known-good manual count.
Contingency: If hierarchy data quality is too poor for automated resolution at launch, implement a manual scope override in the coordinator UI that allows the coordinator to explicitly select org units from a tree picker, bypassing the resolver.
The activity_type_configuration table may not cover all activity types currently in use, leaving a subset unmapped at launch. Bufdir submissions with unmapped categories will be incomplete and may be rejected by Bufdir.
Mitigation & Contingency
Mitigation: Run a query against production activity data before implementation to enumerate all distinct activity type IDs. Cross-reference with Bufdir's published category schema (request from Norse Digital Products). Flag every gap as a known issue and build the warning surface into the preview panel.
Contingency: Implement a fallback 'Other' category bucket for unmapped types and surface a prominent warning in the export preview requiring coordinator acknowledgement before proceeding. Log unmapped types for post-launch cleanup.
Supabase RLS policies on generated_reports and the storage bucket must enforce strict org isolation. A misconfigured policy could allow a coordinator from one organisation to read another organisation's export files, creating a serious data breach with GDPR implications.
Mitigation & Contingency
Mitigation: Write RLS integration tests that attempt cross-org reads with explicitly different JWT tokens and assert that all attempts return empty sets or 403 errors. Include RLS policy review in the pull request checklist. Use Supabase's built-in policy tester during development.
Contingency: If a policy gap is discovered post-deployment, immediately revoke all signed URLs for affected exports, audit the access log for unauthorised reads, and issue a coordinated disclosure to affected organisations per GDPR breach notification requirements.