From c044f28501cee11a79d119302feb41f2389c0631 Mon Sep 17 00:00:00 2001 From: sigals Date: Sat, 20 May 2023 16:29:46 +0300 Subject: [PATCH 1/4] Added use case of oneOf discriminator --- ...-with-oneOf-properties-by-discriminator.js | 57 +++++++++++++ ...roperties-by-discriminator-when-missing.js | 79 +++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 packages/openapi-request-validator/test/data-driven/accept-requestBody-with-oneOf-properties-by-discriminator.js create mode 100644 packages/openapi-request-validator/test/data-driven/fail-requestBody-with-oneOf-properties-by-discriminator-when-missing.js diff --git a/packages/openapi-request-validator/test/data-driven/accept-requestBody-with-oneOf-properties-by-discriminator.js b/packages/openapi-request-validator/test/data-driven/accept-requestBody-with-oneOf-properties-by-discriminator.js new file mode 100644 index 00000000..68076d05 --- /dev/null +++ b/packages/openapi-request-validator/test/data-driven/accept-requestBody-with-oneOf-properties-by-discriminator.js @@ -0,0 +1,57 @@ +module.exports = { + validateArgs: { + requestBody: { + description: 'oneOf with discriminator', + content: { + 'application/json; charset=utf-8': { + schema: { + discriminator: 'my_type', + oneOf: [ + { + $ref: '#/components/schemas/Test1', + }, + { + $ref: "#/components/schemas/Test2" + }, + ] + } + } + } + }, + componentSchemas: { + Test1: { + properties: { + test1_prop: { + type: 'string' + }, + my_type: { + type: 'string', + enum: ['test1'] + } + }, + required: ['my_type', 'test1_prop'] + }, + Test2: { + properties: { + test2_prop: { + type: 'string' + }, + my_type: { + type: 'string', + enum: ['test2'] + } + }, + required: ['my_type'] + } + } + }, + request: { + body: { + 'my_type': 'test1', + 'test1_prop': 'something' + }, + headers: { + 'content-type': 'application/json', + }, + }, +} diff --git a/packages/openapi-request-validator/test/data-driven/fail-requestBody-with-oneOf-properties-by-discriminator-when-missing.js b/packages/openapi-request-validator/test/data-driven/fail-requestBody-with-oneOf-properties-by-discriminator-when-missing.js new file mode 100644 index 00000000..0a5d695b --- /dev/null +++ b/packages/openapi-request-validator/test/data-driven/fail-requestBody-with-oneOf-properties-by-discriminator-when-missing.js @@ -0,0 +1,79 @@ +module.exports = { + validateArgs: { + requestBody: { + description: 'oneOf with discriminator', + content: { + 'application/json; charset=utf-8': { + schema: { + discriminator: 'my_type', + oneOf: [ + { + $ref: '#/components/schemas/Test1', + }, + { + $ref: "#/components/schemas/Test2" + }, + ] + } + } + } + }, + componentSchemas: { + Test1: { + properties: { + test1_prop: { + type: 'string' + }, + my_type: { + type: 'string', + enum: ['test1'] + } + }, + required: ['my_type', 'test1_prop'] + }, + Test2: { + properties: { + test2_prop: { + type: 'string' + }, + my_type: { + type: 'string', + enum: ['test2'] + } + }, + required: ['my_type'] + } + } + }, + request: { + body: { + 'my_type': 'test1' + }, + headers: { + 'content-type': 'application/json', + }, + }, + + expectedError: { + status: 400, + errors: [ + { + errorCode: 'required.openapi.requestValidation', + location: 'body', + message: "must have required property 'test1_prop'", + path: 'test1_prop' + }, + { + errorCode: 'enum.openapi.requestValidation', + location: 'body', + message: 'must be equal to one of the allowed values', + path: 'my_type' + }, + { + errorCode: 'oneOf.openapi.requestValidation', + message: 'must match exactly one schema in oneOf', + location: 'body', + }, + ], + }, +} From 800ae637158f0acae05f9fd0ae4d8276e7b181cb Mon Sep 17 00:00:00 2001 From: sigals Date: Sat, 20 May 2023 16:39:21 +0300 Subject: [PATCH 2/4] Revert "Added use case of oneOf discriminator" This reverts commit c044f28501cee11a79d119302feb41f2389c0631. --- ...-with-oneOf-properties-by-discriminator.js | 57 ------------- ...roperties-by-discriminator-when-missing.js | 79 ------------------- 2 files changed, 136 deletions(-) delete mode 100644 packages/openapi-request-validator/test/data-driven/accept-requestBody-with-oneOf-properties-by-discriminator.js delete mode 100644 packages/openapi-request-validator/test/data-driven/fail-requestBody-with-oneOf-properties-by-discriminator-when-missing.js diff --git a/packages/openapi-request-validator/test/data-driven/accept-requestBody-with-oneOf-properties-by-discriminator.js b/packages/openapi-request-validator/test/data-driven/accept-requestBody-with-oneOf-properties-by-discriminator.js deleted file mode 100644 index 68076d05..00000000 --- a/packages/openapi-request-validator/test/data-driven/accept-requestBody-with-oneOf-properties-by-discriminator.js +++ /dev/null @@ -1,57 +0,0 @@ -module.exports = { - validateArgs: { - requestBody: { - description: 'oneOf with discriminator', - content: { - 'application/json; charset=utf-8': { - schema: { - discriminator: 'my_type', - oneOf: [ - { - $ref: '#/components/schemas/Test1', - }, - { - $ref: "#/components/schemas/Test2" - }, - ] - } - } - } - }, - componentSchemas: { - Test1: { - properties: { - test1_prop: { - type: 'string' - }, - my_type: { - type: 'string', - enum: ['test1'] - } - }, - required: ['my_type', 'test1_prop'] - }, - Test2: { - properties: { - test2_prop: { - type: 'string' - }, - my_type: { - type: 'string', - enum: ['test2'] - } - }, - required: ['my_type'] - } - } - }, - request: { - body: { - 'my_type': 'test1', - 'test1_prop': 'something' - }, - headers: { - 'content-type': 'application/json', - }, - }, -} diff --git a/packages/openapi-request-validator/test/data-driven/fail-requestBody-with-oneOf-properties-by-discriminator-when-missing.js b/packages/openapi-request-validator/test/data-driven/fail-requestBody-with-oneOf-properties-by-discriminator-when-missing.js deleted file mode 100644 index 0a5d695b..00000000 --- a/packages/openapi-request-validator/test/data-driven/fail-requestBody-with-oneOf-properties-by-discriminator-when-missing.js +++ /dev/null @@ -1,79 +0,0 @@ -module.exports = { - validateArgs: { - requestBody: { - description: 'oneOf with discriminator', - content: { - 'application/json; charset=utf-8': { - schema: { - discriminator: 'my_type', - oneOf: [ - { - $ref: '#/components/schemas/Test1', - }, - { - $ref: "#/components/schemas/Test2" - }, - ] - } - } - } - }, - componentSchemas: { - Test1: { - properties: { - test1_prop: { - type: 'string' - }, - my_type: { - type: 'string', - enum: ['test1'] - } - }, - required: ['my_type', 'test1_prop'] - }, - Test2: { - properties: { - test2_prop: { - type: 'string' - }, - my_type: { - type: 'string', - enum: ['test2'] - } - }, - required: ['my_type'] - } - } - }, - request: { - body: { - 'my_type': 'test1' - }, - headers: { - 'content-type': 'application/json', - }, - }, - - expectedError: { - status: 400, - errors: [ - { - errorCode: 'required.openapi.requestValidation', - location: 'body', - message: "must have required property 'test1_prop'", - path: 'test1_prop' - }, - { - errorCode: 'enum.openapi.requestValidation', - location: 'body', - message: 'must be equal to one of the allowed values', - path: 'my_type' - }, - { - errorCode: 'oneOf.openapi.requestValidation', - message: 'must match exactly one schema in oneOf', - location: 'body', - }, - ], - }, -} From 9fbea5b436efbfbf83868a5feb84a8e346535244 Mon Sep 17 00:00:00 2001 From: sigals Date: Sat, 20 May 2023 16:42:16 +0300 Subject: [PATCH 3/4] Add AJV options to response validator --- packages/openapi-response-validator/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/openapi-response-validator/index.ts b/packages/openapi-response-validator/index.ts index e306013d..f8daa97e 100644 --- a/packages/openapi-response-validator/index.ts +++ b/packages/openapi-response-validator/index.ts @@ -3,6 +3,7 @@ import Ajv, { Format, ErrorObject, ValidateFunction, + Options, } from 'ajv'; import { IJsonSchema, OpenAPIV2, OpenAPIV3 } from 'openapi-types'; @@ -37,6 +38,7 @@ export interface OpenAPIResponseValidatorArgs { openAPIResponseValidatorValidationError: OpenAPIResponseValidatorError, ajvError: ErrorObject ): any; + ajvOptions?: Options; } export interface OpenAPIResponseValidatorError { @@ -82,6 +84,7 @@ export default class OpenAPIResponseValidator strict: false, // @ts-ignore TODO get Ajv updated to account for logger logger: false, + ...(args.ajvOptions || {}), }); this.errorMapper = errorTransformer From e07179399a3feb1b12fb524851bc805e8527d0bf Mon Sep 17 00:00:00 2001 From: Sigal Shaharabani Date: Sat, 10 Jun 2023 18:30:20 +0300 Subject: [PATCH 4/4] Added test cases --- ...ail-with-discriminating-errors-on-oneof.js | 59 +++++++++++++++ ...il-with-indisriminating-errors-on-oneof.js | 71 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 packages/openapi-response-validator/test/data-driven/fail-with-discriminating-errors-on-oneof.js create mode 100644 packages/openapi-response-validator/test/data-driven/fail-with-indisriminating-errors-on-oneof.js diff --git a/packages/openapi-response-validator/test/data-driven/fail-with-discriminating-errors-on-oneof.js b/packages/openapi-response-validator/test/data-driven/fail-with-discriminating-errors-on-oneof.js new file mode 100644 index 00000000..6f09520c --- /dev/null +++ b/packages/openapi-response-validator/test/data-driven/fail-with-discriminating-errors-on-oneof.js @@ -0,0 +1,59 @@ +module.exports = { + constructorArgs: { + ajvOptions: { + discriminator: true + }, + responses: { + 200: { + schema: { + oneOf: [ + { + type: 'object', + properties: { + foo: { + type: 'string', + }, + my_type: { + type: 'string', + enum: ['foo'] + } + }, + required: ['foo', 'my_type'], + }, + { + + type: 'object', + properties: { + bar: { + type: 'string', + }, + my_type: { + type: 'string', + enum: ['bar'] + } + }, + required: ['bar', 'my_type'], + } + ], + discriminator: { + propertyName: 'my_type' + } + } + } + }, + }, + inputStatusCode: 200, + inputResponseBody: { + my_type: 'foo', + }, + expectedValidationError: { + message: 'The response was not valid.', + errors:[ + { + errorCode: 'required.openapi.responseValidation', + message: "must have required property 'foo'", + path: 'response' + } + ] + } +} diff --git a/packages/openapi-response-validator/test/data-driven/fail-with-indisriminating-errors-on-oneof.js b/packages/openapi-response-validator/test/data-driven/fail-with-indisriminating-errors-on-oneof.js new file mode 100644 index 00000000..292bdbea --- /dev/null +++ b/packages/openapi-response-validator/test/data-driven/fail-with-indisriminating-errors-on-oneof.js @@ -0,0 +1,71 @@ +module.exports = { + constructorArgs: { + responses: { + 200: { + schema: { + oneOf: [ + { + type: 'object', + properties: { + foo: { + type: 'string', + }, + my_type: { + type: 'string', + enum: ['foo'] + } + }, + required: ['foo', 'my_type'], + }, + { + + type: 'object', + properties: { + bar: { + type: 'string', + }, + my_type: { + type: 'string', + enum: ['bar'] + } + }, + required: ['bar', 'my_type'], + } + ], + discriminator: { + propertyName: 'my_type' + } + } + } + } + }, + inputStatusCode: 200, + inputResponseBody: { + my_type: 'foo', + }, + expectedValidationError: { + message: 'The response was not valid.', + errors:[ + { + errorCode: 'required.openapi.responseValidation', + message: "must have required property 'foo'", + path: 'response' + }, + { + errorCode: 'required.openapi.responseValidation', + message: "must have required property 'bar'", + path: 'response' + }, + { + errorCode: 'enum.openapi.responseValidation', + message: 'must be equal to one of the allowed values', + path: 'my_type' + }, + { + errorCode: 'oneOf.openapi.responseValidation', + message: 'must match exactly one schema in oneOf', + path: 'response' + } + ] + } +}