openapi-enforcer
Advanced tools
Comparing version 1.13.2 to 1.13.3
@@ -7,2 +7,12 @@ # Change Log | ||
## 1.13.3 | ||
### Fixed | ||
- **Discriminator Bugs** | ||
Various bugs were found for serializing, deserializing, randomly generating, and populating values off of a schema that included a discriminator. Some of these bugs were related to not following the OpenAPI specification closely enough. | ||
Now if a discriminator is specified then it will not attempt to find other matches when the discriminator does not resolve the schema. | ||
## 1.13.2 | ||
@@ -9,0 +19,0 @@ |
{ | ||
"name": "openapi-enforcer", | ||
"version": "1.13.2", | ||
"version": "1.13.3", | ||
"description": "Library for validating, parsing, and formatting data against open api schemas.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -63,5 +63,9 @@ /** | ||
let result; | ||
let subSchema; | ||
if (schema.discriminator && (subSchema = schema.discriminate(value))) { | ||
result = Object.assign(value, runDeserialize(exception, map, subSchema, originalValue, options)); | ||
if (schema.discriminator) { | ||
const { name, key, schema: subSchema } = schema.discriminate(value, true) | ||
if (subSchema) { | ||
result = Object.assign(value, runDeserialize(exception, map, subSchema, originalValue, options)); | ||
} else { | ||
exception.message('Discriminator property "' + key + '" as "' + name + '" did not map to a schema'); | ||
} | ||
} else { | ||
@@ -98,7 +102,7 @@ result = schemaUtil.anyOneOf(schema, | ||
if (schema.discriminator) { | ||
const subSchema = schema.discriminate(value); | ||
const { name, key, schema: subSchema } = schema.discriminate(value, true); | ||
if (subSchema) { | ||
Object.assign(value, runDeserialize(exception, map, subSchema, originalValue, options)); | ||
} else { | ||
exception.message('Unable to discriminate to schema'); | ||
exception.message('Discriminator property "' + key + '" as "' + name + '" did not map to a schema'); | ||
} | ||
@@ -105,0 +109,0 @@ } |
@@ -44,7 +44,7 @@ /** | ||
} else { | ||
const subSchema = schema.discriminate(value); | ||
const { name, key, schema: subSchema } = schema.discriminate(value, true); | ||
if (subSchema) { | ||
runPopulate(exception, warn, depth, subSchema, params, object, property, options); | ||
} else { | ||
exception.message('Unable to find discriminator schema'); | ||
exception.message('Discriminator property "' + key + '" as "' + name + '" did not map to a schema'); | ||
} | ||
@@ -51,0 +51,0 @@ } |
@@ -52,4 +52,16 @@ /** | ||
const mode = schema.anyOf ? 'anyOf' : 'oneOf'; | ||
const subSchema = schema.discriminator ? schema.discriminate(value) : chooseOne(schema[mode]); | ||
runRandom(exception, warn, map, subSchema, parent, property, options, depth); | ||
if (schema.discriminator) { | ||
const { name, key, schema: subSchema } = schema.discriminate(value, true); | ||
if (subSchema) { | ||
runRandom(exception, warn, map, subSchema, parent, property, options, depth); | ||
} else if (name === undefined) { | ||
const subSchema = chooseOne(schema[mode]) | ||
runRandom(exception, warn, map, subSchema, parent, property, options, depth); | ||
} else { | ||
exception.message('Discriminator property "' + key + '" as "' + name + '" did not map to a schema'); | ||
} | ||
} else { | ||
const subSchema = chooseOne(schema[mode]) | ||
runRandom(exception, warn, map, subSchema, parent, property, options, depth); | ||
} | ||
@@ -56,0 +68,0 @@ } else if (schema.not) { |
@@ -52,5 +52,9 @@ /** | ||
} else if (schema.anyOf || schema.oneOf) { | ||
let subSchema; | ||
if (schema.discriminator && (subSchema = schema.discriminate(value))) { | ||
Object.assign(value, runSerialize(exception, map, subSchema, originalValue)); | ||
if (schema.discriminator) { | ||
const { name, key, schema: subSchema } = schema.discriminate(value, true) | ||
if (subSchema) { | ||
Object.assign(value, runSerialize(exception, map, subSchema, originalValue)); | ||
} else { | ||
exception.message('Discriminator property "' + key + '" as "' + name + '" did not map to a schema'); | ||
} | ||
} else { | ||
@@ -86,7 +90,7 @@ return schemaUtil.anyOneOf(schema, originalValue, exception, map, runSerialize, true); | ||
if (schema.discriminator) { | ||
const subSchema = schema.discriminate(value); | ||
const { name, key, schema: subSchema } = schema.discriminate(value, true) | ||
if (subSchema) { | ||
Object.assign(value, runSerialize(exception, map, subSchema, originalValue)); | ||
} else { | ||
exception.message('Unable to discriminate to schema'); | ||
exception.message('Discriminator property "' + key + '" as "' + name + '" did not map to a schema'); | ||
} | ||
@@ -93,0 +97,0 @@ } |
@@ -56,4 +56,8 @@ const Exception = require('../exception'); | ||
} else if (matches.length === 0) { | ||
const child = exception.nest('No matching schemas'); | ||
exceptions.forEach(childException => child.push(childException)); | ||
if (exceptions.length > 0) { | ||
const child = exception.nest('No matching schemas'); | ||
exceptions.forEach(childException => child.push(childException)); | ||
} else { | ||
exception.message('No matching schemas') | ||
} | ||
} else { | ||
@@ -60,0 +64,0 @@ return util.merge(value, matches[0].result); |
@@ -78,7 +78,5 @@ /** | ||
if (schema.discriminator) { | ||
const data = schema.discriminate(value, true); | ||
const subSchema = data.schema; | ||
const key = data.key; | ||
const { name, key, schema: subSchema } = schema.discriminate(value, true); | ||
if (!subSchema) { | ||
exception.message('Discriminator property "' + key + '" as "' + value[key] + '" did not map to a schema'); | ||
exception.message('Discriminator property "' + key + '" as "' + name + '" did not map to a schema'); | ||
} else { | ||
@@ -205,3 +203,3 @@ runValidate(exception.at(value[key]), map, subSchema, value, options); | ||
} else if (name) { | ||
exception.message('The value "' + name + '" is not valid for "' + key + '" because it has no associated schema'); | ||
exception.message('Discriminator property "' + key + '" as "' + name + '" did not map to a schema'); | ||
} // else - already taken care of because it's a missing required error | ||
@@ -208,0 +206,0 @@ } |
@@ -115,3 +115,18 @@ const expect = require('chai').expect; | ||
info: { title: '', version: '' }, | ||
paths: {}, | ||
paths: { | ||
'/': { | ||
post: { | ||
requestBody: { | ||
content: { | ||
'application/json': { | ||
schema: { $ref: '#/components/schemas/content' } | ||
} | ||
} | ||
}, | ||
responses: { | ||
200: { description: 'ok' } | ||
} | ||
} | ||
} | ||
}, | ||
components: { | ||
@@ -160,3 +175,5 @@ schemas: { | ||
it('should validate correctly with valid discriminator property name', async () => { | ||
const openapi = await Enforcer(def, { hideWarnings: true }) | ||
const [ openapi, error ] = await Enforcer(def, { fullResult: true }) | ||
expect(error).to.equal(undefined) | ||
const err = openapi.components.schemas.content.validate({ | ||
@@ -169,4 +186,17 @@ type: 'text', | ||
it('should produce a valid exception with invalid discriminator property name', async () => { | ||
const openapi = await Enforcer(def, { hideWarnings: true }) | ||
it('should produce an exception with deserializing invalid discriminator property name', async () => { | ||
const [ openapi, error ] = await Enforcer(def, { fullResult: true }) | ||
expect(error).to.equal(undefined) | ||
const [ , err ] = openapi.components.schemas.content.deserialize({ | ||
type: 'audio', | ||
content: 'hello' | ||
}) | ||
expect(err).to.match(/Discriminator property "type" as "audio" did not map to a schema/) | ||
}) | ||
it('should produce an exception with validating invalid discriminator property name', async () => { | ||
const [ openapi, error ] = await Enforcer(def, { fullResult: true }) | ||
expect(error).to.equal(undefined) | ||
const err = openapi.components.schemas.content.validate({ | ||
@@ -178,4 +208,19 @@ type: 'audio', | ||
}) | ||
it('should produce an error for operation request with invalid discriminator property', async () => { | ||
const [ openapi ] = await Enforcer(def, { fullResult: true, toString: true, componentOptions: { production: false } }); | ||
const [, err] = openapi.request({ | ||
path: '/', | ||
method: 'POST', | ||
body: { | ||
type: 'audio', | ||
url: 'hello' | ||
}, | ||
}); | ||
expect(err).to.match(/Discriminator property "type" as "audio" did not map to a schema/); | ||
}) | ||
}) | ||
}); |
Sorry, the diff of this file is too big to display
1508194
20502