/**
* Tests for SaveButton component.
* Renders button with state-driven text/icon for idle, saving, and saved states.
*/
import { describe, it, expect, vi } from 'vitest'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { axe } from 'vitest-axe'
import { SaveButton } from './save-button'
describe('SaveButton', () => {
it('renders default label in idle state', () => {
render()
expect(screen.getByRole('button', { name: /save/i })).toBeInTheDocument()
expect(screen.getByRole('button')).toBeEnabled()
})
it('renders custom label in idle state', () => {
render()
expect(screen.getByRole('button', { name: /save settings/i })).toBeInTheDocument()
})
it('renders saving label and is disabled in saving state', () => {
render()
const button = screen.getByRole('button', { name: /saving/i })
expect(button).toBeDisabled()
})
it('renders custom saving label', () => {
render()
expect(screen.getByRole('button', { name: /recomputing/i })).toBeDisabled()
})
it('renders saved label with check icon in saved state', () => {
render()
const button = screen.getByRole('button', { name: /saved/i })
expect(button).toBeEnabled()
})
it('renders custom saved label', () => {
render()
expect(screen.getByRole('button', { name: /started/i })).toBeInTheDocument()
})
it('calls onClick when clicked in idle state', async () => {
const user = userEvent.setup()
const onClick = vi.fn()
render()
await user.click(screen.getByRole('button'))
expect(onClick).toHaveBeenCalledOnce()
})
it('does not call onClick when disabled in saving state', async () => {
const user = userEvent.setup()
const onClick = vi.fn()
render()
await user.click(screen.getByRole('button'))
expect(onClick).not.toHaveBeenCalled()
})
it('has aria-live status region for screen readers', () => {
const { rerender } = render()
const liveRegion = screen.getByRole('status')
expect(liveRegion).toBeInTheDocument()
expect(liveRegion).toHaveTextContent('')
rerender()
expect(liveRegion).toHaveTextContent('Saved.')
})
it('announces custom saved label to screen readers', () => {
render()
expect(screen.getByRole('status')).toHaveTextContent('Started.')
})
it('applies custom className', () => {
render()
const button = screen.getByRole('button')
expect(button.className).toContain('mt-4')
})
it('passes axe accessibility check in idle state', async () => {
const { container } = render()
const results = await axe(container)
expect(results).toHaveNoViolations()
})
it('passes axe accessibility check in saved state', async () => {
const { container } = render()
const results = await axe(container)
expect(results).toHaveNoViolations()
})
})