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:
devcodetools committed 2026-09-21 18:22:06 +02:00
1 parent 19a5a47b28
commit 1b8aac89f9
16 files changed
+369 -14

No files matched your search

+49
View File
@@ -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
View File
@@ -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)')
}
}
}