119 lines
3.5 KiB
JavaScript
119 lines
3.5 KiB
JavaScript
import { describe, it, expect } from 'vitest'
|
|
import {
|
|
AppError,
|
|
ValidationError,
|
|
NotFoundError,
|
|
UnauthorizedError,
|
|
ForbiddenError,
|
|
ConflictError,
|
|
formatErrorResponse,
|
|
} from '../../server/utils/errors.js'
|
|
|
|
describe('errors', () => {
|
|
describe('AppError', () => {
|
|
it('creates error with default status code', () => {
|
|
const error = new AppError('Test error')
|
|
expect(error.message).toBe('Test error')
|
|
expect(error.statusCode).toBe(500)
|
|
expect(error.code).toBe('INTERNAL_ERROR')
|
|
expect(error).toBeInstanceOf(Error)
|
|
})
|
|
|
|
it('creates error with custom status code and code', () => {
|
|
const error = new AppError('Custom error', 400, 'CUSTOM_CODE')
|
|
expect(error.statusCode).toBe(400)
|
|
expect(error.code).toBe('CUSTOM_CODE')
|
|
})
|
|
})
|
|
|
|
describe('ValidationError', () => {
|
|
it('creates validation error with 400 status', () => {
|
|
const error = new ValidationError('Invalid input')
|
|
expect(error.statusCode).toBe(400)
|
|
expect(error.code).toBe('VALIDATION_ERROR')
|
|
expect(error.details).toBeNull()
|
|
})
|
|
|
|
it('includes details when provided', () => {
|
|
const details = { field: 'email', reason: 'invalid format' }
|
|
const error = new ValidationError('Invalid input', details)
|
|
expect(error.details).toEqual(details)
|
|
})
|
|
})
|
|
|
|
describe('NotFoundError', () => {
|
|
it('creates not found error with default message', () => {
|
|
const error = new NotFoundError()
|
|
expect(error.statusCode).toBe(404)
|
|
expect(error.code).toBe('NOT_FOUND')
|
|
expect(error.message).toBe('Resource not found')
|
|
})
|
|
|
|
it('creates not found error with custom resource', () => {
|
|
const error = new NotFoundError('User')
|
|
expect(error.message).toBe('User not found')
|
|
})
|
|
})
|
|
|
|
describe('UnauthorizedError', () => {
|
|
it('creates unauthorized error', () => {
|
|
const error = new UnauthorizedError()
|
|
expect(error.statusCode).toBe(401)
|
|
expect(error.code).toBe('UNAUTHORIZED')
|
|
expect(error.message).toBe('Unauthorized')
|
|
})
|
|
|
|
it('creates unauthorized error with custom message', () => {
|
|
const error = new UnauthorizedError('Invalid credentials')
|
|
expect(error.message).toBe('Invalid credentials')
|
|
})
|
|
})
|
|
|
|
describe('ForbiddenError', () => {
|
|
it('creates forbidden error', () => {
|
|
const error = new ForbiddenError()
|
|
expect(error.statusCode).toBe(403)
|
|
expect(error.code).toBe('FORBIDDEN')
|
|
})
|
|
})
|
|
|
|
describe('ConflictError', () => {
|
|
it('creates conflict error', () => {
|
|
const error = new ConflictError()
|
|
expect(error.statusCode).toBe(409)
|
|
expect(error.code).toBe('CONFLICT')
|
|
})
|
|
})
|
|
|
|
describe('formatErrorResponse', () => {
|
|
it('formats AppError correctly', () => {
|
|
const error = new ValidationError('Invalid input', { field: 'email' })
|
|
const response = formatErrorResponse(error)
|
|
expect(response).toEqual({
|
|
error: {
|
|
code: 'VALIDATION_ERROR',
|
|
message: 'Invalid input',
|
|
details: { field: 'email' },
|
|
},
|
|
})
|
|
})
|
|
|
|
it('formats generic Error correctly', () => {
|
|
const error = new Error('Generic error')
|
|
const response = formatErrorResponse(error)
|
|
expect(response).toEqual({
|
|
error: {
|
|
code: 'INTERNAL_ERROR',
|
|
message: 'Generic error',
|
|
},
|
|
})
|
|
})
|
|
|
|
it('handles error without message', () => {
|
|
const error = {}
|
|
const response = formatErrorResponse(error)
|
|
expect(response.error.message).toBe('Internal server error')
|
|
})
|
|
})
|
|
})
|