swagger-mock-validator
Advanced tools
Comparing version 8.0.0 to 9.0.0
@@ -0,1 +1,20 @@ | ||
# [9.0.0](https://bitbucket.org/atlassian/swagger-mock-validator/compare/8.0.0...9.0.0) (2019-11-07) | ||
### Bug Fixes | ||
* correctly validate request bodies containing a JSON null or false value ([79fae8c](https://bitbucket.org/atlassian/swagger-mock-validator/commits/79fae8c1cd2175f04070e4980120a699eeb87dff)) | ||
### Features | ||
* support the nullable attribute for data types ([d3c13cc](https://bitbucket.org/atlassian/swagger-mock-validator/commits/d3c13cc2f50c7f749a86d2ffa0f09e4bf6d4d6d2)) | ||
### BREAKING CHANGES | ||
* Prior to this change the tool used to succeed when a pact request specified a request body containing solely the JSON literals ‘null' or 'false’, regardless of what the spec accepted. Now, request bodies with such values will only pass validation if the spec is okay with them. | ||
# [8.0.0](https://bitbucket.org/atlassian/swagger-mock-validator/compare/7.0.0...8.0.0) (2019-09-18) | ||
@@ -2,0 +21,0 @@ |
@@ -5,3 +5,9 @@ "use strict"; | ||
const traverse_json_schema_1 = require("../../../common/traverse-json-schema"); | ||
const fixReferencesJsonSchemaVisitor = (mutableSchema) => { | ||
const isSingleTypeDefinition = (typeDefinition) => typeDefinition !== undefined && !Array.isArray(typeDefinition); | ||
const convertNullableToTypeNull = (mutableSchema) => { | ||
if (mutableSchema.nullable && isSingleTypeDefinition(mutableSchema.type)) { | ||
mutableSchema.type = [mutableSchema.type, 'null']; | ||
} | ||
}; | ||
const fixJsonSchemaReferences = (mutableSchema) => { | ||
if (mutableSchema.$ref && mutableSchema.$ref.indexOf('#/components/schemas/') === 0) { | ||
@@ -11,4 +17,8 @@ mutableSchema.$ref = mutableSchema.$ref.replace(/^#\/components\/schemas\//, '#/definitions/'); | ||
}; | ||
const pointComponentsSchemasToDefinitions = (schema) => { | ||
traverse_json_schema_1.traverseJsonSchema(schema, fixReferencesJsonSchemaVisitor); | ||
const prepareOpenApi3SchemaForValidationVisitor = (mutableSchema) => { | ||
convertNullableToTypeNull(mutableSchema); | ||
fixJsonSchemaReferences(mutableSchema); | ||
}; | ||
const prepareOpenApi3SchemaForValidation = (schema) => { | ||
traverse_json_schema_1.traverseJsonSchema(schema, prepareOpenApi3SchemaForValidationVisitor); | ||
return schema; | ||
@@ -21,3 +31,3 @@ }; | ||
modifiedSchema.definitions = schemaComponents; | ||
return pointComponentsSchemasToDefinitions(modifiedSchema); | ||
return prepareOpenApi3SchemaForValidation(modifiedSchema); | ||
}; |
@@ -17,3 +17,3 @@ "use strict"; | ||
}; | ||
const isOptionalRequestBodyMissing = (parsedMockInteraction, parsedSpecOperation) => !parsedMockInteraction.requestBody.value && | ||
const isOptionalRequestBodyMissing = (parsedMockInteraction, parsedSpecOperation) => parsedMockInteraction.requestBody.value === undefined && | ||
!(parsedSpecOperation.requestBodyParameter && parsedSpecOperation.requestBodyParameter.required); | ||
@@ -20,0 +20,0 @@ const specAndMockHaveNoBody = (parsedMockInteraction, parsedSpecOperation) => !parsedSpecOperation.requestBodyParameter && !parsedMockInteraction.requestBody.value; |
@@ -187,3 +187,3 @@ # OpenApi 3 Support | ||
| format | yes | | ||
| nullable | no | | ||
| nullable | yes | | ||
| discriminator | no | | ||
@@ -190,0 +190,0 @@ | readOnly | no | |
import * as _ from 'lodash'; | ||
import {JsonSchemaVisitor, traverseJsonSchema} from '../../../common/traverse-json-schema'; | ||
import {ParsedSpecJsonSchemaCore} from '../../parsed-spec'; | ||
import {ParsedSpecJsonSchemaCore, ParsedSpecJsonSchemaType} from '../../parsed-spec'; | ||
import {Openapi3Schema, Schema as Openapi3JsonSchema} from '../openapi3'; | ||
@@ -10,3 +10,14 @@ | ||
const fixReferencesJsonSchemaVisitor: JsonSchemaVisitor = (mutableSchema: ParsedSpecJsonSchemaCore) => { | ||
const isSingleTypeDefinition = ( | ||
typeDefinition: ParsedSpecJsonSchemaType | ParsedSpecJsonSchemaType[] | undefined | ||
): typeDefinition is ParsedSpecJsonSchemaType => | ||
typeDefinition !== undefined && !Array.isArray(typeDefinition); | ||
const convertNullableToTypeNull = (mutableSchema: ParsedSpecJsonSchemaCore) => { | ||
if ((mutableSchema as Openapi3JsonSchema).nullable && isSingleTypeDefinition(mutableSchema.type)) { | ||
mutableSchema.type = [mutableSchema.type, 'null']; | ||
} | ||
}; | ||
const fixJsonSchemaReferences = (mutableSchema: ParsedSpecJsonSchemaCore) => { | ||
if (mutableSchema.$ref && mutableSchema.$ref.indexOf('#/components/schemas/') === 0) { | ||
@@ -17,4 +28,9 @@ mutableSchema.$ref = mutableSchema.$ref.replace(/^#\/components\/schemas\//, '#/definitions/'); | ||
const pointComponentsSchemasToDefinitions = (schema: Openapi3JsonSchema): ParsedSpecJsonSchemaCore => { | ||
traverseJsonSchema(schema, fixReferencesJsonSchemaVisitor); | ||
const prepareOpenApi3SchemaForValidationVisitor: JsonSchemaVisitor = (mutableSchema: ParsedSpecJsonSchemaCore) => { | ||
convertNullableToTypeNull(mutableSchema); | ||
fixJsonSchemaReferences(mutableSchema); | ||
}; | ||
const prepareOpenApi3SchemaForValidation = (schema: Openapi3JsonSchema): ParsedSpecJsonSchemaCore => { | ||
traverseJsonSchema(schema, prepareOpenApi3SchemaForValidationVisitor); | ||
return schema; | ||
@@ -32,3 +48,3 @@ }; | ||
modifiedSchema.definitions = schemaComponents; | ||
return pointComponentsSchemasToDefinitions(modifiedSchema); | ||
return prepareOpenApi3SchemaForValidation(modifiedSchema); | ||
}; |
@@ -76,3 +76,3 @@ export interface ParsedSpec { | ||
required?: string[]; | ||
type?: ParsedSpecJsonSchemaType; | ||
type?: ParsedSpecJsonSchemaType | ParsedSpecJsonSchemaType[]; | ||
uniqueItems?: boolean; | ||
@@ -79,0 +79,0 @@ } |
@@ -26,3 +26,3 @@ import * as _ from 'lodash'; | ||
parsedMockInteraction: ParsedMockInteraction, parsedSpecOperation: ParsedSpecOperation | ||
) => !parsedMockInteraction.requestBody.value && | ||
) => parsedMockInteraction.requestBody.value === undefined && | ||
!(parsedSpecOperation.requestBodyParameter && parsedSpecOperation.requestBodyParameter.required); | ||
@@ -29,0 +29,0 @@ |
{ | ||
"name": "swagger-mock-validator", | ||
"version": "8.0.0", | ||
"version": "9.0.0", | ||
"description": "A CLI tool to validate mocks against swagger/OpenApi specs.", | ||
@@ -5,0 +5,0 @@ "bin": { |
@@ -28,3 +28,3 @@ import {customMatchers, CustomMatchers} from './support/custom-jasmine-matchers'; | ||
swaggerDefinitions?: DefinitionsBuilder) => { | ||
const interactionWithRequestBodyBuilder = pactRequestBody | ||
const interactionWithRequestBodyBuilder = pactRequestBody !== undefined | ||
? defaultInteractionBuilder.withRequestBody(pactRequestBody) | ||
@@ -74,3 +74,3 @@ : defaultInteractionBuilder; | ||
message: 'Request body is incompatible with the request body schema in the spec file: ' + | ||
'should be number', | ||
'should be number', | ||
mockDetails: { | ||
@@ -181,3 +181,3 @@ interactionDescription: 'interaction description', | ||
message: 'Request body is incompatible with the request body schema in the spec file: ' + | ||
'should be number', | ||
'should be number', | ||
mockDetails: { | ||
@@ -202,3 +202,3 @@ interactionDescription: 'interaction description', | ||
message: 'Request body is incompatible with the request body schema in the spec file: ' + | ||
'should be number', | ||
'should be number', | ||
mockDetails: { | ||
@@ -257,3 +257,3 @@ interactionDescription: 'interaction description', | ||
const result = await validateRequestBody(null, swaggerBodyParameter); | ||
const result = await validateRequestBody(undefined, swaggerBodyParameter); | ||
@@ -264,3 +264,3 @@ expect(result.failureReason).toEqual(expectedFailedValidationError); | ||
message: 'Request body is incompatible with the request body schema in the spec file: ' + | ||
'should be object', | ||
'should be object', | ||
mockDetails: { | ||
@@ -291,3 +291,3 @@ interactionDescription: 'interaction description', | ||
const result = await validateRequestBody(null, swaggerBodyParameter); | ||
const result = await validateRequestBody(undefined, swaggerBodyParameter); | ||
@@ -310,3 +310,3 @@ expect(result).toContainNoWarningsOrErrors(); | ||
message: 'Request body is incompatible with the request body schema in the spec file: ' + | ||
'should be object', | ||
'should be object', | ||
mockDetails: { | ||
@@ -345,3 +345,3 @@ interactionDescription: 'interaction description', | ||
message: 'Request body is incompatible with the request body schema in the spec file: ' + | ||
'should NOT have additional properties', | ||
'should NOT have additional properties', | ||
mockDetails: { | ||
@@ -398,2 +398,32 @@ interactionDescription: 'interaction description', | ||
}); | ||
it('should return the error when pact request body is a JSON null value and not matching the schema', async () => { | ||
const pactRequestBody = null; | ||
const swaggerBodyParameter = bodyParameterBuilder.withOptionalSchema(schemaBuilder.withTypeNumber()); | ||
const result = await validateRequestBody(pactRequestBody, swaggerBodyParameter); | ||
expect(result.failureReason).toEqual(expectedFailedValidationError); | ||
expect(result).toContainErrors([{ | ||
code: 'request.body.incompatible', | ||
message: 'Request body is incompatible with the request body schema in the spec file: should be number', | ||
mockDetails: { | ||
interactionDescription: 'interaction description', | ||
interactionState: '[none]', | ||
location: '[root].interactions[0].request.body', | ||
mockFile: 'pact.json', | ||
value: null | ||
}, | ||
source: 'spec-mock-validation', | ||
specDetails: { | ||
location: '[root].paths./does/exist.get.parameters[0].schema.type', | ||
pathMethod: 'get', | ||
pathName: '/does/exist', | ||
specFile: 'spec.json', | ||
value: 'number' | ||
}, | ||
type: 'error' | ||
}]); | ||
}); | ||
}); |
@@ -10,3 +10,3 @@ import * as _ from 'lodash'; | ||
actualResults: T[]; | ||
customEqualityTesters: CustomEqualityTester[]; | ||
customEqualityTesters: ReadonlyArray<CustomEqualityTester>; | ||
expectedResults: T[]; | ||
@@ -19,3 +19,3 @@ type: string; | ||
actualResult: T; | ||
customEqualityTesters: CustomEqualityTester[]; | ||
customEqualityTesters: ReadonlyArray<CustomEqualityTester>; | ||
expectedResult: T; | ||
@@ -29,3 +29,3 @@ index: number; | ||
actualResult: T; | ||
customEqualityTesters: CustomEqualityTester[]; | ||
customEqualityTesters: ReadonlyArray<CustomEqualityTester>; | ||
expectedResult: T; | ||
@@ -32,0 +32,0 @@ index: number; |
@@ -19,2 +19,3 @@ import {cloneDeep} from 'lodash'; | ||
createOpenApi3SchemaBuilder(setValueOn(openApi3Schema, `not`, schemaBuilder.build())), | ||
withNullable: (value: boolean) => createOpenApi3SchemaBuilder(setValueOn(openApi3Schema, 'nullable', value)), | ||
withOneOf: (schemaBuilders: OpenApi3SchemaBuilder[]) => | ||
@@ -21,0 +22,0 @@ createOpenApi3SchemaBuilder( |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
874207
17876