From db7b82309e3f60d8225b027de48937eeac320035 Mon Sep 17 00:00:00 2001 From: Daneryl Date: Thu, 2 Feb 2023 11:17:28 +0100 Subject: [PATCH] pass coerceTypes through --- src/middlewares/openapi.request.validator.ts | 8 +++- test/coercion.spec.ts | 40 ++++++++++++++++---- test/resources/coercion.yaml | 24 ++++++++++++ 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/middlewares/openapi.request.validator.ts b/src/middlewares/openapi.request.validator.ts index de56edba..45b11ea5 100644 --- a/src/middlewares/openapi.request.validator.ts +++ b/src/middlewares/openapi.request.validator.ts @@ -44,7 +44,11 @@ export class RequestValidator { this.apiDoc = apiDoc; this.requestOpts.allowUnknownQueryParameters = options.allowUnknownQueryParameters; - this.ajv = createRequestAjv(apiDoc, { ...options, coerceTypes: true }); + + this.ajv = createRequestAjv( + apiDoc, + !options.coerceTypes ? { ...options, coerceTypes: true } : options, + ); this.ajvBody = createRequestAjv(apiDoc, options); } @@ -212,7 +216,7 @@ export class RequestValidator { // NOOP } } - }) + }); return null; } diff --git a/test/coercion.spec.ts b/test/coercion.spec.ts index 053ac6fc..7dda3a06 100644 --- a/test/coercion.spec.ts +++ b/test/coercion.spec.ts @@ -7,23 +7,34 @@ import * as packageJson from '../package.json'; describe(packageJson.name, () => { let app = null; + let arrayCoercedApp = null; before(async () => { // Set up the express app const apiSpec = path.join('test', 'resources', 'coercion.yaml'); + const routes = express + .Router() + .post(`/pets`, (req, res) => res.json(req.body)) + .post(`/pets_string_boolean`, (req, res) => res.json(req.body)) + .get(`/pets_as_array_parameter`, (req, res) => res.json(req.query)); + app = await createApp({ apiSpec }, 3005, (app) => - app.use( - `${app.basePath}/coercion`, - express - .Router() - .post(`/pets`, (req, res) => res.json(req.body)) - .post(`/pets_string_boolean`, (req, res) => res.json(req.body)), - ), + app.use(`${app.basePath}/coercion`, routes), + ); + arrayCoercedApp = await createApp( + { apiSpec, validateRequests: { coerceTypes: 'array' } }, + 3006, + (appWithCoerceTypes) => + appWithCoerceTypes.use( + `${appWithCoerceTypes.basePath}/coercion`, + routes, + ), ); }); after(() => { app.server.close(); + arrayCoercedApp.server.close(); }); it('should return 400 since is_cat is passed as string not boolean', async () => @@ -35,7 +46,9 @@ describe(packageJson.name, () => { }) .expect(400) .then((r) => { - expect(r.body.message).to.contain('request/body/is_cat must be boolean'); + expect(r.body.message).to.contain( + 'request/body/is_cat must be boolean', + ); })); it('should return 400 when age is passed as string, but number is expected', async () => @@ -102,4 +115,15 @@ describe(packageJson.name, () => { .then((r) => { expect(r.body.message).to.contain('request/body/is_cat must be string'); })); + + it('should return 200 when names is a string and coerce names to be an array', async () => + request(arrayCoercedApp) + .get(`${arrayCoercedApp.basePath}/coercion/pets_as_array_parameter`) + .query({ + filter: { names: 'test' }, + }) + .expect(200) + .then((r) => { + expect(r.text).to.equal('{"filter":{"names":["test"]}}'); + })); }); diff --git a/test/resources/coercion.yaml b/test/resources/coercion.yaml index 66b1ae00..5e9344f4 100644 --- a/test/resources/coercion.yaml +++ b/test/resources/coercion.yaml @@ -46,6 +46,30 @@ paths: schema: $ref: '#/components/schemas/PetStringBoolean' + /coercion/pets_as_array_parameter: + get: + description: Returns pets by name + operationId: addPet + parameters: + - in: query + name: filter + schema: + type: object + additionalProperties: false + properties: + names: + type: array + items: + type: string + responses: + '200': + description: pet response + content: + application/json: + schema: + type: array + items: { $ref: '#/components/schemas/Pet' } + components: schemas: Pet: