From 9037acf508beacac1efcb4f39403c203097d193e Mon Sep 17 00:00:00 2001 From: Oliwia Rogala Date: Tue, 14 May 2024 11:54:44 +0200 Subject: [PATCH] fix(components): add support for oneOf/anyOf JSON Schema keywords in parameter-row rendering (#9934) Refs #7912 --- src/core/components/parameter-row.jsx | 17 ++++++- .../features/parameters-one-of-any-of.cy.js | 49 ++++++++++++++++++ .../parameters-one-of-any-of-oas3.yaml | 50 +++++++++++++++++++ .../parameters-one-of-any-of-oas31.yaml | 50 +++++++++++++++++++ .../bugs/4557-default-parameter-values.jsx | 2 + test/unit/components/parameter-row.jsx | 4 ++ 6 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 test/e2e-cypress/e2e/features/parameters-one-of-any-of.cy.js create mode 100644 test/e2e-cypress/static/documents/features/parameters-one-of-any-of-oas3.yaml create mode 100644 test/e2e-cypress/static/documents/features/parameters-one-of-any-of-oas31.yaml diff --git a/src/core/components/parameter-row.jsx b/src/core/components/parameter-row.jsx index 2e440783f7b..cb3b7780143 100644 --- a/src/core/components/parameter-row.jsx +++ b/src/core/components/parameter-row.jsx @@ -1,5 +1,5 @@ import React, { Component } from "react" -import { Map, List } from "immutable" +import { Map, List, fromJS } from "immutable" import PropTypes from "prop-types" import ImPropTypes from "react-immutable-proptypes" import win from "core/window" @@ -97,7 +97,7 @@ export default class ParameterRow extends Component { let { specSelectors, pathMethod, rawParam, oas3Selectors, fn } = this.props const paramWithMeta = specSelectors.parameterWithMetaByIdentity(pathMethod, rawParam) || Map() - const { schema } = getParameterSchema(paramWithMeta, { isOAS3: specSelectors.isOAS3() }) + let { schema } = getParameterSchema(paramWithMeta, { isOAS3: specSelectors.isOAS3() }) const parameterMediaType = paramWithMeta .get("content", Map()) .keySeq() @@ -126,6 +126,8 @@ export default class ParameterRow extends Component { ? paramWithMeta.getIn(["schema", "example"]) : (schema && schema.getIn(["default"])) } else if (specSelectors.isOAS3()) { + schema = this.composeJsonSchema(schema) + const currentExampleKey = oas3Selectors.activeExamplesMember(...pathMethod, "parameters", this.getParamKey()) initialValue = paramWithMeta.getIn(["examples", currentExampleKey, "value"]) !== undefined @@ -181,6 +183,13 @@ export default class ParameterRow extends Component { return `${param.get("name")}-${param.get("in")}` } + composeJsonSchema(schema) { + const { fn } = this.props + const oneOf = schema.get("oneOf")?.get(0)?.toJS() + const anyOf = schema.get("anyOf")?.get(0)?.toJS() + return fromJS(fn.mergeJsonSchema(schema.toJS(), oneOf ?? anyOf ?? {})) + } + render() { let {param, rawParam, getComponent, getConfigs, isExecute, fn, onChangeConsumes, specSelectors, pathMethod, specPath, oas3Selectors} = this.props @@ -222,6 +231,10 @@ export default class ParameterRow extends Component { let { schema } = getParameterSchema(param, { isOAS3 }) let paramWithMeta = specSelectors.parameterWithMetaByIdentity(pathMethod, rawParam) || Map() + if (isOAS3) { + schema = this.composeJsonSchema(schema) + } + let format = schema ? schema.get("format") : null let type = schema ? schema.get("type") : null let itemType = schema ? schema.getIn(["items", "type"]) : null diff --git a/test/e2e-cypress/e2e/features/parameters-one-of-any-of.cy.js b/test/e2e-cypress/e2e/features/parameters-one-of-any-of.cy.js new file mode 100644 index 00000000000..943cba52337 --- /dev/null +++ b/test/e2e-cypress/e2e/features/parameters-one-of-any-of.cy.js @@ -0,0 +1,49 @@ +/** + * @prettier + */ + +describe("Parameter with oneOf and anyOf keywords in OpenAPI 3.0.x", () => { + it("should render correct form fields", () => { + cy.visit("/?url=/documents/features/parameters-one-of-any-of-oas3.yaml") + .get("#operations-default-get_") + .click() + cy.get(".parameters-col_description") + .eq(1) + .find("select") + .should("exist") + .and("have.value", "ascending") + cy.get(".parameters-col_description") + .eq(2) + .find("input") + .should("exist") + .and("have.value", "test") + cy.get(".parameters-col_description") + .eq(3) + .find("textarea") + .should("exist") + .and("contain", "\"eq\": \"active\"") + }) +}) + +describe("Parameter with oneOf and anyOf keywords in OpenAPI 3.1.0.", () => { + it("should render correct form fields", () => { + cy.visit("/?url=/documents/features/parameters-one-of-any-of-oas31.yaml") + .get("#operations-default-get_") + .click() + cy.get(".parameters-col_description") + .eq(1) + .find("select") + .should("exist") + .and("have.value", "ascending") + cy.get(".parameters-col_description") + .eq(2) + .find("input") + .should("exist") + .and("have.value", "test") + cy.get(".parameters-col_description") + .eq(3) + .find("textarea") + .should("exist") + .and("contain", "\"eq\": \"active\"") + }) +}) diff --git a/test/e2e-cypress/static/documents/features/parameters-one-of-any-of-oas3.yaml b/test/e2e-cypress/static/documents/features/parameters-one-of-any-of-oas3.yaml new file mode 100644 index 00000000000..873846ad01d --- /dev/null +++ b/test/e2e-cypress/static/documents/features/parameters-one-of-any-of-oas3.yaml @@ -0,0 +1,50 @@ +openapi: 3.0.0 +paths: + /: + get: + parameters: + - name: enum + in: query + schema: + oneOf: + - type: string + default: ascending + enum: + - ascending + - descending + - name: string + in: query + default: test + schema: + anyOf: + - type: string + - name: object + in: query + schema: + oneOf: + - type: object + properties: + eq: + type: string + enum: + - active + - archived + neq: + type: string + enum: + - active + - archived + in: + type: array + items: + type: string + enum: + - active + - archived + notIn: + type: array + items: + type: string + enum: + - active + - archived diff --git a/test/e2e-cypress/static/documents/features/parameters-one-of-any-of-oas31.yaml b/test/e2e-cypress/static/documents/features/parameters-one-of-any-of-oas31.yaml new file mode 100644 index 00000000000..563aef35d67 --- /dev/null +++ b/test/e2e-cypress/static/documents/features/parameters-one-of-any-of-oas31.yaml @@ -0,0 +1,50 @@ +openapi: 3.1.0 +paths: + /: + get: + parameters: + - name: enum + in: query + schema: + oneOf: + - type: string + default: ascending + enum: + - ascending + - descending + - name: string + in: query + default: test + schema: + anyOf: + - type: string + - name: object + in: query + schema: + oneOf: + - type: object + properties: + eq: + type: string + enum: + - active + - archived + neq: + type: string + enum: + - active + - archived + in: + type: array + items: + type: string + enum: + - active + - archived + notIn: + type: array + items: + type: string + enum: + - active + - archived diff --git a/test/unit/bugs/4557-default-parameter-values.jsx b/test/unit/bugs/4557-default-parameter-values.jsx index c2a65a37049..1fea545c46e 100644 --- a/test/unit/bugs/4557-default-parameter-values.jsx +++ b/test/unit/bugs/4557-default-parameter-values.jsx @@ -9,6 +9,7 @@ import ParameterRow from "core/components/parameter-row" import { memoizedSampleFromSchema, memoizedCreateXMLExample, + mergeJsonSchema, } from "core/plugins/json-schema-5-samples/fn/index" import makeGetSampleSchema from "core/plugins/json-schema-5-samples/fn/get-sample-schema" import makeGetJsonSampleSchema from "core/plugins/json-schema-5-samples/fn/get-json-sample-schema" @@ -103,6 +104,7 @@ describe("bug #4557: default parameter values", function () { getYamlSampleSchema: makeGetYamlSampleSchema(getSystem), getXmlSampleSchema: makeGetXmlSampleSchema(getSystem), getSampleSchema: makeGetSampleSchema(getSystem), + mergeJsonSchema, }, }) const props = { diff --git a/test/unit/components/parameter-row.jsx b/test/unit/components/parameter-row.jsx index d266cb9b527..bcf9e540a4d 100644 --- a/test/unit/components/parameter-row.jsx +++ b/test/unit/components/parameter-row.jsx @@ -9,6 +9,7 @@ import ParameterRow from "core/components/parameter-row" import { memoizedSampleFromSchema, memoizedCreateXMLExample, + mergeJsonSchema, } from "core/plugins/json-schema-5-samples/fn/index" import makeGetSampleSchema from "core/plugins/json-schema-5-samples/fn/get-sample-schema" import makeGetJsonSampleSchema from "core/plugins/json-schema-5-samples/fn/get-json-sample-schema" @@ -31,6 +32,7 @@ describe("", () => { getYamlSampleSchema: makeGetYamlSampleSchema(getSystem), getXmlSampleSchema: makeGetXmlSampleSchema(getSystem), getSampleSchema: makeGetSampleSchema(getSystem), + mergeJsonSchema, }, oas3Selectors: { activeExamplesMember: () => {} }, getConfigs: () => ({}), @@ -276,6 +278,7 @@ describe("bug #5573: zero default and example values", function () { getYamlSampleSchema: makeGetYamlSampleSchema(getSystem), getXmlSampleSchema: makeGetXmlSampleSchema(getSystem), getSampleSchema: makeGetSampleSchema(getSystem), + mergeJsonSchema, }, }) const props = { @@ -329,6 +332,7 @@ describe("bug #5573: zero default and example values", function () { getYamlSampleSchema: makeGetYamlSampleSchema(getSystem), getXmlSampleSchema: makeGetXmlSampleSchema(getSystem), getSampleSchema: makeGetSampleSchema(getSystem), + mergeJsonSchema, }, }) const props = {