Skip to content

Commit 89e52b0

Browse files
feat: add Fragment publish and unpublish methods [DX-929] (#3002)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 0362ae1 commit 89e52b0

2 files changed

Lines changed: 89 additions & 0 deletions

File tree

lib/adapters/REST/endpoints/fragment.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,34 @@ export const del: RestEndpoint<'Fragment', 'delete'> = (
7272
) => {
7373
return raw.del(http, getBaseUrl(params) + `/${params.fragmentId}`)
7474
}
75+
76+
export const publish: RestEndpoint<'Fragment', 'publish'> = (
77+
http: AxiosInstance,
78+
params: GetFragmentParams & { version: number },
79+
headers?: RawAxiosRequestHeaders,
80+
) => {
81+
return raw.put<FragmentProps>(
82+
http,
83+
getBaseUrl(params) + `/${params.fragmentId}/published`,
84+
null,
85+
{
86+
headers: {
87+
'X-Contentful-Version': params.version,
88+
...headers,
89+
},
90+
},
91+
)
92+
}
93+
94+
export const unpublish: RestEndpoint<'Fragment', 'unpublish'> = (
95+
http: AxiosInstance,
96+
params: GetFragmentParams & { version: number },
97+
headers?: RawAxiosRequestHeaders,
98+
) => {
99+
return raw.del<FragmentProps>(http, getBaseUrl(params) + `/${params.fragmentId}/published`, {
100+
headers: {
101+
'X-Contentful-Version': params.version,
102+
...headers,
103+
},
104+
})
105+
}

test/unit/adapters/REST/endpoints/fragment.test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,62 @@ describe('Rest Fragment', { concurrent: true }, () => {
205205
)
206206
})
207207
})
208+
209+
test('publish calls correct URL with PUT and X-Contentful-Version header', async () => {
210+
const mockResponse = {
211+
sys: { id: 'fragment123', type: 'Fragment', version: 2, publishedVersion: 1 },
212+
name: 'Test Fragment',
213+
}
214+
215+
const { httpMock, adapterMock } = setupRestAdapter(Promise.resolve({ data: mockResponse }))
216+
217+
return adapterMock
218+
.makeRequest({
219+
entityType: 'Fragment',
220+
action: 'publish',
221+
userAgent: 'mocked',
222+
params: {
223+
spaceId: 'space123',
224+
environmentId: 'master',
225+
fragmentId: 'fragment123',
226+
version: 1,
227+
},
228+
})
229+
.then((r) => {
230+
expect(r).to.eql(mockResponse)
231+
expect(httpMock.put.mock.calls[0][0]).to.eql(
232+
'/spaces/space123/environments/master/fragments/fragment123/published',
233+
)
234+
expect(httpMock.put.mock.calls[0][2].headers['X-Contentful-Version']).to.eql(1)
235+
})
236+
})
237+
238+
test('unpublish calls correct URL with DELETE and X-Contentful-Version header', async () => {
239+
const mockResponse = {
240+
sys: { id: 'fragment123', type: 'Fragment', version: 3 },
241+
name: 'Test Fragment',
242+
}
243+
244+
const { httpMock, adapterMock } = setupRestAdapter(Promise.resolve({ data: mockResponse }))
245+
246+
return adapterMock
247+
.makeRequest({
248+
entityType: 'Fragment',
249+
action: 'unpublish',
250+
userAgent: 'mocked',
251+
params: {
252+
spaceId: 'space123',
253+
environmentId: 'master',
254+
fragmentId: 'fragment123',
255+
version: 2,
256+
},
257+
})
258+
.then((r) => {
259+
expect(r).to.eql(mockResponse)
260+
expect(httpMock.delete.mock.calls[0][0]).to.eql(
261+
'/spaces/space123/environments/master/fragments/fragment123/published',
262+
)
263+
expect(httpMock.delete.mock.calls[0][1].headers['X-Contentful-Version']).to.eql(2)
264+
})
265+
})
208266
})

0 commit comments

Comments
 (0)