Skip to content

Commit

Permalink
feat(operations): validate request params
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksandryackovlev committed Feb 20, 2020
1 parent dff5717 commit 391b38f
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
21 changes: 17 additions & 4 deletions src/operation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Ajv from 'ajv';
import { has, get, set } from 'lodash';

import faker from 'faker';
import { pathToRegexp } from 'path-to-regexp';
import { pathToRegexp, match } from 'path-to-regexp';

jsf.extend('faker', () => {
// faker.locale = locale;
Expand All @@ -24,7 +24,7 @@ jsf.define('examples', (value) => {
return '';
});

const ajv = new Ajv({ unknownFormats: ['int32', 'int64', 'binary'] });
const ajv = new Ajv({ coerceTypes: true, unknownFormats: ['int32', 'int64', 'binary'] });

function isReferenceObject(response: unknown): response is OpenAPIV3.ReferenceObject {
return typeof response === 'object' && response !== null && '$ref' in response;
Expand All @@ -37,6 +37,8 @@ class Operation {

operation: OpenAPIV3.OperationObject;

pathPattern: string;

securitySchemes: { [key: string]: OpenAPIV3.SecuritySchemeObject } | null;

constructor({
Expand All @@ -50,13 +52,13 @@ class Operation {
operation: OpenAPIV3.OperationObject;
securitySchemes?: { [key: string]: OpenAPIV3.SecuritySchemeObject };
}) {
const pathPattern = path.replace(/\{([^/}]+)\}/g, (p1: string, p2: string): string => `:${p2}`);
this.pathPattern = path.replace(/\{([^/}]+)\}/g, (p1: string, p2: string): string => `:${p2}`);

this.method = method.toUpperCase();
this.operation = operation;
this.securitySchemes = securitySchemes || null;

this.pathRegexp = pathToRegexp(pathPattern);
this.pathRegexp = pathToRegexp(this.pathPattern);
}

getResponseSchema(): JSONSchema | null {
Expand Down Expand Up @@ -214,6 +216,17 @@ class Operation {
}
}

const matchPath = match(this.pathPattern);
const matchObject = matchPath(req.path);

if ((matchObject && matchObject.params) || schemas.path) {
const isPathValid = ajv.validate(schemas.path, (matchObject && matchObject.params) || {});

if (!isPathValid) {
return false;
}
}

return true;
}

Expand Down
6 changes: 3 additions & 3 deletions test/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ describe('middleware', () => {
expect(response.status).toBe(400);
});

it.skip('should return an 400 error response if path params are not valid', async () => {
const response = await request.get('/api/pet/2');
it('should return an 400 error response if path params are not valid', async () => {
const response = await request.get('/api/pet/foo').set('api_key', 'someKey');

expect(response.status).toBe(200);
expect(response.status).toBe(400);
});

it('should return an 400 error response if query params are not valid', async () => {
Expand Down

0 comments on commit 391b38f

Please sign in to comment.