Skip to content

Commit 6edd93f

Browse files
peeeteeerPeter Rothlaender
andauthored
🗺️ feat: Add Parameter Location Mapping for OpenAPI actions (#6858)
* fix: action parameters are assigned to the correct location (query, parameter, header, body) * removed copy/paste error * added unit tests, only add contenttype if specified --------- Co-authored-by: Peter Rothlaender <[email protected]>
1 parent 16aa5ed commit 6edd93f

File tree

2 files changed

+311
-19
lines changed

2 files changed

+311
-19
lines changed

packages/data-provider/specs/actions.spec.ts

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,244 @@ describe('ActionRequest', () => {
206206
},
207207
});
208208
});
209+
210+
it('handles GET requests with header and query parameters', async () => {
211+
mockedAxios.get.mockResolvedValue({ data: { success: true } });
212+
213+
const data: Record<string, unknown> = {
214+
'api-version': '2025-01-01',
215+
'some-header': 'header-var',
216+
};
217+
218+
const loc: Record<string, 'query' | 'path' | 'header' | 'body'> = {
219+
'api-version': 'query',
220+
'some-header': 'header',
221+
};
222+
223+
const actionRequest = new ActionRequest(
224+
'https://example.com',
225+
'/get',
226+
'GET',
227+
'testGET',
228+
false,
229+
'',
230+
loc,
231+
);
232+
const executer = actionRequest.setParams(data);
233+
const response = await executer.execute();
234+
expect(mockedAxios.get).toHaveBeenCalled();
235+
236+
const [url, config] = mockedAxios.get.mock.calls[0];
237+
expect(url).toBe('https://example.com/get');
238+
expect(config?.headers).toEqual({
239+
'some-header': 'header-var',
240+
});
241+
expect(config?.params).toEqual({
242+
'api-version': '2025-01-01',
243+
});
244+
expect(response.data.success).toBe(true);
245+
});
246+
247+
it('handles GET requests with header and path parameters', async () => {
248+
mockedAxios.get.mockResolvedValue({ data: { success: true } });
249+
250+
const data: Record<string, unknown> = {
251+
'user-id': '1',
252+
'some-header': 'header-var',
253+
};
254+
255+
const loc: Record<string, 'query' | 'path' | 'header' | 'body'> = {
256+
'user-id': 'path',
257+
'some-header': 'header',
258+
};
259+
260+
const actionRequest = new ActionRequest(
261+
'https://example.com',
262+
'/getwithpath/{user-id}',
263+
'GET',
264+
'testGETwithpath',
265+
false,
266+
'',
267+
loc,
268+
);
269+
const executer = actionRequest.setParams(data);
270+
const response = await executer.execute();
271+
expect(mockedAxios.get).toHaveBeenCalled();
272+
273+
const [url, config] = mockedAxios.get.mock.calls[0];
274+
expect(url).toBe('https://example.com/getwithpath/1');
275+
expect(config?.headers).toEqual({
276+
'some-header': 'header-var',
277+
});
278+
expect(config?.params).toEqual({
279+
});
280+
expect(response.data.success).toBe(true);
281+
});
282+
283+
it('handles POST requests with body, header and query parameters', async () => {
284+
mockedAxios.post.mockResolvedValue({ data: { success: true } });
285+
286+
const data: Record<string, unknown> = {
287+
'api-version': '2025-01-01',
288+
'message': 'a body parameter',
289+
'some-header': 'header-var',
290+
};
291+
292+
const loc: Record<string, 'query' | 'path' | 'header' | 'body'> = {
293+
'api-version': 'query',
294+
'message': 'body',
295+
'some-header': 'header',
296+
};
297+
298+
const actionRequest = new ActionRequest(
299+
'https://example.com',
300+
'/post',
301+
'POST',
302+
'testPost',
303+
false,
304+
'application/json',
305+
loc,
306+
);
307+
const executer = actionRequest.setParams(data);
308+
const response = await executer.execute();
309+
expect(mockedAxios.post).toHaveBeenCalled();
310+
311+
const [url, body, config] = mockedAxios.post.mock.calls[0];
312+
expect(url).toBe('https://example.com/post');
313+
expect(body).toEqual({ message: 'a body parameter' });
314+
expect(config?.headers).toEqual({
315+
'some-header': 'header-var',
316+
'Content-Type': 'application/json',
317+
});
318+
expect(config?.params).toEqual({
319+
'api-version': '2025-01-01',
320+
});
321+
expect(response.data.success).toBe(true);
322+
});
323+
324+
it('handles PUT requests with body, header and query parameters', async () => {
325+
mockedAxios.put.mockResolvedValue({ data: { success: true } });
326+
327+
const data: Record<string, unknown> = {
328+
'api-version': '2025-01-01',
329+
'message': 'a body parameter',
330+
'some-header': 'header-var',
331+
};
332+
333+
const loc: Record<string, 'query' | 'path' | 'header' | 'body'> = {
334+
'api-version': 'query',
335+
'message': 'body',
336+
'some-header': 'header',
337+
};
338+
339+
const actionRequest = new ActionRequest(
340+
'https://example.com',
341+
'/put',
342+
'PUT',
343+
'testPut',
344+
false,
345+
'application/json',
346+
loc,
347+
);
348+
const executer = actionRequest.setParams(data);
349+
const response = await executer.execute();
350+
expect(mockedAxios.put).toHaveBeenCalled();
351+
352+
const [url, body, config] = mockedAxios.put.mock.calls[0];
353+
expect(url).toBe('https://example.com/put');
354+
expect(body).toEqual({ message: 'a body parameter' });
355+
expect(config?.headers).toEqual({
356+
'some-header': 'header-var',
357+
'Content-Type': 'application/json',
358+
});
359+
expect(config?.params).toEqual({
360+
'api-version': '2025-01-01',
361+
});
362+
expect(response.data.success).toBe(true);
363+
});
364+
365+
it('handles PATCH requests with body, header and query parameters', async () => {
366+
mockedAxios.patch.mockResolvedValue({ data: { success: true } });
367+
368+
const data: Record<string, unknown> = {
369+
'api-version': '2025-01-01',
370+
'message': 'a body parameter',
371+
'some-header': 'header-var',
372+
};
373+
374+
const loc: Record<string, 'query' | 'path' | 'header' | 'body'> = {
375+
'api-version': 'query',
376+
'message': 'body',
377+
'some-header': 'header',
378+
};
379+
380+
const actionRequest = new ActionRequest(
381+
'https://example.com',
382+
'/patch',
383+
'PATCH',
384+
'testPatch',
385+
false,
386+
'application/json',
387+
loc,
388+
);
389+
const executer = actionRequest.setParams(data);
390+
const response = await executer.execute();
391+
expect(mockedAxios.patch).toHaveBeenCalled();
392+
393+
const [url, body, config] = mockedAxios.patch.mock.calls[0];
394+
expect(url).toBe('https://example.com/patch');
395+
expect(body).toEqual({ message: 'a body parameter' });
396+
expect(config?.headers).toEqual({
397+
'some-header': 'header-var',
398+
'Content-Type': 'application/json',
399+
});
400+
expect(config?.params).toEqual({
401+
'api-version': '2025-01-01',
402+
});
403+
expect(response.data.success).toBe(true);
404+
});
405+
406+
it('handles DELETE requests with body, header and query parameters', async () => {
407+
mockedAxios.delete.mockResolvedValue({ data: { success: true } });
408+
409+
const data: Record<string, unknown> = {
410+
'api-version': '2025-01-01',
411+
'message-id': '1',
412+
'some-header': 'header-var',
413+
};
414+
415+
const loc: Record<string, 'query' | 'path' | 'header' | 'body'> = {
416+
'api-version': 'query',
417+
'message-id': 'body',
418+
'some-header': 'header',
419+
};
420+
421+
const actionRequest = new ActionRequest(
422+
'https://example.com',
423+
'/delete',
424+
'DELETE',
425+
'testDelete',
426+
false,
427+
'application/json',
428+
loc,
429+
);
430+
const executer = actionRequest.setParams(data);
431+
const response = await executer.execute();
432+
expect(mockedAxios.delete).toHaveBeenCalled();
433+
434+
const [url, config] = mockedAxios.delete.mock.calls[0];
435+
expect(url).toBe('https://example.com/delete');
436+
expect(config?.data).toEqual({ 'message-id': '1' });
437+
expect(config?.headers).toEqual({
438+
'some-header': 'header-var',
439+
'Content-Type': 'application/json',
440+
});
441+
expect(config?.params).toEqual({
442+
'api-version': '2025-01-01',
443+
});
444+
expect(response.data.success).toBe(true);
445+
});
446+
209447
});
210448

211449
it('throws an error for unsupported HTTP method', async () => {

0 commit comments

Comments
 (0)