425e29ea21
New components (all with .tsx + .test.tsx, 90%+ coverage): - CalendarDay: day cell with event badges - CalendarEvent: colored event chip with dismiss option - DaysBreakdown: table of days by type - ProgressChart: progress bar toward age-4 deadline - TipCard: optimization tip card with severity badges - VacationDaysInput: number input with min/max validation - ParentProfileInput: dual selects for salary type & employment status - PlanningGoalSelector: radio buttons for planning goal - BreakPeriodsInput: list manager with inline add/edit form All components follow existing patterns from Header/Footer: - Typed props interfaces (exported) - Semantic HTML with data-testid & ARIA attributes - No business logic, purely presentational - Comprehensive test coverage including edge cases npm test: 22 files, 167 tests passing npx tsc --noEmit: clean Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
51 lines
2.0 KiB
TypeScript
51 lines
2.0 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { render } from '@testing-library/react'
|
|
import { DaysBreakdown } from './DaysBreakdown'
|
|
|
|
describe('DaysBreakdown', () => {
|
|
it('renders empty state when no breakdown provided', () => {
|
|
const { getByTestId } = render(<DaysBreakdown breakdown={[]} />)
|
|
expect(getByTestId('days-breakdown').textContent).toContain('No days recorded yet')
|
|
})
|
|
|
|
it('renders table with breakdown data', () => {
|
|
const breakdown = [
|
|
{ type: 'vacation', count: 10 },
|
|
{ type: 'sick leave', count: 3 },
|
|
{ type: 'parental', count: 50 },
|
|
]
|
|
const { getByTestId } = render(<DaysBreakdown breakdown={breakdown} />)
|
|
const table = getByTestId('days-breakdown')
|
|
expect(table.querySelector('table')).toBeInTheDocument()
|
|
expect(table.textContent).toContain('vacation')
|
|
expect(table.textContent).toContain('10')
|
|
})
|
|
|
|
it('renders correct number of rows', () => {
|
|
const breakdown = [
|
|
{ type: 'vacation', count: 10 },
|
|
{ type: 'sick leave', count: 3 },
|
|
{ type: 'parental', count: 50 },
|
|
]
|
|
const { getByTestId } = render(<DaysBreakdown breakdown={breakdown} />)
|
|
expect(getByTestId('breakdown-row-vacation')).toBeInTheDocument()
|
|
expect(getByTestId('breakdown-row-sick leave')).toBeInTheDocument()
|
|
expect(getByTestId('breakdown-row-parental')).toBeInTheDocument()
|
|
})
|
|
|
|
it('displays correct values in table', () => {
|
|
const breakdown = [{ type: 'vacation', count: 25 }]
|
|
const { getByTestId } = render(<DaysBreakdown breakdown={breakdown} />)
|
|
const row = getByTestId('breakdown-row-vacation')
|
|
expect(row.textContent).toContain('vacation')
|
|
expect(row.textContent).toContain('25')
|
|
})
|
|
|
|
it('renders table headers', () => {
|
|
const breakdown = [{ type: 'vacation', count: 10 }]
|
|
const { getByTestId } = render(<DaysBreakdown breakdown={breakdown} />)
|
|
const table = getByTestId('days-breakdown').querySelector('table')
|
|
expect(table?.querySelector('thead')).toBeInTheDocument()
|
|
})
|
|
})
|