import {describe, it, expect, vi} from 'vitest'; const {default: createController} = await import('../commentaire.js'); const dbUser = {id: 1, username: 'foo', email: 'foo@bar.com'}; const dbParole = {id: 7, documentId: 'parole-doc-7'}; function buildStrapi({existingParole = dbParole} = {}) { const commentaireDocuments = { create: vi.fn(async ({data}) => ({id: 99, ...data})) }; const paroleDocuments = { update: vi.fn(async () => {}) }; const userDbQuery = { findOne: vi.fn(async ({where}) => (where.id === dbUser.id ? dbUser : null)) }; const paroleDbQuery = { findOne: vi.fn(async ({where}) => (where.id === existingParole?.id ? existingParole : null)) }; const strapi = { contentType: vi.fn(() => ({uid: 'api::commentaire.commentaire', kind: 'collectionType'})), db: { query: vi.fn(uid => { if (uid === 'plugin::users-permissions.user') return userDbQuery; if (uid === 'api::parole.parole') return paroleDbQuery; throw new Error(`unexpected uid: ${uid}`); }) }, documents: vi.fn(uid => { if (uid === 'api::commentaire.commentaire') return commentaireDocuments; if (uid === 'api::parole.parole') return paroleDocuments; throw new Error(`unexpected uid: ${uid}`); }) }; return {strapi, commentaireDocuments, paroleDocuments, userDbQuery, paroleDbQuery}; } function buildCtx(data) { return { request: { body: {data}, header: {authorization: 'Bearer faketoken'} } }; } function buildData(overrides = {}) { return { contenu: 'Un commentaire', datePublication: '2026-07-04', parole: dbParole.id, user: {...dbUser}, ...overrides }; } describe('commentaire.create', () => { it('retrouve la parole par son id (pas par le documentId du user) et l\'associe correctement', async () => { const {strapi, commentaireDocuments, paroleDocuments, paroleDbQuery} = buildStrapi(); const controller = createController({strapi}); const ctx = buildCtx(buildData()); await controller.create(ctx); expect(paroleDbQuery.findOne).toHaveBeenCalledWith({where: {id: dbParole.id}}); expect(commentaireDocuments.create).toHaveBeenCalled(); expect(paroleDocuments.update).toHaveBeenCalledWith({ documentId: dbParole.documentId, data: {commentaires: {connect: [99]}} }); }); it('rejette quand la parole ciblée n\'existe pas', async () => { const {strapi, commentaireDocuments} = buildStrapi({existingParole: null}); const controller = createController({strapi}); const ctx = buildCtx(buildData()); await expect(controller.create(ctx)).rejects.toThrow('Texte introuvable.'); expect(commentaireDocuments.create).not.toHaveBeenCalled(); }); it('refuse sans planter quand data.user est absent', async () => { const {strapi, userDbQuery} = buildStrapi(); const controller = createController({strapi}); const ctx = buildCtx(buildData({user: undefined})); await expect(controller.create(ctx)).rejects.toThrow('Informations manquantes.'); expect(userDbQuery.findOne).not.toHaveBeenCalled(); }); it('refuse sans planter quand data.parole est absent', async () => { const {strapi, paroleDbQuery} = buildStrapi(); const controller = createController({strapi}); const ctx = buildCtx(buildData({parole: undefined})); await expect(controller.create(ctx)).rejects.toThrow('Informations manquantes.'); expect(paroleDbQuery.findOne).not.toHaveBeenCalled(); }); it('ignore les champs non autorisés du payload (mass assignment)', async () => { const {strapi, commentaireDocuments} = buildStrapi(); const controller = createController({strapi}); const ctx = buildCtx(buildData({publishedAt: '2020-01-01'})); await controller.create(ctx); expect(commentaireDocuments.create).toHaveBeenCalledWith({ data: { contenu: 'Un commentaire', datePublication: '2026-07-04', user: dbUser.id, parole: dbParole.id } }); }); });