Files
archon/archon-ui-main/test/errors.test.tsx

199 lines
6.1 KiB
TypeScript

import { render, screen, fireEvent } from '@testing-library/react'
import { describe, test, expect, vi } from 'vitest'
import React from 'react'
describe('Error Handling Tests', () => {
test('api error simulation', () => {
const MockApiComponent = () => {
const [error, setError] = React.useState('')
const [loading, setLoading] = React.useState(false)
const fetchData = async () => {
setLoading(true)
try {
// Simulate API error
throw new Error('Network error')
} catch (err) {
setError('Failed to load data')
} finally {
setLoading(false)
}
}
return (
<div>
<button onClick={fetchData}>Load Data</button>
{loading && <div>Loading...</div>}
{error && <div role="alert">{error}</div>}
</div>
)
}
render(<MockApiComponent />)
fireEvent.click(screen.getByText('Load Data'))
expect(screen.getByRole('alert')).toHaveTextContent('Failed to load data')
})
test('timeout error simulation', () => {
const MockTimeoutComponent = () => {
const [status, setStatus] = React.useState('idle')
const handleTimeout = () => {
setStatus('loading')
setTimeout(() => {
setStatus('timeout')
}, 100)
}
return (
<div>
<button onClick={handleTimeout}>Start Request</button>
{status === 'loading' && <div>Loading...</div>}
{status === 'timeout' && <div role="alert">Request timed out</div>}
</div>
)
}
render(<MockTimeoutComponent />)
fireEvent.click(screen.getByText('Start Request'))
expect(screen.getByText('Loading...')).toBeInTheDocument()
// Wait for timeout
setTimeout(() => {
expect(screen.getByRole('alert')).toHaveTextContent('Request timed out')
}, 150)
})
test('form validation errors', () => {
const MockFormErrors = () => {
const [values, setValues] = React.useState({ name: '', email: '' })
const [errors, setErrors] = React.useState<string[]>([])
const validate = () => {
const newErrors: string[] = []
if (!values.name) newErrors.push('Name is required')
if (!values.email) newErrors.push('Email is required')
if (values.email && !values.email.includes('@')) {
newErrors.push('Invalid email format')
}
setErrors(newErrors)
}
return (
<div>
<input
placeholder="Name"
value={values.name}
onChange={(e) => setValues({ ...values, name: e.target.value })}
/>
<input
placeholder="Email"
value={values.email}
onChange={(e) => setValues({ ...values, email: e.target.value })}
/>
<button onClick={validate}>Submit</button>
{errors.length > 0 && (
<div role="alert">
{errors.map((error, index) => (
<div key={index}>{error}</div>
))}
</div>
)}
</div>
)
}
render(<MockFormErrors />)
// Submit empty form
fireEvent.click(screen.getByText('Submit'))
const alert = screen.getByRole('alert')
expect(alert).toHaveTextContent('Name is required')
expect(alert).toHaveTextContent('Email is required')
})
test('connection error recovery', () => {
const MockConnection = () => {
const [connected, setConnected] = React.useState(true)
const [error, setError] = React.useState('')
const handleDisconnect = () => {
setConnected(false)
setError('Connection lost')
}
const handleReconnect = () => {
setConnected(true)
setError('')
}
return (
<div>
<div>Status: {connected ? 'Connected' : 'Disconnected'}</div>
{error && <div role="alert">{error}</div>}
<button onClick={handleDisconnect}>Simulate Disconnect</button>
<button onClick={handleReconnect}>Reconnect</button>
</div>
)
}
render(<MockConnection />)
expect(screen.getByText('Status: Connected')).toBeInTheDocument()
fireEvent.click(screen.getByText('Simulate Disconnect'))
expect(screen.getByText('Status: Disconnected')).toBeInTheDocument()
expect(screen.getByRole('alert')).toHaveTextContent('Connection lost')
fireEvent.click(screen.getByText('Reconnect'))
expect(screen.getByText('Status: Connected')).toBeInTheDocument()
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
})
test('user friendly error messages', () => {
const MockErrorMessages = () => {
const [errorType, setErrorType] = React.useState('')
const getErrorMessage = (type: string) => {
switch (type) {
case '401':
return 'Please log in to continue'
case '403':
return "You don't have permission to access this"
case '404':
return "We couldn't find what you're looking for"
case '500':
return 'Something went wrong on our end'
default:
return ''
}
}
return (
<div>
<button onClick={() => setErrorType('401')}>401 Error</button>
<button onClick={() => setErrorType('403')}>403 Error</button>
<button onClick={() => setErrorType('404')}>404 Error</button>
<button onClick={() => setErrorType('500')}>500 Error</button>
{errorType && (
<div role="alert">{getErrorMessage(errorType)}</div>
)}
</div>
)
}
render(<MockErrorMessages />)
fireEvent.click(screen.getByText('401 Error'))
expect(screen.getByRole('alert')).toHaveTextContent('Please log in to continue')
fireEvent.click(screen.getByText('404 Error'))
expect(screen.getByRole('alert')).toHaveTextContent("We couldn't find what you're looking for")
fireEvent.click(screen.getByText('500 Error'))
expect(screen.getByRole('alert')).toHaveTextContent('Something went wrong on our end')
})
})