From 57cdd9f6da38418d6214ac3c6480c5847ecd0228 Mon Sep 17 00:00:00 2001 From: AlexVarchuk Date: Fri, 4 Feb 2022 15:21:46 +0200 Subject: [PATCH] fix: external ref in schema definition (#1894) --- src/services/OpenAPIParser.ts | 3 ++ src/services/__tests__/OpenAPIParser.test.ts | 11 ++++ .../__snapshots__/OpenAPIParser.test.ts.snap | 11 ++++ .../fixtures/3.1/schemaDefinition.json | 54 +++++++++++++++++++ src/services/__tests__/models/Schema.test.ts | 8 +++ 5 files changed, 87 insertions(+) create mode 100644 src/services/__tests__/fixtures/3.1/schemaDefinition.json diff --git a/src/services/OpenAPIParser.ts b/src/services/OpenAPIParser.ts index a82b0d83dd..bdc86bbebb 100644 --- a/src/services/OpenAPIParser.ts +++ b/src/services/OpenAPIParser.ts @@ -191,6 +191,9 @@ export class OpenAPIParser { const { $ref, ...rest } = ref; const keys = Object.keys(rest); if (keys.length === 0) { + if (this.isRef(resolved)) { + return this.shallowDeref(resolved); + } return resolved; } if ( diff --git a/src/services/__tests__/OpenAPIParser.test.ts b/src/services/__tests__/OpenAPIParser.test.ts index 60dea80944..7942b7b1dd 100644 --- a/src/services/__tests__/OpenAPIParser.test.ts +++ b/src/services/__tests__/OpenAPIParser.test.ts @@ -26,5 +26,16 @@ describe('Models', () => { expect(parser.shallowDeref(schemaOrRef)).toMatchSnapshot(); }); + + test('should correct resolve double $ref if no need sibling', () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const spec = require('./fixtures/3.1/schemaDefinition.json'); + parser = new OpenAPIParser(spec, undefined, opts); + const schemaOrRef: Referenced = { + $ref: '#/components/schemas/Parent', + }; + + expect(parser.deref(schemaOrRef, false, true)).toMatchSnapshot(); + }); }); }); diff --git a/src/services/__tests__/__snapshots__/OpenAPIParser.test.ts.snap b/src/services/__tests__/__snapshots__/OpenAPIParser.test.ts.snap index ffbcbff54a..8b5ea0181d 100644 --- a/src/services/__tests__/__snapshots__/OpenAPIParser.test.ts.snap +++ b/src/services/__tests__/__snapshots__/OpenAPIParser.test.ts.snap @@ -1,5 +1,16 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Models Schema should correct resolve double $ref if no need sibling 1`] = ` +Object { + "properties": Object { + "test": Object { + "type": "string", + }, + }, + "type": "object", +} +`; + exports[`Models Schema should hoist oneOfs when mergin allOf 1`] = ` Object { "oneOf": Array [ diff --git a/src/services/__tests__/fixtures/3.1/schemaDefinition.json b/src/services/__tests__/fixtures/3.1/schemaDefinition.json new file mode 100644 index 0000000000..9cac3b5f9a --- /dev/null +++ b/src/services/__tests__/fixtures/3.1/schemaDefinition.json @@ -0,0 +1,54 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Schema definition double $ref", + "version": "1.0.0" + }, + "servers": [ + { + "url": "example.com" + } + ], + "tags": [ + { + "name": "test", + "x-displayName": "The test Model", + "description": "\n" + } + ], + "paths": { + "/newPath": { + "post": { + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Child" + } + } + } + }, + "responses": { + "200": { + "description": "all ok" + } + } + } + } + }, + "components": { + "schemas": { + "Parent": { + "$ref": "#/components/schemas/Child" + }, + "Child": { + "type": "object", + "properties": { + "test": { + "type": "string" + } + } + } + } + } +} diff --git a/src/services/__tests__/models/Schema.test.ts b/src/services/__tests__/models/Schema.test.ts index 460ca7c110..9b9cdafcc0 100644 --- a/src/services/__tests__/models/Schema.test.ts +++ b/src/services/__tests__/models/Schema.test.ts @@ -40,5 +40,13 @@ describe('Models', () => { expect(schema.oneOf).toHaveLength(2); expect(schema.displayType).toBe('(Array of strings or numbers) or string'); }); + + test('schemaDefinition should resolve double ref', () => { + const spec = require('../fixtures/3.1/schemaDefinition.json'); + parser = new OpenAPIParser(spec, undefined, opts); + const schema = new SchemaModel(parser, spec.components.schemas.Parent, '', opts); + expect(schema.fields).toHaveLength(1); + expect(schema.pointer).toBe('#/components/schemas/Child'); + }); }); });