Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/rich-falcons-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@redocly/openapi-core": patch
---

Fixed the `no-invalid-schema-examples` rule validating nullable OpenAPI 3.0 schemas incorrectly.
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,39 @@ describe('no-invalid-schema-examples', () => {
]
`);
});

it('should not report on nullable example for OAS3', async () => {
const document = parseYamlToDocument(
outdent`
openapi: 3.0.3
info: {}
paths:
/subscriptions:
get:
responses:
"200":
content:
application/json:
schema:
nullable: true
type: object
example: null
allOf:
- $ref: "#/components/schemas/RiskMetadata"
components:
schemas:
RiskMetadata:
type: object
`,
'foobar.yaml'
);

const results = await lintDocument({
externalRefResolver: new BaseResolver(),
document,
config: await makeConfig({ rules: { 'no-invalid-schema-examples': 'error' } }),
});

expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
});
});
24 changes: 18 additions & 6 deletions packages/core/src/rules/common/no-invalid-schema-examples.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
import { getAdditionalPropertiesOption, validateExample } from '../utils';

import type { UserContext } from '../../walk';
import type { Oas3_1Schema } from '../../typings/openapi';
import type { Oas3_1Schema, Oas3Schema } from '../../typings/openapi';
import type { Oas2Rule, Oas3Rule } from '../../visitors';

export const NoInvalidSchemaExamples: any = (opts: any) => {
export const NoInvalidSchemaExamples: Oas3Rule | Oas2Rule = (opts: any) => {
const allowAdditionalProperties = getAdditionalPropertiesOption(opts) ?? false;
return {
Schema: {
leave(schema: Oas3_1Schema, ctx: UserContext) {
if (schema.examples) {
for (const example of schema.examples) {
leave(schema: Oas3_1Schema | Oas3Schema, ctx: UserContext) {
const examples = (schema as Oas3_1Schema).examples;
if (examples) {
for (const example of examples) {
validateExample(
example,
schema,
ctx.location.child(['examples', schema.examples.indexOf(example)]),
ctx.location.child(['examples', examples.indexOf(example)]),
ctx,
allowAdditionalProperties
);
}
}

if (schema.example !== undefined) {
// Handle nullable example for OAS3
if (
(schema as Oas3Schema).nullable === true &&
schema.example === null &&
schema.type !== undefined
) {
return;
}

validateExample(schema.example, schema, ctx.location.child('example'), ctx, true);
}
},
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/rules/oas2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const rules: Oas2RuleSet<'built-in'> = {
//@ts-ignore TODO: This is depricated property `spec` and should be removed in the future
spec: Struct as Oas2Rule,
struct: Struct as Oas2Rule,
'no-invalid-schema-examples': NoInvalidSchemaExamples,
'no-invalid-schema-examples': NoInvalidSchemaExamples as Oas2Rule,
'no-invalid-parameter-examples': NoInvalidParameterExamples,
'info-contact': InfoContact as Oas2Rule,
'info-license': InfoLicense as Oas2Rule,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/rules/oas3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export const rules: Oas3RuleSet<'built-in'> = {
'request-mime-type': RequestMimeType,
'response-mime-type': ResponseMimeType,
'path-segment-plural': PathSegmentPlural as Oas3Rule,
'no-invalid-schema-examples': NoInvalidSchemaExamples,
'no-invalid-schema-examples': NoInvalidSchemaExamples as Oas3Rule,
'no-invalid-parameter-examples': NoInvalidParameterExamples,
'response-contains-header': ResponseContainsHeader as Oas3Rule,
'response-contains-property': ResponseContainsProperty,
Expand Down
Loading