From 3577fae4e41b16f6dda630f8a232d091484b56d0 Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Thu, 18 Aug 2022 17:19:18 +0200 Subject: [PATCH] get list of components to delete them afterwards --- .../lib/services/entity-service/components.js | 30 +++++++++++++++++++ .../lib/services/entity-service/index.js | 15 ++++++++-- .../tests/api/basic-dp-compo.test.e2e.js | 9 ++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/packages/core/strapi/lib/services/entity-service/components.js b/packages/core/strapi/lib/services/entity-service/components.js index 8b11ee31ca..2ff04d6e98 100644 --- a/packages/core/strapi/lib/services/entity-service/components.js +++ b/packages/core/strapi/lib/services/entity-service/components.js @@ -100,6 +100,34 @@ const createComponents = async (uid, data) => { return componentBody; }; +/** + * @param {str} uid + * @param {*} entity + * @return {Array<{uid: string, data: *}>} + */ +const getComponents = async (uid, entity) => { + const { attributes } = strapi.getModel(uid); + const components = []; + + for (const attributeName in attributes) { + const attribute = attributes[attributeName]; + + if (attribute.type === 'component' || attribute.type === 'dynamiczone') { + const value = await strapi.query(uid).load(entity, attributeName); + if (!value) continue; + + _.castArray(value).forEach((component) => { + components.push({ + uid: attribute.type === 'component' ? attribute.component : component.__component, + data: component, + }); + }); + } + } + + return components; +}; + /* delete old components create or update @@ -352,7 +380,9 @@ const deleteComponent = async (uid, componentToDelete) => { module.exports = { omitComponentData, + getComponents, createComponents, updateComponents, deleteComponents, + deleteComponent, }; diff --git a/packages/core/strapi/lib/services/entity-service/index.js b/packages/core/strapi/lib/services/entity-service/index.js index f5bdffdb68..5f116a7548 100644 --- a/packages/core/strapi/lib/services/entity-service/index.js +++ b/packages/core/strapi/lib/services/entity-service/index.js @@ -14,9 +14,10 @@ const uploadFiles = require('../utils/upload-files'); const { omitComponentData, + getComponents, createComponents, updateComponents, - deleteComponents, + deleteComponent, } = require('./components'); const { transformParamsToQuery, pickSelectionParams } = require('./params'); const { applyTransforms } = require('./attributes'); @@ -213,8 +214,10 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator }) return null; } + const componentsToDelete = await getComponents(uid, entityToDelete); + await db.query(uid).delete({ where: { id: entityToDelete.id } }); - await deleteComponents(uid, entityToDelete); + await Promise.all(componentsToDelete.map((compo) => deleteComponent(compo.uid, compo.data))); await this.emitEvent(uid, ENTRY_DELETE, entityToDelete); @@ -234,8 +237,14 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator }) return null; } + const componentsToDelete = await Promise.all( + entitiesToDelete.map((entityToDelete) => getComponents(uid, entityToDelete)) + ); + const deletedEntities = await db.query(uid).deleteMany(query); - await Promise.all(entitiesToDelete.map((entity) => deleteComponents(uid, entity))); + await Promise.all( + componentsToDelete.flat().map((compo) => deleteComponent(compo.uid, compo.data)) + ); // Trigger webhooks. One for each entity await Promise.all(entitiesToDelete.map((entity) => this.emitEvent(uid, ENTRY_DELETE, entity))); diff --git a/packages/core/strapi/tests/api/basic-dp-compo.test.e2e.js b/packages/core/strapi/tests/api/basic-dp-compo.test.e2e.js index f6238e1895..7a53b1ad8b 100644 --- a/packages/core/strapi/tests/api/basic-dp-compo.test.e2e.js +++ b/packages/core/strapi/tests/api/basic-dp-compo.test.e2e.js @@ -158,6 +158,15 @@ describe('Core API - Basic + compo + draftAndPublish', () => { data.productsWithCompoAndDP.shift(); }); + describe('database state', () => { + test('components have been removed from the database', async () => { + const dbComponents = await strapi.db + .query('default.compo') + .findMany({ name: 'compo name updated' }); + expect(dbComponents).toHaveLength(0); + }); + }); + describe('validation', () => { test('Cannot create product with compo - compo required', async () => { const product = {