From 5573a614ca5f672c4f628d95069513f4d37287ac Mon Sep 17 00:00:00 2001 From: Andrew Tatomyr Date: Fri, 19 Jan 2024 11:53:50 +0200 Subject: [PATCH] fix: false positive errors when validating examples with refs (#1377) --- .changeset/small-rules-vanish.md | 6 +++ .../components.yaml | 11 ++++ .../openapi.yaml | 21 ++++++++ .../redocly.yaml | 6 +++ .../snapshot.js | 11 ++++ .../openapi.yaml | 53 +++++++++++++++++++ .../redocly.yaml | 6 +++ .../snapshot.js | 11 ++++ package-lock.json | 12 ++--- packages/core/src/rules/ajv.ts | 10 ++-- 10 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 .changeset/small-rules-vanish.md create mode 100644 __tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/components.yaml create mode 100644 __tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/openapi.yaml create mode 100644 __tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/redocly.yaml create mode 100644 __tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/snapshot.js create mode 100644 __tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/openapi.yaml create mode 100644 __tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/redocly.yaml create mode 100644 __tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/snapshot.js diff --git a/.changeset/small-rules-vanish.md b/.changeset/small-rules-vanish.md new file mode 100644 index 0000000000..d246ee9bbe --- /dev/null +++ b/.changeset/small-rules-vanish.md @@ -0,0 +1,6 @@ +--- +"@redocly/openapi-core": patch +"@redocly/cli": patch +--- + +Fixed a problem where the linter incorrectly returned an error for valid examples that contain references. diff --git a/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/components.yaml b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/components.yaml new file mode 100644 index 0000000000..c1a28f0b92 --- /dev/null +++ b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/components.yaml @@ -0,0 +1,11 @@ +components: + schemas: + A: + type: object + properties: + a: + type: string + b: + $ref: '#/components/schemas/B' + B: + type: string diff --git a/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/openapi.yaml b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/openapi.yaml new file mode 100644 index 0000000000..5c640b6075 --- /dev/null +++ b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/openapi.yaml @@ -0,0 +1,21 @@ +openapi: 3.1.0 +components: + schemas: + C: + $ref: './components.yaml#/components/schemas/A' + D: + $ref: './components.yaml#/components/schemas/A' +paths: + /pet: + get: + responses: + 200: + content: + application/json: + example: { 'a': 'test', 'b': 'test' } + schema: + $ref: '#/components/schemas/C' + application/x+json: + example: { 'a': 'test', 'b': 'test' } + schema: + $ref: '#/components/schemas/D' diff --git a/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/redocly.yaml b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/redocly.yaml new file mode 100644 index 0000000000..3516cbec1d --- /dev/null +++ b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/redocly.yaml @@ -0,0 +1,6 @@ +apis: + main: + root: ./openapi.yaml + +rules: + no-invalid-media-type-examples: error diff --git a/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/snapshot.js b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/snapshot.js new file mode 100644 index 0000000000..1cb5d0b959 --- /dev/null +++ b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs-different-files/snapshot.js @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`E2E lint no-invalid-media-type-examples-multiple-valid-refs-different-files 1`] = ` + +validating /openapi.yaml... +/openapi.yaml: validated in ms + +Woohoo! Your API description is valid. 🎉 + + +`; diff --git a/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/openapi.yaml b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/openapi.yaml new file mode 100644 index 0000000000..71ffe21ede --- /dev/null +++ b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/openapi.yaml @@ -0,0 +1,53 @@ +openapi: 3.1.0 +paths: + /foo: + get: + responses: + '200': + content: + application/json: + schema: + type: object + properties: + id: + $ref: '#/components/schemas/foo' + examples: + ValidFoo: + value: + id: 1 + /bar: + get: + responses: + '200': + content: + application/json: + schema: + type: object + properties: + id: + $ref: '#/components/schemas/bar' + examples: + ValidBar: + value: + id: 1 + application/baz+json: + schema: + type: object + properties: + id: + $ref: '#/components/schemas/baz' + examples: + ValidBaz: + value: # + id: 3 + +components: + schemas: + commonId: + type: integer + foo: + $ref: '#/components/schemas/commonId' + bar: + $ref: '#/components/schemas/commonId' + baz: + $ref: '#/components/schemas/commonId' diff --git a/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/redocly.yaml b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/redocly.yaml new file mode 100644 index 0000000000..3516cbec1d --- /dev/null +++ b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/redocly.yaml @@ -0,0 +1,6 @@ +apis: + main: + root: ./openapi.yaml + +rules: + no-invalid-media-type-examples: error diff --git a/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/snapshot.js b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/snapshot.js new file mode 100644 index 0000000000..255b2115c7 --- /dev/null +++ b/__tests__/lint/no-invalid-media-type-examples-multiple-valid-refs/snapshot.js @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`E2E lint no-invalid-media-type-examples-multiple-valid-refs 1`] = ` + +validating /openapi.yaml... +/openapi.yaml: validated in ms + +Woohoo! Your API description is valid. 🎉 + + +`; diff --git a/package-lock.json b/package-lock.json index 3694f16933..c8580b3168 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9373,9 +9373,9 @@ } }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -20008,9 +20008,9 @@ }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true } } diff --git a/packages/core/src/rules/ajv.ts b/packages/core/src/rules/ajv.ts index b7790b484a..90f101bb0a 100644 --- a/packages/core/src/rules/ajv.ts +++ b/packages/core/src/rules/ajv.ts @@ -1,6 +1,8 @@ -import Ajv, { ValidateFunction, ErrorObject } from '@redocly/ajv/dist/2020'; +import Ajv from '@redocly/ajv/dist/2020'; import { Location, escapePointer } from '../ref-utils'; -import { ResolveFn } from '../walk'; + +import type { ValidateFunction, ErrorObject } from '@redocly/ajv/dist/2020'; +import type { ResolveFn } from '../walk'; let ajvInstance: Ajv | null = null; @@ -21,10 +23,10 @@ function getAjv(resolve: ResolveFn, allowAdditionalProperties: boolean) { allowUnionTypes: true, validateFormats: false, // TODO: fix it defaultUnevaluatedProperties: allowAdditionalProperties, - loadSchemaSync(base: string, $ref: string) { + loadSchemaSync(base: string, $ref: string, $id: string) { const resolvedRef = resolve({ $ref }, base.split('#')[0]); if (!resolvedRef || !resolvedRef.location) return false; - return { $id: resolvedRef.location.absolutePointer, ...resolvedRef.node }; + return { $id: resolvedRef.location.source.absoluteRef + '#' + $id, ...resolvedRef.node }; }, logger: false, });