import {describe, it, expect, vi} from 'vitest'; const {default: createController} = await import('../parole.js'); function buildStrapi({dbUser, artiste}) { const paroleDocuments = { findMany: vi.fn(async () => []), create: vi.fn(async ({data}) => ({id: 42, ...data})), update: vi.fn(async ({data}) => ({id: 42, ...data})) }; const userDocuments = { findOne: vi.fn(async () => dbUser), update: vi.fn(async () => {}) }; const artisteDocuments = { findOne: vi.fn(async () => artiste) }; const strapi = { contentType: vi.fn(() => ({uid: 'api::parole.parole', kind: 'collectionType'})), service: vi.fn(() => ({ validateParoles: vi.fn(), translateLyrics: vi.fn() })), documents: vi.fn(uid => { if (uid === 'plugin::users-permissions.user') return userDocuments; if (uid === 'api::artiste.artiste') return artisteDocuments; if (uid === 'api::parole.parole') return paroleDocuments; throw new Error(`unexpected uid: ${uid}`); }) }; return {strapi, paroleDocuments, userDocuments, artisteDocuments}; } function buildCtx(data) { return { request: { body: {data}, header: {authorization: 'Bearer faketoken'} }, badRequest: vi.fn(), notFound: vi.fn() }; } const dbUser = {id: 1, documentId: 'user-doc-1', username: 'foo', email: 'foo@bar.com'}; const artiste = {id: 9, documentId: 'artiste-doc-1'}; function buildData(overrides = {}) { return { titre: 'Test', transcription: 'Paroles...', user: {...dbUser}, artistes: [{documentId: 'artiste-doc-1'}], ...overrides }; } describe('parole.findOne', () => { it('interroge avec le documentId venant de ctx.params.id, pas avec ctx lui-même', async () => { const paroleDocuments = { findOne: vi.fn(async ({documentId}) => ({id: 1, documentId, titre: 'Test'})) }; const strapi = { contentType: vi.fn(() => ({uid: 'api::parole.parole', kind: 'collectionType'})), documents: vi.fn(uid => { if (uid === 'api::parole.parole') return paroleDocuments; throw new Error(`unexpected uid: ${uid}`); }) }; const controller = createController({strapi}); const ctx = {params: {id: 'doc-123'}}; const result = await controller.findOne(ctx); expect(paroleDocuments.findOne).toHaveBeenCalledWith({ documentId: 'doc-123', populate: ['artistes'] }); expect(result).toEqual({id: 1, documentId: 'doc-123', titre: 'Test'}); }); }); describe('parole.create', () => { it('crée la parole quand le user et l\'artiste existent', async () => { const {strapi, paroleDocuments} = buildStrapi({dbUser, artiste}); const controller = createController({strapi}); const ctx = buildCtx(buildData()); await controller.create(ctx); expect(paroleDocuments.create).toHaveBeenCalled(); }); it('refuse sans planter quand data.user est absent', async () => { const {strapi, userDocuments} = buildStrapi({dbUser, artiste}); const controller = createController({strapi}); const ctx = buildCtx(buildData({user: undefined})); await controller.create(ctx); expect(ctx.badRequest).toHaveBeenCalled(); expect(userDocuments.findOne).not.toHaveBeenCalled(); }); it('refuse sans planter quand data.artistes est vide', async () => { const {strapi, artisteDocuments} = buildStrapi({dbUser, artiste}); const controller = createController({strapi}); const ctx = buildCtx(buildData({artistes: []})); await controller.create(ctx); expect(ctx.badRequest).toHaveBeenCalled(); expect(artisteDocuments.findOne).not.toHaveBeenCalled(); }); it('ignore les champs non autorisés du payload (mass assignment)', async () => { const {strapi, paroleDocuments} = buildStrapi({dbUser, artiste}); const controller = createController({strapi}); const ctx = buildCtx(buildData({ userAdmin: {id: 999}, isNewRelease: true, difference: [{fake: true}] })); await controller.create(ctx); expect(paroleDocuments.create).toHaveBeenCalledWith({ data: { titre: 'Test', transcription: 'Paroles...', traductions: undefined, traductionAuto: undefined, artistes: [artiste.id], user: dbUser.id } }); }); }); describe('parole.update', () => { it('ignore les champs non autorisés du payload (mass assignment)', async () => { const {strapi, paroleDocuments} = buildStrapi({dbUser, artiste}); const controller = createController({strapi}); const ctx = buildCtx({ documentId: 'doc-1', titre: 'Nouveau titre', transcription: 'Nouveau texte', traductions: {francais: 'salut'}, traductionAuto: true, artistes: [9], userAdmin: {id: 999}, user: {id: 999} }); await controller.update(ctx); expect(paroleDocuments.update).toHaveBeenCalledWith({ documentId: 'doc-1', data: { titre: 'Nouveau titre', transcription: 'Nouveau texte', traductions: {francais: 'salut'}, traductionAuto: true, artistes: [9] } }); }); });