Feat/frontend tests (#62)

* test(frontend): add vitest test infrastructure

- Add vitest, testing-library, jsdom dependencies
- Configure vitest with jsdom environment
- Add test setup with mocks for fetch, localStorage, matchMedia
- Set 75% coverage threshold

* Add frontend tests (#61)

* Initial plan

* Add frontend tests - utilities, hooks, and components (21% coverage)

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Add more component tests (Auth, AboutModal, ExportModal) and useRefill hook tests - 30% coverage

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Add useMedicationForm utility function tests - 30% coverage

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Add AppHeader tests and more schedule.ts tests - 32% coverage

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Changes before error encountered

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Fix page tests and add more tests - 326 tests passing, 34% coverage

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Add tests for ProfileModal, UserFilterModal, MedDetailModal - 361 tests, 36% coverage

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Add SharedSchedule tests - 366 tests, 39% coverage

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Expand page tests - 383 tests, 39% coverage

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Add MobileEditModal tests - 409 tests, 40% coverage

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Expand Dashboard and Schedule page tests - 427 tests, 40% coverage

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* Fix code review issues - remove invalid remindEnabled property

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>
This commit is contained in:
Daniel Volz
2026-01-22 10:25:11 +01:00
committed by GitHub
parent 8718311876
commit fd055a3a2a
36 changed files with 7602 additions and 3 deletions
@@ -0,0 +1,67 @@
import { describe, it, expect, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { MedicationAvatar } from '../../components/MedicationAvatar';
describe('MedicationAvatar', () => {
it('renders initials when no image provided', () => {
render(<MedicationAvatar name="Test Medication" />);
expect(screen.getByText('TM')).toBeInTheDocument();
});
it('uses first two initials from medication name', () => {
render(<MedicationAvatar name="Very Long Medication Name" />);
expect(screen.getByText('VL')).toBeInTheDocument();
});
it('handles single word names', () => {
render(<MedicationAvatar name="Aspirin" />);
expect(screen.getByText('A')).toBeInTheDocument();
});
it('renders image when imageUrl provided', () => {
render(<MedicationAvatar name="Test Med" imageUrl="test-image.jpg" />);
const img = screen.getByAltText('Test Med');
expect(img).toBeInTheDocument();
expect(img).toHaveAttribute('src', '/api/images/test-image.jpg');
});
it('applies small size class by default', () => {
const { container } = render(<MedicationAvatar name="Test" />);
expect(container.querySelector('.med-avatar-sm')).toBeInTheDocument();
});
it('applies medium size class', () => {
const { container } = render(<MedicationAvatar name="Test" size="md" />);
expect(container.querySelector('.med-avatar-md')).toBeInTheDocument();
});
it('applies large size class', () => {
const { container } = render(<MedicationAvatar name="Test" size="lg" />);
expect(container.querySelector('.med-avatar-lg')).toBeInTheDocument();
});
it('handles empty name with fallback', () => {
render(<MedicationAvatar name="" />);
expect(screen.getByText('?')).toBeInTheDocument();
});
it('converts initials to uppercase', () => {
render(<MedicationAvatar name="lower case" />);
expect(screen.getByText('LC')).toBeInTheDocument();
});
it('adds initials class when no image', () => {
const { container } = render(<MedicationAvatar name="Test" />);
expect(container.querySelector('.med-avatar-initials')).toBeInTheDocument();
});
});