test(api): couvrir les routes CRUD, random, thèmes et les helpers HTTP
Ajoute les tests des routes /api/cards, /api/cards/[id], /api/cards/random et /api/cards/themes, ainsi que les tests des helpers http (handleError, parseJsonBody) et de la factory getCardService. Corrige le formatage des fichiers sources embarqués non formatés par les commits précédents.
This commit is contained in:
1 parent
19a5a47b28
commit
1b8aac89f9
16 files changed
+369
-14
No files matched your search
@@ -0,0 +1,49 @@
|
||||
// @vitest-environment node
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { NextRequest } from 'next/server'
|
||||
import { ZodError } from 'zod'
|
||||
import { NotFoundError, ValidationError } from '@/domain/errors'
|
||||
import { handleError, parseJsonBody } from './http'
|
||||
|
||||
describe('handleError', () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
})
|
||||
|
||||
it('renvoie 400 pour une erreur de validation zod', () => {
|
||||
const res = handleError(new ZodError([]))
|
||||
expect(res.status).toBe(400)
|
||||
})
|
||||
|
||||
it('renvoie le statut de l erreur applicative (404)', () => {
|
||||
const res = handleError(new NotFoundError('Carte x introuvable'))
|
||||
expect(res.status).toBe(404)
|
||||
})
|
||||
|
||||
it('renvoie 400 pour ValidationError', () => {
|
||||
const res = handleError(new ValidationError('Payload invalide'))
|
||||
expect(res.status).toBe(400)
|
||||
})
|
||||
|
||||
it('renvoie 500 pour une erreur inattendue', async () => {
|
||||
const res = handleError(new Error('boom'))
|
||||
expect(res.status).toBe(500)
|
||||
expect(await res.json()).toHaveProperty('error', 'InternalServerError')
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseJsonBody', () => {
|
||||
it('renvoie le corps JSON parsé', async () => {
|
||||
const request = new NextRequest('http://localhost/api/cards', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ question: 'Q' }),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
await expect(parseJsonBody(request)).resolves.toEqual({ question: 'Q' })
|
||||
})
|
||||
|
||||
it('lève ValidationError si le corps n est pas du JSON', async () => {
|
||||
const request = new NextRequest('http://localhost/api/cards', { method: 'POST', body: '{bad' })
|
||||
await expect(parseJsonBody(request)).rejects.toThrow(ValidationError)
|
||||
})
|
||||
})
|
||||
+9
-3
@@ -10,10 +10,16 @@ export function handleError(error: unknown): NextResponse {
|
||||
)
|
||||
}
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json({ error: error.name, message: error.message }, { status: error.status })
|
||||
return NextResponse.json(
|
||||
{ error: error.name, message: error.message },
|
||||
{ status: error.status },
|
||||
)
|
||||
}
|
||||
console.error(error)
|
||||
return NextResponse.json({ error: 'InternalServerError', message: 'Erreur interne' }, { status: 500 })
|
||||
return NextResponse.json(
|
||||
{ error: 'InternalServerError', message: 'Erreur interne' },
|
||||
{ status: 500 },
|
||||
)
|
||||
}
|
||||
|
||||
export async function parseJsonBody(request: NextRequest): Promise<unknown> {
|
||||
@@ -22,4 +28,4 @@ export async function parseJsonBody(request: NextRequest): Promise<unknown> {
|
||||
} catch {
|
||||
throw new ValidationError('Corps de requête invalide (JSON attendu)')
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user