Files
kestrelos/test/unit/errors.spec.js
Madison Grubb b0e8dd7ad9
Some checks failed
ci/woodpecker/pr/pr Pipeline failed
make kestrel a tak server, so that it can send and receive pois as cots data
2026-02-17 10:42:53 -05:00

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')
})
})
})