From 267ba8fc10d39640da1f1b807ebee33e9c7daf0e Mon Sep 17 00:00:00 2001 From: Oliwia Rogala Date: Fri, 10 May 2024 11:43:17 +0200 Subject: [PATCH] fix(execute): fix multiple path parameters templating Refs #3508 --- src/execute/index.js | 6 ++- src/execute/oas3/parameter-builders.js | 9 +++-- src/execute/swagger2/parameter-builders.js | 7 ++-- test/execute/main.js | 47 ++++++++++++++++++++++ 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/execute/index.js b/src/execute/index.js index c69020beb..38d4836f6 100755 --- a/src/execute/index.js +++ b/src/execute/index.js @@ -172,7 +172,7 @@ export function buildRequest(options) { const { operation = {}, method, pathName } = operationRaw; - req.url += baseUrl({ + const baseURL = baseUrl({ spec, scheme, contextUrl, @@ -182,6 +182,8 @@ export function buildRequest(options) { method, }); + req.url += baseURL; + // Mostly for testing if (!operationId) { // Not removing req.cookies causes testing issues and would @@ -266,7 +268,7 @@ export function buildRequest(options) { value, operation, spec, - pathName, + baseURL, }); } }); diff --git a/src/execute/oas3/parameter-builders.js b/src/execute/oas3/parameter-builders.js index 0e5e7e8db..b62e6890f 100644 --- a/src/execute/oas3/parameter-builders.js +++ b/src/execute/oas3/parameter-builders.js @@ -3,24 +3,25 @@ import { resolve as resolvePathTemplate } from 'openapi-path-templating'; import stylize, { encodeCharacters } from './style-serializer.js'; import serialize from './content-serializer.js'; -export function path({ req, value, parameter, pathName }) { +export function path({ req, value, parameter, baseURL }) { const { name, style, explode, content } = parameter; if (value === undefined) return; + const pathname = req.url.replace(baseURL, ''); let resolvedPathname; if (content) { const effectiveMediaType = Object.keys(content)[0]; resolvedPathname = resolvePathTemplate( - pathName, + pathname, { [name]: value }, { encoder: (val) => encodeCharacters(serialize(val, effectiveMediaType)) } ); } else { resolvedPathname = resolvePathTemplate( - pathName, + pathname, { [name]: value }, { encoder: (val) => @@ -35,7 +36,7 @@ export function path({ req, value, parameter, pathName }) { ); } - req.url = req.url.replace(pathName, resolvedPathname); + req.url = baseURL + resolvedPathname; } export function query({ req, value, parameter }) { diff --git a/src/execute/swagger2/parameter-builders.js b/src/execute/swagger2/parameter-builders.js index 125c4d7fe..8e8be5823 100644 --- a/src/execute/swagger2/parameter-builders.js +++ b/src/execute/swagger2/parameter-builders.js @@ -51,11 +51,12 @@ function headerBuilder({ req, parameter, value }) { } // Replace path paramters, with values ( ie: the URL ) -function pathBuilder({ req, value, parameter, pathName }) { +function pathBuilder({ req, value, parameter, baseURL }) { if (value !== undefined) { - const resolvedPathname = resolvePathTemplate(pathName, { [parameter.name]: value }); + const pathname = req.url.replace(baseURL, ''); + const resolvedPathname = resolvePathTemplate(pathname, { [parameter.name]: value }); - req.url = req.url.replace(pathName, resolvedPathname); + req.url = baseURL + resolvedPathname; } } diff --git a/test/execute/main.js b/test/execute/main.js index 20d95ad13..d3e6eb0d3 100644 --- a/test/execute/main.js +++ b/test/execute/main.js @@ -1982,6 +1982,53 @@ describe('execute', () => { }); }); + test('should replace all path parameters with their values', () => { + const spec = { + host: 'swagger.io', + basePath: '/v1', + paths: { + '/{id}/orders/{order}/{itemId}': { + get: { + operationId: 'getMe', + parameters: [ + { + in: 'path', + name: 'id', + type: 'number', + required: true, + }, + { + in: 'path', + name: 'order', + type: 'number', + required: true, + }, + { + in: 'path', + name: 'itemId', + type: 'number', + required: true, + }, + ], + }, + }, + }, + }; + + const req = buildRequest({ + spec, + operationId: 'getMe', + parameters: { id: '123', order: '456', itemId: '789' }, + }); + + expect(req).toEqual({ + url: 'http://swagger.io/v1/123/orders/456/789', + method: 'GET', + credentials: 'same-origin', + headers: {}, + }); + }); + test('should not replace path parameters with undefined values', () => { const spec = { host: 'swagger.io',