From 3bea389715cdbb7435874eebcf27e50ac1310c50 Mon Sep 17 00:00:00 2001 From: Oliwia Rogala Date: Wed, 10 Apr 2024 08:41:49 +0200 Subject: [PATCH] fix(oas3): compensate for JSON Schemas left unresolved by swagger-client (#9794) Refs #9790 --- src/core/components/model.jsx | 18 +++-- .../plugins/oas3/all-of-circular-ref.cy.js | 31 +++++++++ .../features/oas3-all-of-circular-ref.yaml | 69 +++++++++++++++++++ 3 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 test/e2e-cypress/e2e/features/plugins/oas3/all-of-circular-ref.cy.js create mode 100644 test/e2e-cypress/static/documents/features/oas3-all-of-circular-ref.yaml diff --git a/src/core/components/model.jsx b/src/core/components/model.jsx index d69b8dfa..dd7a7db8 100644 --- a/src/core/components/model.jsx +++ b/src/core/components/model.jsx @@ -66,16 +66,20 @@ export default class Model extends ImmutablePureComponent { /* * If we have an unresolved ref, get the schema and name from the ref. * If the ref is external, we can't resolve it, so we just display the ref location. - * This is for situations where the ref was not resolved by Swagger Client - * because we reached the traversal depth limit. + * This is for situations where: + * - the ref was not resolved by Swagger Client because we reached the traversal depth limit + * - we had a circular ref inside the allOf keyword */ if ($ref) { - name = this.getModelName($ref) - const refSchema = this.getRefSchema(name) + const refName = this.getModelName($ref) + const refSchema = this.getRefSchema(refName) if (Map.isMap(refSchema)) { - schema = refSchema.set("$$ref", $ref) - $$ref = $ref - } else { + schema = refSchema.mergeDeep(schema) + if (!$$ref) { + schema = schema.set("$$ref", $ref) + $$ref = $ref + } + } else if (Map.isMap(schema) && schema.size === 1) { schema = null name = $ref } diff --git a/test/e2e-cypress/e2e/features/plugins/oas3/all-of-circular-ref.cy.js b/test/e2e-cypress/e2e/features/plugins/oas3/all-of-circular-ref.cy.js new file mode 100644 index 00000000..d3c3cfab --- /dev/null +++ b/test/e2e-cypress/e2e/features/plugins/oas3/all-of-circular-ref.cy.js @@ -0,0 +1,31 @@ +/** + * @prettier + */ + +describe("OpenAPI 3.0 spec with allOf containing a circular reference", () => { + it("should render correct title and properties", () => { + cy.visit("/?url=/documents/features/oas3-all-of-circular-ref.yaml").then( + () => { + cy.get("[id='model-OneOfParent']").find("button").click() + cy.get(".property-row") + .contains("additionalData") + .siblings() + .as("additionalData") + cy.get("@additionalData").find("button").click() + cy.get("@additionalData") + .find("span") + .contains("FirstOneOf") + .should("exist") + .click() + cy.get("@additionalData") + .find("span") + .contains("numberProp") + .should("exist") + cy.get("@additionalData") + .find("span") + .contains("additionalData") + .should("exist") + } + ) + }) +}) diff --git a/test/e2e-cypress/static/documents/features/oas3-all-of-circular-ref.yaml b/test/e2e-cypress/static/documents/features/oas3-all-of-circular-ref.yaml new file mode 100644 index 00000000..a5a4066a --- /dev/null +++ b/test/e2e-cypress/static/documents/features/oas3-all-of-circular-ref.yaml @@ -0,0 +1,69 @@ +openapi: 3.0.0 +info: + title: Test + description: 'Test' + license: + name: 'Apache 2.0' + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' + version: '1.0' +servers: + - + url: 'https://localhost:8000' +components: + schemas: + OneOfParent: + title: OneOfParent + properties: + additionalData: + oneOf: + - + $ref: '#/components/schemas/FirstOneOf' + - + $ref: '#/components/schemas/SecondOneOf' + - + $ref: '#/components/schemas/ThirdOneOf' + type: object + FirstOneOf: + title: FirstOneOf + type: object + allOf: + - + $ref: '#/components/schemas/OneOfParent' + - + properties: + numberProp: + type: number + example: '1' + type: object + SecondOneOf: + title: SecondOneOf + type: object + allOf: + - + $ref: '#/components/schemas/OneOfParent' + - + properties: + person: + properties: + id: + type: string + type: object + type: object + ThirdOneOf: + title: ThirdOneOf + type: object + allOf: + - + $ref: '#/components/schemas/OneOfParent' + - + properties: + person: + properties: + id: + type: string + name: + type: string + surname: + type: string + type: object + type: object