Barazo default frontend barazo.forum
at main 94 lines 3.7 kB view raw
1/** 2 * Tests for SaveButton component. 3 * Renders button with state-driven text/icon for idle, saving, and saved states. 4 */ 5 6import { describe, it, expect, vi } from 'vitest' 7import { render, screen } from '@testing-library/react' 8import userEvent from '@testing-library/user-event' 9import { axe } from 'vitest-axe' 10import { SaveButton } from './save-button' 11 12describe('SaveButton', () => { 13 it('renders default label in idle state', () => { 14 render(<SaveButton status="idle" onClick={vi.fn()} />) 15 expect(screen.getByRole('button', { name: /save/i })).toBeInTheDocument() 16 expect(screen.getByRole('button')).toBeEnabled() 17 }) 18 19 it('renders custom label in idle state', () => { 20 render(<SaveButton status="idle" onClick={vi.fn()} label="Save Settings" />) 21 expect(screen.getByRole('button', { name: /save settings/i })).toBeInTheDocument() 22 }) 23 24 it('renders saving label and is disabled in saving state', () => { 25 render(<SaveButton status="saving" onClick={vi.fn()} />) 26 const button = screen.getByRole('button', { name: /saving/i }) 27 expect(button).toBeDisabled() 28 }) 29 30 it('renders custom saving label', () => { 31 render(<SaveButton status="saving" onClick={vi.fn()} savingLabel="Recomputing..." />) 32 expect(screen.getByRole('button', { name: /recomputing/i })).toBeDisabled() 33 }) 34 35 it('renders saved label with check icon in saved state', () => { 36 render(<SaveButton status="saved" onClick={vi.fn()} />) 37 const button = screen.getByRole('button', { name: /saved/i }) 38 expect(button).toBeEnabled() 39 }) 40 41 it('renders custom saved label', () => { 42 render(<SaveButton status="saved" onClick={vi.fn()} savedLabel="Started" />) 43 expect(screen.getByRole('button', { name: /started/i })).toBeInTheDocument() 44 }) 45 46 it('calls onClick when clicked in idle state', async () => { 47 const user = userEvent.setup() 48 const onClick = vi.fn() 49 render(<SaveButton status="idle" onClick={onClick} />) 50 await user.click(screen.getByRole('button')) 51 expect(onClick).toHaveBeenCalledOnce() 52 }) 53 54 it('does not call onClick when disabled in saving state', async () => { 55 const user = userEvent.setup() 56 const onClick = vi.fn() 57 render(<SaveButton status="saving" onClick={onClick} />) 58 await user.click(screen.getByRole('button')) 59 expect(onClick).not.toHaveBeenCalled() 60 }) 61 62 it('has aria-live status region for screen readers', () => { 63 const { rerender } = render(<SaveButton status="idle" onClick={vi.fn()} />) 64 const liveRegion = screen.getByRole('status') 65 expect(liveRegion).toBeInTheDocument() 66 expect(liveRegion).toHaveTextContent('') 67 68 rerender(<SaveButton status="saved" onClick={vi.fn()} />) 69 expect(liveRegion).toHaveTextContent('Saved.') 70 }) 71 72 it('announces custom saved label to screen readers', () => { 73 render(<SaveButton status="saved" onClick={vi.fn()} savedLabel="Started" />) 74 expect(screen.getByRole('status')).toHaveTextContent('Started.') 75 }) 76 77 it('applies custom className', () => { 78 render(<SaveButton status="idle" onClick={vi.fn()} className="mt-4" />) 79 const button = screen.getByRole('button') 80 expect(button.className).toContain('mt-4') 81 }) 82 83 it('passes axe accessibility check in idle state', async () => { 84 const { container } = render(<SaveButton status="idle" onClick={vi.fn()} />) 85 const results = await axe(container) 86 expect(results).toHaveNoViolations() 87 }) 88 89 it('passes axe accessibility check in saved state', async () => { 90 const { container } = render(<SaveButton status="saved" onClick={vi.fn()} />) 91 const results = await axe(container) 92 expect(results).toHaveNoViolations() 93 }) 94})