fix(oas3): attempt to render schemas not resolved by swagger-client (#9629)
Refs #9513
This commit is contained in:
@@ -2,6 +2,7 @@ import React from "react"
|
||||
import ImmutablePureComponent from "react-immutable-pure-component"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import PropTypes from "prop-types"
|
||||
import { Map } from "immutable"
|
||||
|
||||
import RollingLoadSVG from "core/assets/rolling-load.svg"
|
||||
|
||||
@@ -55,20 +56,35 @@ export default class Model extends ImmutablePureComponent {
|
||||
const PrimitiveModel = getComponent("PrimitiveModel")
|
||||
let type = "object"
|
||||
let $$ref = schema && schema.get("$$ref")
|
||||
let $ref = schema && schema.get("$ref")
|
||||
|
||||
// If we weren't passed a `name` but have a ref, grab the name from the ref
|
||||
if ( !name && $$ref ) {
|
||||
name = this.getModelName( $$ref )
|
||||
// If we weren't passed a `name` but have a resolved ref, grab the name from the ref
|
||||
if (!name && $$ref) {
|
||||
name = this.getModelName($$ref)
|
||||
}
|
||||
// If we weren't passed a `schema` but have a ref, grab the schema from the ref
|
||||
if ( !schema && $$ref ) {
|
||||
schema = this.getRefSchema( name )
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if ($ref) {
|
||||
name = this.getModelName($ref)
|
||||
const refSchema = this.getRefSchema(name)
|
||||
if (Map.isMap(refSchema)) {
|
||||
schema = refSchema.set("$$ref", $ref)
|
||||
$$ref = $ref
|
||||
} else {
|
||||
schema = null
|
||||
name = $ref
|
||||
}
|
||||
}
|
||||
|
||||
if(!schema) {
|
||||
return <span className="model model-title">
|
||||
<span className="model-title__text">{ displayName || name }</span>
|
||||
<RollingLoadSVG height="20px" width="20px" />
|
||||
{!$ref && <RollingLoadSVG height="20px" width="20px" />}
|
||||
</span>
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ export default class ObjectModel extends Component {
|
||||
}
|
||||
</span>)
|
||||
|
||||
const allOf = specSelectors.isOAS3() ? schema.get("allOf") : null
|
||||
const anyOf = specSelectors.isOAS3() ? schema.get("anyOf") : null
|
||||
const oneOf = specSelectors.isOAS3() ? schema.get("oneOf") : null
|
||||
const not = specSelectors.isOAS3() ? schema.get("not") : null
|
||||
@@ -194,6 +195,22 @@ export default class ObjectModel extends Component {
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
{
|
||||
!allOf ? null
|
||||
: <tr>
|
||||
<td>{ "allOf ->" }</td>
|
||||
<td>
|
||||
{allOf.map((schema, k) => {
|
||||
return <div key={k}><Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
specPath={specPath.push("allOf", k)}
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
depth={ depth + 1 } /></div>
|
||||
})}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
{
|
||||
!anyOf ? null
|
||||
: <tr>
|
||||
|
||||
@@ -47,6 +47,16 @@ export const servers = onlyOAS3(() => (system) => {
|
||||
return spec.get("servers", map)
|
||||
})
|
||||
|
||||
export const findSchema = (state, schemaName) => {
|
||||
const resolvedSchema = state.getIn(
|
||||
["resolvedSubtrees", "components", "schemas", schemaName],
|
||||
null
|
||||
)
|
||||
const unresolvedSchema = state.getIn(["json", "components", "schemas", schemaName], null)
|
||||
|
||||
return resolvedSchema || unresolvedSchema || null
|
||||
}
|
||||
|
||||
export const callbacksOperations = onlyOAS3(
|
||||
(state, { callbacks, specPath }) =>
|
||||
(system) => {
|
||||
|
||||
@@ -32,6 +32,10 @@ const OAS3NullSelector = onlyOAS3(nullSelector)
|
||||
* Wrappers
|
||||
*/
|
||||
|
||||
export const findDefinition = onlyOAS3((state, schemaName) => (system) => {
|
||||
return system.getSystem().specSelectors.findSchema(schemaName)
|
||||
})
|
||||
|
||||
export const definitions = onlyOAS3(() => (system) => {
|
||||
const spec = system.getSystem().specSelectors.specJson()
|
||||
const schemas = spec.getIn(["components", "schemas"])
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("OpenAPI 3.0 complex spec with allOf and nested references", () => {
|
||||
it("should render nested references", () => {
|
||||
cy.visit("/?url=/documents/features/oas3-complex-spec.json").then(() => {
|
||||
cy.get(
|
||||
"[id='model-com.sap.ctsm.backend.core.api.study.v1.StudyAPIv1.StudyTreatments-create']"
|
||||
)
|
||||
.find("button")
|
||||
.click()
|
||||
cy.get(".property-row")
|
||||
.contains("scenario")
|
||||
.siblings()
|
||||
.as("scenarioSiblings")
|
||||
cy.get("@scenarioSiblings").find("button").click()
|
||||
cy.get("@scenarioSiblings")
|
||||
.find("span")
|
||||
.contains("scenarioID")
|
||||
.should("not.exist")
|
||||
cy.get("@scenarioSiblings")
|
||||
.find("span")
|
||||
.contains("Scenarios (for create)")
|
||||
.should("exist")
|
||||
.click()
|
||||
cy.get("@scenarioSiblings")
|
||||
.find("span")
|
||||
.contains("scenarioID")
|
||||
.should("exist")
|
||||
cy.get("@scenarioSiblings")
|
||||
.find("span")
|
||||
.contains("#/components/schemas/unresolvedRef")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
||||
})
|
||||
62964
test/e2e-cypress/static/documents/features/oas3-complex-spec.json
Normal file
62964
test/e2e-cypress/static/documents/features/oas3-complex-spec.json
Normal file
File diff suppressed because it is too large
Load Diff
62
test/unit/core/plugins/oas3/selectors.js
Normal file
62
test/unit/core/plugins/oas3/selectors.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import { fromJS } from "immutable"
|
||||
import { findSchema } from "core/plugins/oas3/spec-extensions/selectors"
|
||||
|
||||
describe("findSchema", function () {
|
||||
const state = fromJS({
|
||||
resolvedSubtrees: {
|
||||
components: {
|
||||
schemas: {
|
||||
resolvedSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
name: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
json: {
|
||||
components: {
|
||||
schemas: {
|
||||
unresolvedSchema: {
|
||||
$ref: "#/components/schemas/resolvedSchema",
|
||||
},
|
||||
resolvedSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
name: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
it("should get an unresolved schema", function () {
|
||||
const result = findSchema(state, "unresolvedSchema")
|
||||
|
||||
expect(result).toEqual(
|
||||
state.getIn(["json", "components", "schemas", "unresolvedSchema"])
|
||||
)
|
||||
})
|
||||
|
||||
it("should get a resolved schema", function () {
|
||||
const result = findSchema(state, "resolvedSchema")
|
||||
|
||||
expect(result).toEqual(
|
||||
state.getIn([
|
||||
"resolvedSubtrees",
|
||||
"components",
|
||||
"schemas",
|
||||
"resolvedSchema",
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user