test: Improve Unit Test Coverage Across Components (LanguageSwitcher, Dashboard, Dropdown, VitalsByComponent)
Overview
This MR improves unit test coverage across multiple components and pages, and removes a small unreachable fallback branch in the LanguageSwitcherWithLabel wrapper. The goal is to bring all targeted files to 100% unit test coverage while keeping runtime behavior unchanged.
What does this MR do and why?
Several components had uncovered paths in their rendering logic, async handlers, and utility functions. This MR adds targeted unit tests across LanguageSwitcher, DashboardPage, dropdown UI, and VitalsByComponent to cover those branches. It also verifies storage sync behavior triggered during language changes.
While adding tests, one unreachable branch was identified in LanguageSwitcherWithLabel: label || t('language.title') was nested inside label &&, so the fallback could never execute. That logic was simplified to remove dead code.
There are no intended user-facing behavior changes beyond this internal cleanup.
Changes Made
- Added unit tests for
LanguageSwitcher(icon-only, display variants, language selection, active marker, storage event) - Added test coverage for
LanguageSwitcherWithLabel(wrapper rendering, label/description props) - Added test coverage for
getRoleLanguageHint(known and unknown roles) - Added/updated tests for
DashboardPage - Added/updated tests for dropdown UI component
- Added/updated tests for
VitalsByComponent - Removed unreachable fallback logic from
LanguageSwitcherWithLabel - Removed now-unused
useTranslationcall from the wrapper component
Technical Details
Root cause:
- Multiple components had uncovered branches, especially around conditional rendering, async handlers, and helper fallback logic.
- One branch in
LanguageSwitcherWithLabelwas structurally unreachable becauselabel || t('language.title')was guarded bylabel &&.
Fix approach:
- Added isolated unit tests with mocked translation and component primitives to exercise each branch deterministically.
- Simplified unreachable wrapper logic so branch coverage reflects real executable behavior.
Trade-offs:
- Tests use UI and i18n mocks to keep them focused and reliable rather than relying on full Radix/component-tree behavior.
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
Also includes a minor
♻ ️ refactor — dead code removal inLanguageSwitcherWithLabel
Related Issues / References
No linked issue in this change set.
Screenshots or Screen Recordings
Not applicable. No visible UI changes intended.
How to Set Up and Validate Locally
- Checkout this branch
- Install dependencies:
bun install
- Run the targeted coverage test:
npm run test:coverage
Expected result: All new/updated tests pass; LanguageSwitcher.tsx reports 100% statements, branches, functions, and lines.
Testing Done
-
Manual testing completed -
Unit tests added/updated
Test Cases Covered:
| Scenario | Expected Result | Status |
|---|---|---|
| Default icon-only switcher render | Trigger renders without current-language label text | |
| Native/English display variants | Correct display text shown for each prop combination | |
| Language selection |
changeLanguage is called and storage event is dispatched |
|
| Active language marker | Current language shows checkmark in dropdown list | |
| Wrapper rendering | Label/description render correctly when provided | |
| Role hint helper | Known roles return mapped hints, unknown roles fall back to patient hint | |
| DashboardPage | Updated tests pass with correct role-based rendering | |
| Dropdown UI | Component branches covered with isolated unit tests | |
| VitalsByComponent | All rendering paths and edge cases covered |
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
Component Patterns
-
shadcn/ui components used correctly -
Tailwind classes follow utility-first approach -
Responsive design considered (mobile-first if applicable) -
Accessibility attributes included (aria-*, role, etc.) -
Icons from lucide-react used consistently
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 -
Use of Zod for data validations
Error Handling
-
Errors are caught and handled gracefully -
User-friendly error messages displayed -
Errors are being toasted properly -
Network failures handled appropriately
Documentation
-
README.md updated (if setup steps changed) -
.env.exampleupdated (if new env vars added) -
CHANGELOG.md updated (if applicable)
Known Limitations / Technical Debt
- Repository-wide
i18n:checkis currently failing due to existing hardcoded strings outside the scope of this MR. - This MR validates targeted components with isolated unit tests but does not address broader project-wide i18n cleanup.
Additional Notes
Files changed:
| File | Changes |
|---|---|
src/components/LanguageSwitcher.tsx |
+1 -7 |
tests/unit/components/LanguageSwitcher.test.tsx |
+236 -0 |
tests/pages/DashboardPage.test.tsx |
+93 -42 |
tests/unit/components/ui/dropdown...test.tsx |
+101 -0 |
tests/unit/components/VitalsByC...n.test.tsx |
+160 -0 |
MR Acceptance Checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.