forked from OurHike/OurHike
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHeader.test.tsx
More file actions
87 lines (66 loc) · 2.84 KB
/
Copy pathHeader.test.tsx
File metadata and controls
87 lines (66 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { describe, it, expect, vi, afterEach } from 'vitest'
import { render, screen, cleanup } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Header } from './Header'
// WIREFRAMES.md, map screen §2 - the header is a READ-ONLY zone. Trail + state
// eyebrow, current mile + direction in mono, and on the right exactly two 38px
// icon buttons: legend then search. The doc's words are "Nothing else lives
// here," which is a real constraint worth a regression test - the header is
// prime screen space and the obvious place for scope to creep.
const PROPS = {
trailName: 'Appalachian Trail',
state: 'Virginia',
mile: 1407.2,
direction: 'NOBO' as const,
onOpenLegend: vi.fn(),
onOpenSearch: vi.fn(),
}
afterEach(() => {
cleanup()
vi.clearAllMocks()
})
describe('Header', () => {
it('names the trail and the state in the eyebrow', () => {
render(<Header {...PROPS} />)
expect(screen.getByText(/Appalachian Trail/)).toBeInTheDocument()
expect(screen.getByText(/Virginia/)).toBeInTheDocument()
})
it('renders mile and direction exactly as WIREFRAMES.md spells them', () => {
render(<Header {...PROPS} />)
// "mi 1,407.2 · NOBO" - thousands separator, one decimal place.
expect(screen.getByText('mi 1,407.2 · NOBO')).toBeInTheDocument()
})
it('keeps one decimal place even on a whole mile, so the number never jitters in width', () => {
render(<Header {...PROPS} mile={1400} />)
expect(screen.getByText('mi 1,400.0 · NOBO')).toBeInTheDocument()
})
it('renders a southbound hike as SOBO', () => {
render(<Header {...PROPS} direction="SOBO" />)
expect(screen.getByText('mi 1,407.2 · SOBO')).toBeInTheDocument()
})
it('offers exactly two buttons - legend, then search - and nothing else', () => {
render(<Header {...PROPS} />)
const buttons = screen.getAllByRole('button')
expect(buttons).toHaveLength(2)
expect(buttons[0]).toHaveAccessibleName(/legend/i)
expect(buttons[1]).toHaveAccessibleName(/search/i)
})
it('opens the legend when the legend button is pressed', async () => {
const user = userEvent.setup()
render(<Header {...PROPS} />)
await user.click(screen.getByRole('button', { name: /legend/i }))
expect(PROPS.onOpenLegend).toHaveBeenCalledTimes(1)
expect(PROPS.onOpenSearch).not.toHaveBeenCalled()
})
it('opens search when the search button is pressed', async () => {
const user = userEvent.setup()
render(<Header {...PROPS} />)
await user.click(screen.getByRole('button', { name: /search/i }))
expect(PROPS.onOpenSearch).toHaveBeenCalledTimes(1)
expect(PROPS.onOpenLegend).not.toHaveBeenCalled()
})
it('is a banner landmark, so the read-only zone is skippable by screen reader', () => {
render(<Header {...PROPS} />)
expect(screen.getByRole('banner')).toBeInTheDocument()
})
})