Skip to content

Commit

Permalink
feat: throw RequestValidationError on invalid JSON in query parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
tommorgenstern committed Oct 29, 2023
1 parent 09623c0 commit 703af41
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 4 deletions.
12 changes: 9 additions & 3 deletions src/middleware/native/oas-params.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import _ from "lodash";
import { schema } from "../../utils/index.js";
import { OASBase, logger } from "@oas-tools/commons";
import { schema, commons } from "../../utils/index.js";
import { OASBase, logger, errors } from "@oas-tools/commons";

const { RequestValidationError } = errors;

export class OASParams extends OASBase {

Expand Down Expand Up @@ -126,7 +128,11 @@ function _parseValue(val, paramDefinition, schema, type) {
if (paramDefinition.content) {
const contentType = Object.keys(paramDefinition.content)[0];
if (contentType.toLocaleLowerCase() === "application/json") {
return JSON.parse(val);
try {
return JSON.parse(val);
} catch {
commons.handle(RequestValidationError, `Invalid JSON in parameter '${paramDefinition.name}'.`, true);
}
} else {
logger.warn(`Content type ${contentType} is not supported. Raw value will be returned.`);
return val
Expand Down
28 changes: 27 additions & 1 deletion tests/suites/params.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import {init, close} from '../testServer/index.js';
import fs from 'fs';
import assert from 'assert';
import axios from 'axios';

export default () => {
let cfg;

describe('\n OAS-Params Middleware tests', () => {

before(async () => {
await init(); //init server with default config
cfg = JSON.parse(fs.readFileSync('tests/testServer/.oastoolsrc'));
cfg.logger.level = 'off'; // Set to 'error' if any test fail to see the error message
await init(cfg); //init server with default config
});

it('Should parse path params correctly (explode false)', async () => {
Expand Down Expand Up @@ -71,6 +75,28 @@ export default () => {
});
});

it('Should parse query params correctly (content application/json)', async () => {
await axios.get('http://localhost:8080/api/v1/oasParams/json?queryparamjson={"key":"value","otherkey":"othervalue"}')
.then(res => {
let expected = {
params: {
queryparamjson: {key: 'value', otherkey: 'othervalue'}
},
body: {}
}
assert.deepStrictEqual(res.data, expected);
});
});

it('Should fail when JSON query params are not valid JSON', async () => {
await axios.get('http://localhost:8080/api/v1/oasParams/json?queryparamjson={"key":,"otherkey":"othervalue"}')
.then(() => assert.fail('Got unexpected response, expected 400'))
.catch(err => {
assert.match(err.response?.data?.error, /.*Invalid JSON in parameter '.*'*/);
assert.equal(err.response.status, 400);
})
});

it('Should parse header params correctly (explode false)', async () => {
await axios.get('http://localhost:8080/api/v1/oasParams', { headers: { headerparam: '2022-06-19T00:00:00.000Z' } })
.then(res => {
Expand Down
8 changes: 8 additions & 0 deletions tests/testServer/api/3.0.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ paths:
- $ref: 'subschemas/oasparams.yaml#/explode/cookieparams/0'
responses:
'200': {$ref: 'subschemas/responses.yaml#/200'}
/api/v1/oasParams/json:
x-router-controller: oasParamsTestController
get:
operationId: getRequest
parameters:
- $ref: 'subschemas/oasparams.yaml#/json/queryparams/0'
responses:
'200': {$ref: 'subschemas/responses.yaml#/200'}
/api/v1/oasParams/{testparamsimple}/{testparamslabel}/{testparamsmatrix}:
x-router-controller: oasParamsTestController
get:
Expand Down
15 changes: 15 additions & 0 deletions tests/testServer/api/subschemas/oasparams.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,21 @@ explode:
schema:
type: array

json:
queryparams:
- name: queryparamjson
description: query parameter content application/json
in: query
content:
application/json:
schema:
type: object
properties:
key:
type: string
otherkey:
type: string

body:
schemaWithDefaults:
type: array
Expand Down
8 changes: 8 additions & 0 deletions tests/testServer/controllers/oasParamsTestController.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ export function getRequestExplode(req, res, next) {
service.getRequest(req.params, res, next);
}

/**
* @oastools {method} GET
* @oastools {path} /json
*/
export function getRequestJson(req, res, next) {
service.getRequest(req.params, res, next);
}

/**
* @oastools {method} GET
* @oastools {path} /explode/{testparamsimple}/{testparamslabel}/{testparamsmatrix}
Expand Down

0 comments on commit 703af41

Please sign in to comment.