From c66c972a93731d0d89cf49df4a7f698e3b5028a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20FAMIBELLE-PRONZOLA?= Date: Sat, 4 Jul 2026 11:37:20 +0400 Subject: [PATCH] =?UTF-8?q?fix:=20r=C3=A9parer=20la=20cascade=20de=20renom?= =?UTF-8?q?mage=20des=20slugs=20d'artiste?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../artiste/__tests__/lifecycles.test.js | 66 +++++++++++++++++++ .../content-types/artiste/lifecycles.js | 26 +++++--- 2 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 src/api/artiste/content-types/artiste/__tests__/lifecycles.test.js diff --git a/src/api/artiste/content-types/artiste/__tests__/lifecycles.test.js b/src/api/artiste/content-types/artiste/__tests__/lifecycles.test.js new file mode 100644 index 0000000..5984bed --- /dev/null +++ b/src/api/artiste/content-types/artiste/__tests__/lifecycles.test.js @@ -0,0 +1,66 @@ +import {describe, it, expect, vi, afterEach} from 'vitest' + +async function loadLifecycles(strapiMock) { + vi.resetModules() + global.strapi = strapiMock + const mod = await import('../lifecycles.js') + return mod +} + +describe('artiste afterUpdate — cascade de renommage des slugs', () => { + afterEach(() => { + delete global.strapi + }) + + it("renomme le slug des paroles de l'artiste quand son alias change", async () => { + const artisteFindOne = vi.fn(async () => ({ + id: 5, + paroles: [{id: 10}, {id: 11}] + })) + const paroleFindMany = vi.fn(async () => [ + {id: 10, titre: 'Titre 1', slug: 'ancien-alias-titre-1', artistes: [{alias: 'nouvel-alias'}]}, + {id: 11, titre: 'Titre 2', slug: 'nouvel-alias-titre-2', artistes: [{alias: 'nouvel-alias'}]} + ]) + const paroleUpdate = vi.fn(async () => {}) + + const strapiMock = { + db: { + query: vi.fn(uid => { + if (uid === 'api::artiste.artiste') return {findOne: artisteFindOne} + if (uid === 'api::parole.parole') return {findMany: paroleFindMany, update: paroleUpdate} + throw new Error(`unexpected uid: ${uid}`) + }) + } + } + + const {afterUpdate} = await loadLifecycles(strapiMock) + + await afterUpdate({result: {id: 5}}) + + expect(artisteFindOne).toHaveBeenCalledWith({where: {id: 5}, populate: ['paroles']}) + expect(paroleFindMany).toHaveBeenCalledWith({where: {id: {$in: [10, 11]}}, populate: ['artistes']}) + expect(paroleUpdate).toHaveBeenCalledTimes(1) + expect(paroleUpdate).toHaveBeenCalledWith({where: {id: 10}, data: {slug: 'nouvel-alias-titre-1'}}) + }) + + it("ne fait rien quand l'artiste n'a aucune parole", async () => { + const artisteFindOne = vi.fn(async () => ({id: 5, paroles: []})) + const paroleFindMany = vi.fn() + + const strapiMock = { + db: { + query: vi.fn(uid => { + if (uid === 'api::artiste.artiste') return {findOne: artisteFindOne} + if (uid === 'api::parole.parole') return {findMany: paroleFindMany} + throw new Error(`unexpected uid: ${uid}`) + }) + } + } + + const {afterUpdate} = await loadLifecycles(strapiMock) + + await afterUpdate({result: {id: 5}}) + + expect(paroleFindMany).not.toHaveBeenCalled() + }) +}) diff --git a/src/api/artiste/content-types/artiste/lifecycles.js b/src/api/artiste/content-types/artiste/lifecycles.js index e62905e..5afc926 100644 --- a/src/api/artiste/content-types/artiste/lifecycles.js +++ b/src/api/artiste/content-types/artiste/lifecycles.js @@ -3,13 +3,19 @@ const { ApplicationError } = require("@strapi/utils").errors const slugify = require('slugify') -const jwennTeksEpiId = async data => { - const paroles = await strapi.db.query('api::parole.parole').find({id_in: data}) +const jwennTeksEpiId = async ids => { + const paroles = await strapi.db.query('api::parole.parole').findMany({ + where: {id: {$in: ids}}, + populate: ['artistes'] + }) return paroles } const jwennAwtisEpiId = async id => { - const artiste = await strapi.db.query('api::artiste.artiste').findOne({id}) + const artiste = await strapi.db.query('api::artiste.artiste').findOne({ + where: {id}, + populate: ['paroles'] + }) return artiste } @@ -39,15 +45,15 @@ module.exports = { data.slug = slugify(data.alias, {lower: true, remove: /[*#+~.()'"!:@]/g}) }, afterUpdate: async event => { - let {data} = event.params - const {id} = data - const artiste = await jwennAwtisEpiId(id) + const {result} = event + const artiste = await jwennAwtisEpiId(result.id) if (artiste.paroles && artiste.paroles.length >= 1) { - const paroles = await jwennTeksEpiId(artiste.paroles) - Promise.all(paroles.map(async t => { - const {id, titre, slug, artiste} = t - const alias = artiste.map(a => a.alias).join('-') + const paroleIds = artiste.paroles.map(({id}) => id) + const paroles = await jwennTeksEpiId(paroleIds) + await Promise.all(paroles.map(async t => { + const {id, titre, slug, artistes} = t + const alias = artistes.map(a => a.alias).join('-') const slugUpdated = slugify(`${alias}-${titre}`, {lower: true, remove: /[*#+~.()'"!:@]/g}) if (slug !== slugUpdated) {