fix(content-releases): Send the populate entry when publish (#19262)

* fix(content-releases): Send the populate entry when publish

* populating entries manually

* prettier aws-s3 readme

* apply marks feedback
This commit is contained in:
Fernando Chávez 2024-01-19 15:09:15 +01:00 committed by GitHub
parent c1061cabb3
commit 0d0b078513
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 92 additions and 18 deletions

View File

@ -238,16 +238,29 @@ describe('release service', () => {
const mockPublishMany = jest.fn();
const mockUnpublishMany = jest.fn();
const servicesMock = {
'entity-manager': {
publishMany: mockPublishMany,
unpublishMany: mockUnpublishMany,
},
'populate-builder': () => ({
default: jest.fn().mockReturnThis(),
populateDeep: jest.fn().mockReturnThis(),
build: jest.fn().mockReturnThis(),
}),
};
const strapiMock = {
...baseStrapiMock,
db: {
transaction: jest.fn().mockImplementation((cb) => cb()),
},
plugin: jest.fn().mockReturnValue({
service: jest.fn().mockReturnValue({
publishMany: mockPublishMany,
unpublishMany: mockUnpublishMany,
}),
service: jest
.fn()
.mockImplementation((service: 'entity-manager' | 'populate-builder') => {
return servicesMock[service];
}),
}),
entityService: {
findOne: jest.fn().mockReturnValue({
@ -265,6 +278,7 @@ describe('release service', () => {
},
],
}),
findMany: jest.fn(),
update: jest.fn().mockReturnValue({}),
},
};
@ -272,10 +286,31 @@ describe('release service', () => {
// @ts-expect-error Ignore missing properties
const releaseService = createReleaseService({ strapi: strapiMock });
strapiMock.entityService.findMany.mockReturnValueOnce([
{
contentType: 'contentType',
type: 'publish',
entry: { id: 1 },
},
]);
strapiMock.entityService.findMany.mockReturnValueOnce([
{
contentType: 'contentType',
type: 'unpublish',
entry: { id: 2 },
},
]);
await releaseService.publish(1);
expect(mockPublishMany).toHaveBeenCalledWith([{ id: 1 }], 'contentType');
expect(mockUnpublishMany).toHaveBeenCalledWith([{ id: 2 }], 'contentType');
expect(mockPublishMany).toHaveBeenCalledWith(
[{ contentType: 'contentType', entry: { id: 1 }, type: 'publish' }],
'contentType'
);
expect(mockUnpublishMany).toHaveBeenCalledWith(
[{ contentType: 'contentType', entry: { id: 2 }, type: 'unpublish' }],
'contentType'
);
});
});

View File

@ -420,7 +420,9 @@ const createReleaseService = ({ strapi }: { strapi: LoadedStrapi }) => ({
populate: {
actions: {
populate: {
entry: true,
entry: {
fields: ['id'],
},
},
},
},
@ -441,11 +443,12 @@ const createReleaseService = ({ strapi }: { strapi: LoadedStrapi }) => ({
/**
* We separate publish and unpublish actions group by content type
* And we keep only their ids to fetch them later to get all information needed
*/
const actions: {
[key: UID.ContentType]: {
publish: ReleaseAction['entry'][];
unpublish: ReleaseAction['entry'][];
entriestoPublishIds: ReleaseAction['entry']['id'][];
entriesToUnpublishIds: ReleaseAction['entry']['id'][];
};
} = {};
for (const action of releaseWithPopulatedActionEntries.actions) {
@ -453,31 +456,67 @@ const createReleaseService = ({ strapi }: { strapi: LoadedStrapi }) => ({
if (!actions[contentTypeUid]) {
actions[contentTypeUid] = {
publish: [],
unpublish: [],
entriestoPublishIds: [],
entriesToUnpublishIds: [],
};
}
if (action.type === 'publish') {
actions[contentTypeUid].publish.push(action.entry);
actions[contentTypeUid].entriestoPublishIds.push(action.entry.id);
} else {
actions[contentTypeUid].unpublish.push(action.entry);
actions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
}
}
const entityManagerService = strapi.plugin('content-manager').service('entity-manager');
const populateBuilderService = strapi.plugin('content-manager').service('populate-builder');
// Only publish the release if all action updates are applied successfully to their entry, otherwise leave everything as is
await strapi.db.transaction(async () => {
for (const contentTypeUid of Object.keys(actions)) {
const { publish, unpublish } = actions[contentTypeUid as UID.ContentType];
// @ts-expect-error - populateBuilderService should be a function but is returning service
const populate = await populateBuilderService(contentTypeUid)
.populateDeep(Infinity)
.build();
if (publish.length > 0) {
await entityManagerService.publishMany(publish, contentTypeUid);
const { entriestoPublishIds, entriesToUnpublishIds } =
actions[contentTypeUid as UID.ContentType];
/**
* We need to get the populate entries to be able to publish without errors on components/relations/dynamicZones
* Considering that populate doesn't work well with morph relations we can't get the entries from the Release model
* So, we need to fetch them manually
*/
const entriesToPublish = (await strapi.entityService.findMany(
contentTypeUid as UID.ContentType,
{
filters: {
id: {
$in: entriestoPublishIds,
},
},
populate,
}
)) as Entity[];
const entriesToUnpublish = (await strapi.entityService.findMany(
contentTypeUid as UID.ContentType,
{
filters: {
id: {
$in: entriesToUnpublishIds,
},
},
populate,
}
)) as Entity[];
if (entriesToPublish.length > 0) {
await entityManagerService.publishMany(entriesToPublish, contentTypeUid);
}
if (unpublish.length > 0) {
await entityManagerService.unpublishMany(unpublish, contentTypeUid);
if (entriesToUnpublish.length > 0) {
await entityManagerService.unpublishMany(entriesToUnpublish, contentTypeUid);
}
}
});