Skip to content

Commit

Permalink
fix(execute): resolve multiple path parameters with the same name in …
Browse files Browse the repository at this point in the history
…path templates (#3511)

Refs #3508
  • Loading branch information
glowcloud committed May 10, 2024
1 parent 7be6636 commit f1464a2
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 9 deletions.
6 changes: 4 additions & 2 deletions src/execute/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export function buildRequest(options) {

const { operation = {}, method, pathName } = operationRaw;

req.url += baseUrl({
const baseURL = baseUrl({
spec,
scheme,
contextUrl,
Expand All @@ -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
Expand Down Expand Up @@ -266,7 +268,7 @@ export function buildRequest(options) {
value,
operation,
spec,
pathName,
baseURL,
});
}
});
Expand Down
9 changes: 5 additions & 4 deletions src/execute/oas3/parameter-builders.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand All @@ -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 }) {
Expand Down
7 changes: 4 additions & 3 deletions src/execute/swagger2/parameter-builders.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
47 changes: 47 additions & 0 deletions test/execute/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down

0 comments on commit f1464a2

Please sign in to comment.