medium priority medium complexity testing pending testing specialist Tier 6

Acceptance Criteria

All form field validation errors render the correct error text inline below the relevant field when invalid input is submitted
Cycle prevention error message is displayed as a visible, non-dismissible inline alert when a node is set as a descendant of itself
Depth limit violation message appears when the selected parent would cause the node to exceed the maximum allowed nesting depth for NHF's 1,400-chapter tree
Searchable parent dropdown debounces input by at least 300ms before triggering a search query; no query fires on each keystroke
Dropdown shows a loading indicator while search is in progress and an empty-state message when no matches are found
Create mode renders the form with all fields empty and the submit button labeled 'Create unit'; edit mode pre-populates all fields with existing node data and labels the button 'Save changes'
All interactive form elements have Semantics labels meeting WCAG 2.2 AA: each field has a descriptive semanticsLabel, error states announce the error via Semantics.liveRegion or equivalent
Golden tests cover: empty create form, pre-populated edit form, form with validation errors visible, and dropdown open state
All tests pass with zero flakiness across 10 consecutive runs in CI
Test file is co-located with or clearly linked to the Hierarchy Node Editor widget source file

Technical Requirements

frameworks
flutter_test
flutter/material.dart
bloc_test (for BLoC state injection)
data models
OrganizationUnit
HierarchyNode
HierarchyValidationError
performance requirements
Each widget test must complete in under 2 seconds
Golden test image diffing tolerance set to no more than 0.5% pixel variance to avoid false positives on CI
security requirements
No real Supabase credentials used in tests; all Supabase calls must be mocked or stubbed
ui components
HierarchyNodeEditor widget
Searchable parent dropdown (DropdownSearch or custom implementation)
Inline validation error widgets
Cycle/depth-limit alert banner

Execution Context

Execution Tier
Tier 6

Tier 6 - 158 tasks

Can start after Tier 5 completes

Implementation Notes

Inject BLoC or Riverpod state directly via the widget constructor or a test-specific provider override rather than relying on a full app bootstrap — this keeps tests fast and deterministic. For debounce testing, use fake timers: tester.pump(Duration(milliseconds: 250)) should NOT trigger a search, tester.pump(Duration(milliseconds: 350)) should. For cycle detection error surfacing, emit the relevant BLoC error state before calling tester.pump() and assert the error widget appears. WCAG semantics tests are the most likely to be forgotten — write them first as a checklist.

Golden tests are fragile on different OS font rendering; pin the flutter SDK version in CI to prevent unexpected diffs. Store golden files under test/goldens/hierarchy_node_editor/.

Testing Requirements

Use flutter_test with WidgetTester for all tests. Provide a fake/stub implementation of the HierarchyService and BLoC dependencies using mockito or manual fakes — no live Supabase calls. Group tests into: (1) form validation group, (2) dropdown behavior group, (3) create vs edit mode group, (4) accessibility semantics group, (5) golden tests group. For semantics assertions use tester.getSemantics() and expect correct label, hint, and live-region flags.

Golden tests must be generated once on a canonical device size (e.g., iPhone 14 logical resolution) and checked into the repo. Run golden tests with --update-goldens only intentionally. Aim for 100% branch coverage of the HierarchyNodeEditor widget's rendering logic.

Component
Hierarchy Node Editor Screen
ui medium
Epic Risks (3)
high impact medium prob technical

Recursive aggregation queries across four hierarchy levels (national → region → local) with 1,400 leaf nodes may be too slow for real-time dashboard requests, exceeding the 200ms target and causing spinner timeouts.

Mitigation & Contingency

Mitigation: Implement aggregation as a Supabase RPC using a single recursive CTE rather than multiple round-trip queries. Pre-compute aggregations nightly via a scheduled Edge Function and cache results. For real-time needs, aggregate only the immediate subtree on demand.

Contingency: Surface a 'Refreshing...' indicator and serve stale cached aggregations immediately. Queue an async recalculation and push updated data via Supabase Realtime when ready, avoiding blocking the admin dashboard.

medium impact medium prob scope

The 5-chapter limit and primary-assignment constraint are NHF-specific. Applying these rules globally may break HLF and Blindeforbundet configurations where different limits apply, requiring per-organization configuration that was not initially scoped.

Mitigation & Contingency

Mitigation: Make the maximum assignment count a configurable value stored in the organization's feature-flag or settings table rather than a hardcoded constant. Design the assignment service to read this limit at runtime per organization.

Contingency: Default the limit to a high value (e.g., 100) for organizations other than NHF, effectively making it non-restrictive, while keeping the enforcement logic intact for when per-org configuration is fully implemented.

medium impact low prob technical

The searchable parent dropdown in HierarchyNodeEditor must search across up to 1,400 units efficiently. Client-side filtering of the full hierarchy may be slow; server-side search adds complexity and latency.

Mitigation & Contingency

Mitigation: Use the in-memory hierarchy cache as the search corpus — since the cache already holds the flat unit list, client-side filtering with a debounced input is sufficient and avoids extra Supabase calls. Pre-build a search index on cache load.

Contingency: Cap the dropdown to showing the 50 most recently accessed units by default, with a 'search all' option that triggers a server-side full-text query. This keeps the common case fast while supporting edge cases.