cqt-agent
Version:
159 lines (122 loc) • 4.34 kB
text/typescript
// Vitest Unit Test Template
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { Component } from '../Component'
// Mock dependencies
vi.mock('../hooks/useCustomHook')
vi.mock('../services/apiService')
const mockUseCustomHook = vi.mocked(useCustomHook)
const mockApiService = vi.mocked(apiService)
describe('Component', () => {
const defaultProps = {
// Define default props here
id: 'test-id',
onAction: vi.fn(),
initialValue: 'test'
}
beforeEach(() => {
vi.clearAllMocks()
// Set up common mock implementations
mockUseCustomHook.mockReturnValue({
data: null,
loading: false,
error: null
})
})
afterEach(() => {
vi.clearAllTimers()
})
describe('Rendering', () => {
it('should render with default props', () => {
render(<Component {...defaultProps} />)
expect(screen.getByTestId('test-id')).toBeInTheDocument()
})
it('should render loading state', () => {
mockUseCustomHook.mockReturnValue({
data: null,
loading: true,
error: null
})
render(<Component {...defaultProps} />)
expect(screen.getByRole('progressbar')).toBeInTheDocument()
expect(screen.getByText('Loading...')).toBeInTheDocument()
})
it('should render error state', () => {
const error = new Error('Test error')
mockUseCustomHook.mockReturnValue({
data: null,
loading: false,
error
})
render(<Component {...defaultProps} />)
expect(screen.getByText('Error: Test error')).toBeInTheDocument()
})
})
describe('User Interactions', () => {
it('should handle click events', async () => {
render(<Component {...defaultProps} />)
const button = screen.getByRole('button', { name: /action/i })
fireEvent.click(button)
expect(defaultProps.onAction).toHaveBeenCalledTimes(1)
})
it('should handle keyboard events', () => {
render(<Component {...defaultProps} />)
const input = screen.getByRole('textbox')
fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' })
expect(defaultProps.onAction).toHaveBeenCalled()
})
})
describe('Data Fetching', () => {
it('should fetch data on mount', async () => {
mockApiService.fetchData.mockResolvedValue({ result: 'success' })
render(<Component {...defaultProps} />)
await waitFor(() => {
expect(mockApiService.fetchData).toHaveBeenCalledWith(defaultProps.id)
})
})
it('should handle fetch errors', async () => {
mockApiService.fetchData.mockRejectedValue(new Error('Network error'))
render(<Component {...defaultProps} />)
await waitFor(() => {
expect(screen.getByText('Unable to load data')).toBeInTheDocument()
})
})
})
describe('Accessibility', () => {
it('should have proper ARIA attributes', () => {
render(<Component {...defaultProps} />)
expect(screen.getByRole('main')).toHaveAttribute('aria-label')
expect(screen.getByRole('button')).toHaveAttribute('aria-describedby')
})
it('should support keyboard navigation', () => {
render(<Component {...defaultProps} />)
const firstFocusable = screen.getByRole('button')
firstFocusable.focus()
expect(firstFocusable).toHaveFocus()
})
it('should announce important state changes', async () => {
render(<Component {...defaultProps} />)
const button = screen.getByRole('button')
fireEvent.click(button)
await waitFor(() => {
expect(screen.getByRole('status')).toHaveTextContent('Action completed')
})
})
})
describe('Edge Cases', () => {
it('should handle null props gracefully', () => {
expect(() => {
render(<Component {...defaultProps} initialValue={null} />)
}).not.toThrow()
})
it('should handle empty state', () => {
mockUseCustomHook.mockReturnValue({
data: [],
loading: false,
error: null
})
render(<Component {...defaultProps} />)
expect(screen.getByText('No items found')).toBeInTheDocument()
})
})
})