test(sujets): 8 tests route GET /sujets
This commit is contained in:
parent
cc72487013
commit
1a5b79807e
1 changed files with 165 additions and 0 deletions
165
src/routes/__tests__/sujets.test.ts
Normal file
165
src/routes/__tests__/sujets.test.ts
Normal 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')
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
Add table
Add a link
Reference in a new issue