diff --git a/packages/core/content-releases/server/src/controllers/__tests__/release.test.ts b/packages/core/content-releases/server/src/controllers/__tests__/release.test.ts index 2c546068df..7a8447a76c 100644 --- a/packages/core/content-releases/server/src/controllers/__tests__/release.test.ts +++ b/packages/core/content-releases/server/src/controllers/__tests__/release.test.ts @@ -1,14 +1,16 @@ import releaseController from '../release'; const mockFindPage = jest.fn(); -const mockFindManyForContentTypeEntry = jest.fn(); +const mockFindManyWithContentTypeEntryAttached = jest.fn(); +const mockFindManyWithoutContentTypeEntryAttached = jest.fn(); const mockCountActions = jest.fn(); jest.mock('../../utils', () => ({ getService: jest.fn(() => ({ findOne: jest.fn(() => ({ id: 1 })), findPage: mockFindPage, - findManyForContentTypeEntry: mockFindManyForContentTypeEntry, + findManyWithContentTypeEntryAttached: mockFindManyWithContentTypeEntryAttached, + findManyWithoutContentTypeEntryAttached: mockFindManyWithoutContentTypeEntryAttached, countActions: mockCountActions, getContentTypesDataForActions: jest.fn(), })), @@ -19,7 +21,7 @@ describe('Release controller', () => { describe('findMany', () => { it('should call findPage', async () => { mockFindPage.mockResolvedValue({ results: [], pagination: {} }); - mockFindManyForContentTypeEntry.mockResolvedValue([]); + mockFindManyWithContentTypeEntryAttached.mockResolvedValue([]); const userAbility = { can: jest.fn(), }; @@ -53,9 +55,9 @@ describe('Release controller', () => { expect(mockFindPage).toHaveBeenCalled(); }); - it('should call findManyForContentTypeEntry', async () => { + it('should call findManyWithoutContentTypeEntryAttached', async () => { mockFindPage.mockResolvedValue({ results: [], pagination: {} }); - mockFindManyForContentTypeEntry.mockResolvedValue([]); + mockFindManyWithContentTypeEntryAttached.mockResolvedValue([]); const userAbility = { can: jest.fn(), }; @@ -86,7 +88,7 @@ describe('Release controller', () => { // @ts-expect-error partial context await releaseController.findMany(ctx); - expect(mockFindManyForContentTypeEntry).toHaveBeenCalled(); + expect(mockFindManyWithoutContentTypeEntryAttached).toHaveBeenCalled(); }); }); describe('create', () => { diff --git a/packages/core/content-releases/server/src/controllers/release.ts b/packages/core/content-releases/server/src/controllers/release.ts index 469e58cdfb..77e630faa0 100644 --- a/packages/core/content-releases/server/src/controllers/release.ts +++ b/packages/core/content-releases/server/src/controllers/release.ts @@ -40,9 +40,9 @@ const releaseController = { const hasEntryAttached: GetContentTypeEntryReleases.Request['query']['hasEntryAttached'] = typeof query.hasEntryAttached === 'string' ? JSON.parse(query.hasEntryAttached) : false; - const data = await releaseService.findManyForContentTypeEntry(contentTypeUid, entryId, { - hasEntryAttached, - }); + const data = hasEntryAttached + ? await releaseService.findManyWithContentTypeEntryAttached(contentTypeUid, entryId) + : await releaseService.findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId); ctx.body = { data }; } else { diff --git a/packages/core/content-releases/server/src/services/__tests__/release.test.ts b/packages/core/content-releases/server/src/services/__tests__/release.test.ts index 3fcf5ae0f9..31d15c2e9c 100644 --- a/packages/core/content-releases/server/src/services/__tests__/release.test.ts +++ b/packages/core/content-releases/server/src/services/__tests__/release.test.ts @@ -279,8 +279,8 @@ describe('release service', () => { }); }); - describe('findManyForContentTypeEntry', () => { - it('should format the return value correctly when hasEntryAttached is true', async () => { + describe('findManyWithContentTypeEntryAttached', () => { + it('should format the return value correctly', async () => { const strapiMock = { ...baseStrapiMock, db: { @@ -294,12 +294,9 @@ describe('release service', () => { // @ts-expect-error Ignore missing properties const releaseService = createReleaseService({ strapi: strapiMock }); - const releases = await releaseService.findManyForContentTypeEntry( + const releases = await releaseService.findManyWithContentTypeEntryAttached( 'api::contentType.contentType', - 1, - { - hasEntryAttached: true, - } + 1 ); expect(releases).toEqual([{ name: 'test release', action: { type: 'publish' } }]); diff --git a/packages/core/content-releases/server/src/services/release.ts b/packages/core/content-releases/server/src/services/release.ts index c26513b500..3683f247ea 100644 --- a/packages/core/content-releases/server/src/services/release.ts +++ b/packages/core/content-releases/server/src/services/release.ts @@ -79,60 +79,80 @@ const createReleaseService = ({ strapi }: { strapi: LoadedStrapi }) => ({ }); }, - async findManyForContentTypeEntry( + async findManyWithContentTypeEntryAttached( contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'], - entryId: GetContentTypeEntryReleases.Request['query']['entryId'], - { - hasEntryAttached, - }: { hasEntryAttached?: GetContentTypeEntryReleases.Request['query']['hasEntryAttached'] } = { - hasEntryAttached: false, - } + entryId: GetContentTypeEntryReleases.Request['query']['entryId'] ) { - const whereActions = hasEntryAttached - ? { - // Find all Releases where the content type entry is present - actions: { - target_type: contentTypeUid, - target_id: entryId, - }, - } - : { - // Find all Releases where the content type entry is not present - $or: [ - { - $not: { - actions: { - target_type: contentTypeUid, - target_id: entryId, - }, - }, - }, - { - actions: null, - }, - ], - }; - const populateAttachedAction = hasEntryAttached - ? { - // Filter the action to get only the content type entry - actions: { - where: { - target_type: contentTypeUid, - target_id: entryId, - }, - }, - } - : {}; - const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({ where: { - ...whereActions, + actions: { + target_type: contentTypeUid, + target_id: entryId, + }, releasedAt: { $null: true, }, }, populate: { - ...populateAttachedAction, + // Filter the action to get only the content type entry + actions: { + where: { + target_type: contentTypeUid, + target_id: entryId, + }, + }, + }, + }); + + return releases.map((release) => { + if (release.actions?.length) { + const [actionForEntry] = release.actions; + + // Remove the actions key to replace it with an action key + delete release.actions; + + return { + ...release, + action: actionForEntry, + }; + } + + return release; + }); + }, + + async findManyWithoutContentTypeEntryAttached( + contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'], + entryId: GetContentTypeEntryReleases.Request['query']['entryId'] + ) { + // We get the list of releases where the entry is present + const releasesRelated = await strapi.db.query(RELEASE_MODEL_UID).findMany({ + where: { + releasedAt: { + $null: true, + }, + actions: { + target_type: contentTypeUid, + target_id: entryId, + }, + }, + }); + + const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({ + where: { + $or: [ + { + id: { + $notIn: releasesRelated.map((release) => release.id), + }, + }, + { + actions: null, + }, + ], + releasedAt: { + $null: true, + }, }, });