Phase 2: Build 9 presentational components with full test coverage
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>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
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()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user