test(sujets): 8 tests route GET /sujets

This commit is contained in:
Hermann_Kitio 2026-04-21 01:03:49 +03:00
parent cc72487013
commit 1a5b79807e

View file

@ -0,0 +1,165 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { Hono } from 'hono'
// ─── Mocks ───────────────────────────────────────────────────────────────────
vi.mock('../../lib/supabase', () => ({
supabase: {
from: vi.fn(),
},
}))
vi.mock('../../middleware/auth', () => ({
authMiddleware: async (c: any, next: any) => {
const authHeader = c.req.header('Authorization')
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return c.json({ error: true, code: 'AUTH_REQUIRED' }, 401)
}
c.set('user', { id: 'test-user-id', email: 'u@test.com' })
c.set('profile', {
id: 'test-user-id',
email: 'u@test.com',
plan: 'free',
simulations_used: 0,
stripe_customer_id: null,
stripe_subscription_id: null,
plan_expires_at: null,
created_at: '2026-01-01',
updated_at: '2026-01-01',
})
await next()
},
}))
import { supabase } from '../../lib/supabase'
import sujetsRoutes from '../sujets'
function buildApp() {
const app = new Hono()
app.route('/sujets', sujetsRoutes)
return app
}
/** Mock from('sujets').select().eq('mode').eq('tache').eq('actif').order() */
function mockSujetsQuery(rows: unknown[] | null, error: unknown = null) {
vi.mocked(supabase.from).mockReturnValueOnce({
select: vi.fn(() => ({
eq: vi.fn(() => ({
eq: vi.fn(() => ({
eq: vi.fn(() => ({
order: vi.fn(() => ({ data: rows, error })),
})),
})),
})),
})),
} as any)
}
const AUTH_HEADERS = { Authorization: 'Bearer valid-token' }
describe('GET /sujets', () => {
beforeEach(() => {
vi.mocked(supabase.from).mockReset()
})
it('retourne 401 sans authentification', async () => {
const app = buildApp()
const res = await app.request('/sujets?mode=EE&tache=1')
expect(res.status).toBe(401)
const body = await res.json()
expect(body.code).toBe('AUTH_REQUIRED')
})
it('retourne 400 VALIDATION_ERROR si mode invalide', async () => {
const app = buildApp()
const res = await app.request('/sujets?mode=XX&tache=1', { headers: AUTH_HEADERS })
expect(res.status).toBe(400)
const body = await res.json()
expect(body.code).toBe('VALIDATION_ERROR')
})
it('retourne 400 VALIDATION_ERROR si mode manquant', async () => {
const app = buildApp()
const res = await app.request('/sujets?tache=1', { headers: AUTH_HEADERS })
expect(res.status).toBe(400)
const body = await res.json()
expect(body.code).toBe('VALIDATION_ERROR')
})
it('retourne 400 VALIDATION_ERROR si tache invalide', async () => {
const app = buildApp()
const res = await app.request('/sujets?mode=EE&tache=9', { headers: AUTH_HEADERS })
expect(res.status).toBe(400)
const body = await res.json()
expect(body.code).toBe('VALIDATION_ERROR')
})
it('retourne 400 VALIDATION_ERROR si tache non numérique', async () => {
const app = buildApp()
const res = await app.request('/sujets?mode=EE&tache=abc', { headers: AUTH_HEADERS })
expect(res.status).toBe(400)
const body = await res.json()
expect(body.code).toBe('VALIDATION_ERROR')
})
it('retourne la liste des sujets actifs pour (mode, tache) valides', async () => {
const rows = [
{
id: 'sujet-1',
consigne: 'Écrivez un texte.',
role: null,
contexte: null,
doc1_titre: null,
doc1_texte: null,
doc2_titre: null,
doc2_texte: null,
},
{
id: 'sujet-2',
consigne: 'Autre consigne.',
role: 'journaliste',
contexte: 'magazine',
doc1_titre: null,
doc1_texte: null,
doc2_titre: null,
doc2_texte: null,
},
]
mockSujetsQuery(rows)
const app = buildApp()
const res = await app.request('/sujets?mode=EE&tache=1', { headers: AUTH_HEADERS })
expect(res.status).toBe(200)
const body = await res.json()
expect(body).toEqual({ sujets: rows })
expect(vi.mocked(supabase.from).mock.calls[0][0]).toBe('sujets')
})
it('retourne un tableau vide si aucun sujet actif', async () => {
mockSujetsQuery([])
const app = buildApp()
const res = await app.request('/sujets?mode=EO&tache=3', { headers: AUTH_HEADERS })
expect(res.status).toBe(200)
const body = await res.json()
expect(body).toEqual({ sujets: [] })
})
it('retourne 500 INTERNAL_ERROR si Supabase échoue', async () => {
mockSujetsQuery(null, { message: 'connection refused' })
const app = buildApp()
const res = await app.request('/sujets?mode=EE&tache=2', { headers: AUTH_HEADERS })
expect(res.status).toBe(500)
const body = await res.json()
expect(body.code).toBe('INTERNAL_ERROR')
})
})