Ui/mobile ui
Overview
This Merge Request dramatically enhances the frontend unit test coverage for the volunteer-facing components: PatientHistoryPage and RecordVitalsPage. By implementing comprehensive coverage for complex edge cases, keyboard input preventions, robust API error handlers, and loading states, we successfully satisfied the rigorous branch coverage requirements for these critical workflow panels.
What does this MR do and why?
To ensure frontend reliability and meet the pipeline's strict global branch coverage threshold, we targeted low-coverage components highlighted in recent reports:
-
RecordVitalsPage(Vitals Recording Form):- Covered keydown input prevention (
preventNonNumericKeys) verifying that alphabetical and invalid symbols are blocked while control keys (e.g. Backspace, Delete) remain functional. - Tested diverse API mutation error structures (
updateVitals.onError), including string rejections, standard Error instances, missing nested Axios metadata, and circular structure JSON-parsing failures (forcing the try-catch block). - Validated submit-time checks where invalid numeric/temperature strings (e.g.
NaNor decimals) bypass initial cleanings, verifying the toast notification is correctly dispatched.
- Covered keydown input prevention (
-
PatientHistoryPage(Patient Detail / Case Record View):- Added edge cases covering empty history records where vitals contain
nullfields, asserting that--fallback structures are rendered correctly. - Verified that consultations with missing camp locations gracefully default to
"Unknown location". - Simulated pending mutation states during vitals updates inside the dialog box to assert the loading spinner is displayed properly.
- Added edge cases covering empty history records where vitals contain
All tests compile with strict TypeScript rules and pass all linter and CI checks with zero errors.
Changes Made
Tests Modified
- 🧪 PatientHistoryPage.test.tsx - Appended new describe block targeting missing edge cases, null histories, null camp location consultation, and pending loaders.
- 🧪 RecordVitalsPage.test.tsx - Added describe block validating keyboard blocking events, 4 distinct API error scenarios, and submit-time NaN validation.
Technical Details
-
KeyboardEvent Simulation: Leveraged
vi.spyOn(KeyboardEvent.prototype, 'preventDefault')combined with RTLfireEvent.keyDownto reliably check character interception under React 19's event delegation layer. -
Strict Typing Workarounds: Formulated precise mock configurations and structured error castings to fully avoid using the
anytype, aligning with@typescript-eslint/no-explicit-anyESLint rules.
Type of Change
-
🐛 Bug fix (non-breaking change that fixes an issue) -
✨ New feature (non-breaking change that adds functionality) -
💥 Breaking change (fix or feature that would cause existing functionality to change) -
📝 Documentation update -
🎨 UI/UX improvement -
♻ ️ Refactor (no functional changes) -
⚡ Performance improvement -
🧪 Test update -
🔧 Configuration change -
🚨 Security fix
Related Issues / References
closes #352 (closed)
Screenshots or Screen Recordings
Tests run results and coverage passing metrics are documented in the table below.
How to Set Up and Validate Locally
-
Pull the
UI/mobile_uibranch. -
Run the linter:
bun run lint -
Execute the unit test suites:
bun x vitest run tests/volunteers/PatientHistoryPage.test.tsx bun x vitest run tests/volunteers/RecordVitalsPage.test.tsx -
Verify global branch coverage exceeds target requirements:
bun x vitest run --coverage
Testing Done
-
Manual testing completed (Verified that linter, type-check, and build steps succeed) -
Unit tests added/updated
Test Cases Covered:
| Scenario | Expected Result | Status |
|---|---|---|
| Vitals Input keyboard handler intercepts alpha characters |
event.preventDefault() called for 'a', but bypassed for control keys |
|
| Vitals Mutation fails with standard Error | Toast displays correct generic error message | |
| Vitals Mutation fails with complex non-detailed error object | Error JSON representation extracted and handled gracefully | |
| Vitals Mutation rejects with a primitive string | Toast displays primitive string content safely | |
| Vitals Mutation throws during circular error stringification | Caught in try-catch block, fallbacks safely to error.message
|
|
| Empty Patient History data rendering | Null vital numbers map to -- fallbacks correctly |
|
| Consultation without camp location record | Component renders Unknown location badge gracefully |
|
| Dialog Vitals Update loading state | Loader spinner animate-spin is visible during pending updates |
Code Quality Checklist
Code Standards
-
Code follows project conventions (naming, structure, formatting) -
No console.log() or debugger statements left in code -
No unused imports, variables, or functions -
No duplicate code and use of existing components for reusability -
i18n check passed with no hardcoded strings in codebase for i18n support -
TypeScript types are properly defined (no anyunless justified) -
ESLint and Prettier checks pass bun run lint
React Best Practices
-
Components are properly split and single-responsibility -
Hooks follow rules (no conditional hooks, proper dependencies) -
State management is appropriate (local vs global state) -
No unnecessary re-renders (memoization used where needed) -
Event handlers are properly cleaned up
API & Data Fetching
-
TanStack Query used for server state (if applicable) -
Loading and error states handled -
API types defined in src/types/api.ts -
Axios interceptors handle auth tokens correctly
Error Handling
-
Errors are caught and handled gracefully -
User-friendly error messages displayed -
Errors are being toasted properly -
Network failures handled appropriately
Known Limitations / Technical Debt

dc2bb25ca152de01aecc4549495545/Screenshot_From_2026-05-23_14-30-28.png)
None identified. Coverage thresholds were successfully exceeded with optimal codebase sanity.






