diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index 3ed208b76ec..d4c7c782b4a 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -4,6 +4,7 @@ import ImPropTypes from "react-immutable-proptypes" import cx from "classnames" import { fromJS, Seq, Iterable, List, Map } from "immutable" import { getSampleSchema, fromJSOrdered, stringify } from "core/utils" +import { isFunc } from "../utils" const getExampleComponent = ( sampleResponse, HighlightCode, getConfigs ) => { if ( @@ -100,7 +101,6 @@ export default class Response extends React.Component { const Example = getComponent("Example") - var sampleResponse var schema, specPathWithPossibleSchema const activeContentType = this.state.responseContentType || contentType @@ -118,38 +118,63 @@ export default class Response extends React.Component { specPathWithPossibleSchema = response.has("schema") ? specPath.push("schema") : specPath } + const overrideSchemaExample = (oldSchema, newExample) => { + if(newExample === undefined) + return oldSchema + + if(!oldSchema) + oldSchema = { } + + if(isFunc(oldSchema.toJS)) + oldSchema = oldSchema.toJS() + + oldSchema.example = newExample && isFunc(newExample.toJS) + ? newExample.toJS() + : newExample + return oldSchema + } + let mediaTypeExample + let shouldOverrideSchemaExample = false + let sampleSchema + let sampleGenConfig = { + includeReadOnly: true + } + // Goal: find an example value for `sampleResponse` if(isOAS3) { - const oas3SchemaForContentType = activeMediaType.get("schema", Map({})) - + sampleSchema = activeMediaType.get("schema", Map({})).toJS() if(examplesForMediaType) { const targetExamplesKey = this.getTargetExamplesKey() - const targetExample = examplesForMediaType.get(targetExamplesKey, Map({})) - sampleResponse = stringify(targetExample.get("value")) + mediaTypeExample = examplesForMediaType + .get(targetExamplesKey, Map({})) + .get("value") + if(mediaTypeExample === undefined) { + mediaTypeExample = examplesForMediaType.values().next().value + } + shouldOverrideSchemaExample = true } else if(activeMediaType.get("example") !== undefined) { // use the example key's value - sampleResponse = stringify(activeMediaType.get("example")) - } else { - // use an example value generated based on the schema - sampleResponse = getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, { - includeReadOnly: true - }) + mediaTypeExample = activeMediaType.get("example") + shouldOverrideSchemaExample = true } } else { - if(response.getIn(["examples", activeContentType])) { - sampleResponse = response.getIn(["examples", activeContentType]) - } else { - sampleResponse = schema ? getSampleSchema( - schema.toJS(), - activeContentType, - { - includeReadOnly: true, - includeWriteOnly: true // writeOnly has no filtering effect in swagger 2.0 - } - ) : null + sampleSchema = schema + sampleGenConfig = {...sampleGenConfig, includeWriteOnly: true} + const oldOASMediaTypeExample = response.getIn(["examples", activeContentType]) + if(oldOASMediaTypeExample) { + mediaTypeExample = oldOASMediaTypeExample + shouldOverrideSchemaExample = true } } + const schemaForSampleGeneration = shouldOverrideSchemaExample + ? overrideSchemaExample(sampleSchema, mediaTypeExample) + : sampleSchema + + const sampleResponse = schemaForSampleGeneration + ? getSampleSchema(schemaForSampleGeneration, activeContentType, sampleGenConfig) + : null + let example = getExampleComponent( sampleResponse, HighlightCode, getConfigs ) return ( diff --git a/test/e2e-cypress/static/documents/bugs/6442.yaml b/test/e2e-cypress/static/documents/bugs/6442.yaml new file mode 100644 index 00000000000..b8c0d9aa319 --- /dev/null +++ b/test/e2e-cypress/static/documents/bugs/6442.yaml @@ -0,0 +1,52 @@ +openapi: 3.0.1 +info: + title: Example Swagger + version: '1.0' +servers: + - url: /api/v1 +paths: + /xmlTest: + get: + summary: subscribes to a siri vm stream + operationId: xmlTest + parameters: [] + responses: + '200': + description: Simple example + content: + application/xml: + schema: + type: object + xml: + name: root + properties: + x: + type: string + example: + x: what the f + examples: + x2: + summary: "xml not rendered via 'examples' keyword" + value: + x: should be xml + /xmlTest2: + get: + summary: subscribes to a siri vm stream + operationId: xmlTest2 + parameters: [] + responses: + '200': + description: Simple example + content: + application/xml: + schema: + type: object + xml: + name: root + properties: + x: + type: string + example: + x: what the f + example: + x: should be xml \ No newline at end of file diff --git a/test/e2e-cypress/tests/bugs/6442.js b/test/e2e-cypress/tests/bugs/6442.js new file mode 100644 index 00000000000..206055ab0b3 --- /dev/null +++ b/test/e2e-cypress/tests/bugs/6442.js @@ -0,0 +1,33 @@ +describe("#6442: 'Examples' keyword definitions can not be rendered as xml", () => { + it("should render response examples accourdingly to content-type xml", () => { + const xmlIndicator = "should be xml" + + cy + .visit("?url=/documents/bugs/6442.yaml") + .get("#operations-default-xmlTest") + .click() + .get(".responses-wrapper") + .within(() => { + cy + .get(".microlight") + .should("include.text", xmlIndicator) + }) + }) +}) + +describe("#6442: 'Example' keyword definitions can not be rendered as xml", () => { + it("should render response examples accourdingly to content-type xml", () => { + const xmlIndicator = "should be xml" + + cy + .visit("?url=/documents/bugs/6442.yaml") + .get("#operations-default-xmlTest2") + .click() + .get(".responses-wrapper") + .within(() => { + cy + .get(".microlight") + .should("include.text", xmlIndicator) + }) + }) +})