diff --git a/lib/adapters/REST/endpoints/entry.ts b/lib/adapters/REST/endpoints/entry.ts index 305af7eec8..f0386b53f7 100644 --- a/lib/adapters/REST/endpoints/entry.ts +++ b/lib/adapters/REST/endpoints/entry.ts @@ -13,6 +13,8 @@ import type { PatchEntryParams, PatchReleaseEntryParams, QueryParams, + UpdateEntryParams, + UpdateReleaseEntryParams, } from '../../../common-types' import type { CreateEntryProps, EntryProps, EntryReferenceProps } from '../../../entities/entry' import type { RestEndpoint } from '../types' @@ -105,10 +107,14 @@ export const patch: RestEndpoint<'Entry', 'patch'> = = ( http: AxiosInstance, - params: GetSpaceEnvironmentParams & { entryId: string }, + params: UpdateEntryParams & QueryParams, rawData: EntryProps, headers?: RawAxiosRequestHeaders ) => { + if (params.releaseId) { + return releaseEntry.update(http, params as UpdateReleaseEntryParams, rawData, headers ?? {}) + } + const data: SetOptional = copy(rawData) delete data.sys return raw.put>( diff --git a/lib/common-types.ts b/lib/common-types.ts index e95d53073b..9e0dbc4ab6 100644 --- a/lib/common-types.ts +++ b/lib/common-types.ts @@ -1618,7 +1618,7 @@ export type MRActions = { return: EntryProps } update: { - params: GetSpaceEnvironmentParams & { entryId: string } + params: UpdateEntryParams & QueryParams payload: EntryProps headers?: RawAxiosRequestHeaders return: EntryProps @@ -2396,6 +2396,7 @@ export type PatchEntryParams = GetSpaceEnvironmentParams & { version: number releaseId?: string } +export type UpdateEntryParams = GetSpaceEnvironmentParams & { entryId: string; releaseId?: string } export type GetExtensionParams = GetSpaceEnvironmentParams & { extensionId: string } export type GetEnvironmentTemplateParams = GetOrganizationParams & { environmentTemplateId: string } export type GetFunctionParams = GetAppDefinitionParams & { functionId: string } diff --git a/lib/plain/common-types.ts b/lib/plain/common-types.ts index 495764753a..ddb7e8a307 100644 --- a/lib/plain/common-types.ts +++ b/lib/plain/common-types.ts @@ -25,6 +25,7 @@ import type { PatchReleaseEntryParams, QueryParams, ReleaseEnvironmentParams, + UpdateEntryParams, UpdateReleaseEntryParams, } from '../common-types' import type { @@ -320,7 +321,7 @@ export type PlainClientAPI = { > > update( - params: OptionalDefaults, + params: OptionalDefaults, rawData: EntryProps, headers?: RawAxiosRequestHeaders ): Promise> diff --git a/test/integration/entry-integration.test.ts b/test/integration/entry-integration.test.ts index 80629f5e4a..01131e9a3c 100644 --- a/test/integration/entry-integration.test.ts +++ b/test/integration/entry-integration.test.ts @@ -823,6 +823,32 @@ describe('Entry Api', () => { expect(patchedEntry.sys.version).toBeGreaterThan(entryToPatch.sys.version) expect((patchedEntry as any).sys.release.sys.id).toEqual(entryToPatch.sys.release.sys.id) }) + + test('entry.update works', async () => { + const entryToUpdate = await createEntryClient.entry.get({ + entryId: entry.sys.id, + releaseId: release.sys.id, + }) + + const updatedEntry = await createEntryClient.entry.update( + { + entryId: entryToUpdate.sys.id, + releaseId: release.sys.id, + }, + { + ...entryToUpdate, + fields: { + ...entryToUpdate.fields, + title: { 'en-US': 'Entry updated via release' }, + }, + } + ) + + expect(updatedEntry.sys.id).toEqual(entryToUpdate.sys.id) + expect(updatedEntry.fields.title['en-US']).toEqual('Entry updated via release') + expect(updatedEntry.sys.version).toBeGreaterThan(entryToUpdate.sys.version) + expect((updatedEntry as any).sys.release.sys.id).toEqual(entryToUpdate.sys.release.sys.id) + }) }) describe('releaseId is provided in default params, but not in params', () => { @@ -878,6 +904,30 @@ describe('Entry Api', () => { expect(patchedEntry.sys.version).toBeGreaterThan(entryToPatch.sys.version) expect((patchedEntry as any).sys.release.sys.id).toEqual(entryToPatch.sys.release.sys.id) }) + + test('entry.update works', async () => { + const entryToUpdate = await createEntryClient.entry.get({ + entryId: entry.sys.id, + }) + + const updatedEntry = await createEntryClient.entry.update( + { + entryId: entryToUpdate.sys.id, + }, + { + ...entryToUpdate, + fields: { + ...entryToUpdate.fields, + title: { 'en-US': 'Entry updated via default release' }, + }, + } + ) + + expect(updatedEntry.sys.id).toEqual(entryToUpdate.sys.id) + expect(updatedEntry.fields.title['en-US']).toEqual('Entry updated via default release') + expect(updatedEntry.sys.version).toBeGreaterThan(entryToUpdate.sys.version) + expect((updatedEntry as any).sys.release.sys.id).toEqual(entryToUpdate.sys.release.sys.id) + }) }) }) diff --git a/test/unit/adapters/REST/endpoints/entry.test.ts b/test/unit/adapters/REST/endpoints/entry.test.ts index 87f5fd4e6d..cb22b8aa3c 100644 --- a/test/unit/adapters/REST/endpoints/entry.test.ts +++ b/test/unit/adapters/REST/endpoints/entry.test.ts @@ -276,4 +276,85 @@ describe('Rest Entry', () => { ) }) }) + + test('update without releaseId', async () => { + const { httpMock, adapterMock, entityMock } = setup(Promise.resolve({})) + + httpMock.put.mockReturnValue(Promise.resolve({ data: entityMock })) + + const updateData = { + ...entityMock, + fields: { + title: { 'en-US': 'Updated Title' }, + }, + } + + return adapterMock + .makeRequest({ + entityType: 'Entry', + action: 'update', + userAgent: 'mocked', + params: { + spaceId: 'space123', + environmentId: 'master', + entryId: 'entry123', + }, + payload: updateData, + }) + .then((r) => { + expect(r).to.eql(entityMock) + expect(httpMock.put.mock.calls[0][0]).to.eql( + '/spaces/space123/environments/master/entries/entry123' + ) + // Check that sys is removed from the payload + expect(httpMock.put.mock.calls[0][1]).not.toHaveProperty('sys') + expect(httpMock.put.mock.calls[0][1].fields.title['en-US']).to.eql('Updated Title') + expect(httpMock.put.mock.calls[0][2].headers['X-Contentful-Version']).to.eql( + updateData.sys.version + ) + }) + }) + + test('update with releaseId delegates to release entry', async () => { + const { httpMock, adapterMock, entityMock } = setup(Promise.resolve({})) + + // Mock the release entry endpoint + httpMock.put.mockReturnValue(Promise.resolve({ data: entityMock })) + + const updateData = { + ...entityMock, + fields: { + title: { 'en-US': 'Updated Title in Release' }, + }, + } + + return adapterMock + .makeRequest({ + entityType: 'Entry', + action: 'update', + userAgent: 'mocked', + params: { + spaceId: 'space123', + environmentId: 'master', + entryId: 'entry123', + releaseId: 'release456', + }, + payload: updateData, + }) + .then((r) => { + expect(r).to.eql(entityMock) + // When releaseId is provided, it should call the release entry endpoint + expect(httpMock.put.mock.calls[0][0]).to.eql( + '/spaces/space123/environments/master/releases/release456/entries/entry123' + ) + // Check that sys is removed from the payload + expect(httpMock.put.mock.calls[0][1]).not.toHaveProperty('sys') + expect(httpMock.put.mock.calls[0][1].fields.title['en-US']).to.eql( + 'Updated Title in Release' + ) + expect(httpMock.put.mock.calls[0][2].headers['X-Contentful-Version']).to.eql( + updateData.sys.version + ) + }) + }) })