From a13ac1ebe8203b2d9fd8837e4b93142bea8cc5e8 Mon Sep 17 00:00:00 2001 From: mathis-m Date: Fri, 2 Oct 2020 13:16:06 +0200 Subject: [PATCH 01/14] response sample generation should take content type into consideration for stringify --- src/core/components/response.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index 2e078c99dd6..ef25ad5098a 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -125,7 +125,10 @@ export default class Response extends React.Component { if(examplesForMediaType) { const targetExamplesKey = this.getTargetExamplesKey() const targetExample = examplesForMediaType.get(targetExamplesKey, Map({})) - sampleResponse = stringify(targetExample.get("value")) + const sampleSchema = {...schema, example: targetExample.get("value").toJS()} + sampleResponse = getSampleSchema(sampleSchema, this.state.responseContentType, { + includeReadOnly: true + }) } else if(activeMediaType.get("example") !== undefined) { // use the example key's value sampleResponse = stringify(activeMediaType.get("example")) From 6c6f11af96104cd25d9d82a5af6595a7492da3b6 Mon Sep 17 00:00:00 2001 From: mathis-m Date: Fri, 2 Oct 2020 15:30:52 +0200 Subject: [PATCH 02/14] fix bad if and refactor cases --- src/core/components/response.jsx | 33 +++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index ef25ad5098a..310ae5e1ff6 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -122,22 +122,33 @@ export default class Response extends React.Component { if(isOAS3) { const oas3SchemaForContentType = activeMediaType.get("schema", Map({})) + const getSchemaFromExample = (targetExample) => { + const sampleSchema = { ...schema } + sampleSchema.example = typeof targetExample.toJS === "function" + ? targetExample.toJS() + : targetExample + return sampleSchema + } + + let targetExample; + let useoas3Schema = true; if(examplesForMediaType) { const targetExamplesKey = this.getTargetExamplesKey() - const targetExample = examplesForMediaType.get(targetExamplesKey, Map({})) - const sampleSchema = {...schema, example: targetExample.get("value").toJS()} - sampleResponse = getSampleSchema(sampleSchema, this.state.responseContentType, { - includeReadOnly: true - }) + targetExample = examplesForMediaType + .get(targetExamplesKey, Map({})) + .get("value") + useoas3Schema = false; } 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 - }) + targetExample = activeMediaType.get("example") + useoas3Schema = false; } + const sampleSchema = useoas3Schema + ? oas3SchemaForContentType.toJS() + : getSchemaFromExample(targetExample) + sampleResponse = getSampleSchema(sampleSchema, this.state.responseContentType, { + includeReadOnly: true + }) } else { if(response.getIn(["examples", activeContentType])) { sampleResponse = response.getIn(["examples", activeContentType]) From 78d99cb7e092018d4cef5d6207239a1f9a074ded Mon Sep 17 00:00:00 2001 From: mathis-m Date: Fri, 2 Oct 2020 15:42:49 +0200 Subject: [PATCH 03/14] add guard --- src/core/components/response.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index 310ae5e1ff6..6577342850c 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -123,6 +123,8 @@ export default class Response extends React.Component { const oas3SchemaForContentType = activeMediaType.get("schema", Map({})) const getSchemaFromExample = (targetExample) => { + if(targetExample == undefined) + return schema const sampleSchema = { ...schema } sampleSchema.example = typeof targetExample.toJS === "function" ? targetExample.toJS() From da8ff17167c368a2214178edee0af0aa6d56b93c Mon Sep 17 00:00:00 2001 From: mathis-m Date: Fri, 2 Oct 2020 16:21:56 +0200 Subject: [PATCH 04/14] add response example should respect media type test --- .../static/documents/bugs/6442.yaml | 52 +++++++++++++++++++ test/e2e-cypress/tests/bugs/6442.js | 33 ++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 test/e2e-cypress/static/documents/bugs/6442.yaml create mode 100644 test/e2e-cypress/tests/bugs/6442.js 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) + }) + }) +}) From 032996a9c4631fd76ce7ee27fe506a33bea83e3b Mon Sep 17 00:00:00 2001 From: mathis-m Date: Sat, 3 Oct 2020 15:59:40 +0200 Subject: [PATCH 05/14] fix lint --- src/core/components/response.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index 6577342850c..ade57d5681f 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -132,18 +132,18 @@ export default class Response extends React.Component { return sampleSchema } - let targetExample; - let useoas3Schema = true; + let targetExample + let useoas3Schema = true if(examplesForMediaType) { const targetExamplesKey = this.getTargetExamplesKey() targetExample = examplesForMediaType .get(targetExamplesKey, Map({})) .get("value") - useoas3Schema = false; + useoas3Schema = false } else if(activeMediaType.get("example") !== undefined) { // use the example key's value targetExample = activeMediaType.get("example") - useoas3Schema = false; + useoas3Schema = false } const sampleSchema = useoas3Schema ? oas3SchemaForContentType.toJS() From f3d2cde11b77d41d78822bb486b61306d3631e65 Mon Sep 17 00:00:00 2001 From: mathis-m Date: Sun, 4 Oct 2020 23:36:21 +0200 Subject: [PATCH 06/14] refactor and use oas3 schema --- src/core/components/response.jsx | 36 +++++++++++++++++--------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index ade57d5681f..5fec8663d23 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -122,33 +122,35 @@ export default class Response extends React.Component { if(isOAS3) { const oas3SchemaForContentType = activeMediaType.get("schema", Map({})) - const getSchemaFromExample = (targetExample) => { - if(targetExample == undefined) + const overrideSchemaExample = (oldSchema, newExample) => { + if(newExample == undefined) return schema - const sampleSchema = { ...schema } - sampleSchema.example = typeof targetExample.toJS === "function" - ? targetExample.toJS() - : targetExample - return sampleSchema + oldSchema.example = typeof newExample.toJS === "function" + ? newExample.toJS() + : newExample + return oldSchema } - let targetExample - let useoas3Schema = true + let mediaTypeExample + let shouldOverrideSchemaExample = true + if(examplesForMediaType) { const targetExamplesKey = this.getTargetExamplesKey() - targetExample = examplesForMediaType + mediaTypeExample = examplesForMediaType .get(targetExamplesKey, Map({})) .get("value") - useoas3Schema = false + shouldOverrideSchemaExample = false } else if(activeMediaType.get("example") !== undefined) { // use the example key's value - targetExample = activeMediaType.get("example") - useoas3Schema = false + mediaTypeExample = activeMediaType.get("example") + shouldOverrideSchemaExample = false } - const sampleSchema = useoas3Schema - ? oas3SchemaForContentType.toJS() - : getSchemaFromExample(targetExample) - sampleResponse = getSampleSchema(sampleSchema, this.state.responseContentType, { + + const schemaJS = oas3SchemaForContentType.toJS(); + const schemaForSampleGeneration = shouldOverrideSchemaExample + ? schemaJS + : overrideSchemaExample(schemaJS, mediaTypeExample) + sampleResponse = getSampleSchema(schemaForSampleGeneration, this.state.responseContentType, { includeReadOnly: true }) } else { From 8c5e67ce62c3aa2d5f35dca98c75550ed54beb4b Mon Sep 17 00:00:00 2001 From: mathis-m Date: Sun, 4 Oct 2020 23:37:33 +0200 Subject: [PATCH 07/14] use oas3 schema instead --- src/core/components/response.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index 5fec8663d23..f57163e3e98 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -124,7 +124,7 @@ export default class Response extends React.Component { const overrideSchemaExample = (oldSchema, newExample) => { if(newExample == undefined) - return schema + return oldSchema oldSchema.example = typeof newExample.toJS === "function" ? newExample.toJS() : newExample From 1cc4071cb52eba2f8ee4813a45d996dca90d1631 Mon Sep 17 00:00:00 2001 From: mathis-m Date: Sun, 4 Oct 2020 23:42:17 +0200 Subject: [PATCH 08/14] use state or prop content-type --- src/core/components/response.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index f57163e3e98..d4103aa9044 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -150,7 +150,7 @@ export default class Response extends React.Component { const schemaForSampleGeneration = shouldOverrideSchemaExample ? schemaJS : overrideSchemaExample(schemaJS, mediaTypeExample) - sampleResponse = getSampleSchema(schemaForSampleGeneration, this.state.responseContentType, { + sampleResponse = getSampleSchema(schemaForSampleGeneration, activeContentType, { includeReadOnly: true }) } else { From 408fc251f3c2a62c834b613aea0df111a33bdff8 Mon Sep 17 00:00:00 2001 From: mathis-m Date: Mon, 5 Oct 2020 00:07:15 +0200 Subject: [PATCH 09/14] < oas 3 should also use schema and response example --- src/core/components/response.jsx | 68 +++++++++++++++----------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index d4103aa9044..27caac3edca 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -100,7 +100,6 @@ export default class Response extends React.Component { const Example = getComponent("Example") - var sampleResponse var schema, specPathWithPossibleSchema const activeContentType = this.state.responseContentType || contentType @@ -118,56 +117,53 @@ export default class Response extends React.Component { specPathWithPossibleSchema = response.has("schema") ? specPath.push("schema") : specPath } + const overrideSchemaExample = (oldSchema, newExample) => { + if(!oldSchema) + return null + oldSchema.example = typeof newExample.toJS === "function" + ? 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({})) - - const overrideSchemaExample = (oldSchema, newExample) => { - if(newExample == undefined) - return oldSchema - oldSchema.example = typeof newExample.toJS === "function" - ? newExample.toJS() - : newExample - return oldSchema - } - - let mediaTypeExample - let shouldOverrideSchemaExample = true - + sampleSchema = activeMediaType.get("schema", Map({})).toJS() if(examplesForMediaType) { const targetExamplesKey = this.getTargetExamplesKey() mediaTypeExample = examplesForMediaType .get(targetExamplesKey, Map({})) .get("value") - shouldOverrideSchemaExample = false + shouldOverrideSchemaExample = true } else if(activeMediaType.get("example") !== undefined) { // use the example key's value mediaTypeExample = activeMediaType.get("example") - shouldOverrideSchemaExample = false + shouldOverrideSchemaExample = true } - - const schemaJS = oas3SchemaForContentType.toJS(); - const schemaForSampleGeneration = shouldOverrideSchemaExample - ? schemaJS - : overrideSchemaExample(schemaJS, mediaTypeExample) - sampleResponse = getSampleSchema(schemaForSampleGeneration, activeContentType, { - includeReadOnly: 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 ( From 6515294aab3091cdf8da9ee2016f79a9b93d99ac Mon Sep 17 00:00:00 2001 From: mathis-m Date: Mon, 5 Oct 2020 11:32:38 +0200 Subject: [PATCH 10/14] fix switch to first if not existing --- src/core/components/response.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index 27caac3edca..6f5e5e69bc6 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -120,6 +120,8 @@ export default class Response extends React.Component { const overrideSchemaExample = (oldSchema, newExample) => { if(!oldSchema) return null + if(newExample === undefined) + return oldSchema oldSchema.example = typeof newExample.toJS === "function" ? newExample.toJS() : newExample From b48f4121eafaedccc24092538359b41a806d4726 Mon Sep 17 00:00:00 2001 From: mathis-m Date: Mon, 5 Oct 2020 11:47:10 +0200 Subject: [PATCH 11/14] default to first example in case target key was not found --- src/core/components/response.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index 6f5e5e69bc6..5e9e4e889c1 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -142,6 +142,9 @@ export default class Response extends React.Component { 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 From 4e9e31df5a9f0898cc57158c2ad81fbc9b6fbc0a Mon Sep 17 00:00:00 2001 From: mathis-m Date: Mon, 5 Oct 2020 15:13:29 +0200 Subject: [PATCH 12/14] use empty schema when no schema defined for sample gen util --- src/core/components/response.jsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index 5e9e4e889c1..d6957ab77b9 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -118,10 +118,12 @@ export default class Response extends React.Component { } const overrideSchemaExample = (oldSchema, newExample) => { - if(!oldSchema) - return null if(newExample === undefined) return oldSchema + + if(!oldSchema) + oldSchema = { } + oldSchema.example = typeof newExample.toJS === "function" ? newExample.toJS() : newExample @@ -162,8 +164,8 @@ export default class Response extends React.Component { } const schemaForSampleGeneration = shouldOverrideSchemaExample - ? overrideSchemaExample(sampleSchema, mediaTypeExample) - : sampleSchema + ? overrideSchemaExample(sampleSchema, mediaTypeExample) + : sampleSchema const sampleResponse = schemaForSampleGeneration ? getSampleSchema(schemaForSampleGeneration, activeContentType, sampleGenConfig) From 3db8f6258a7ad11d3f7e67ce2bf1c0977ce4b754 Mon Sep 17 00:00:00 2001 From: mathis-m Date: Thu, 8 Oct 2020 08:42:49 +0200 Subject: [PATCH 13/14] us isFunc instead. should pass json instead of map upsi fixes ci --- src/core/components/response.jsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index d6957ab77b9..61e8ec7baac 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 ( @@ -124,7 +125,10 @@ export default class Response extends React.Component { if(!oldSchema) oldSchema = { } - oldSchema.example = typeof newExample.toJS === "function" + if(isFunc(oldSchema.toJS)) + oldSchema = oldSchema.toJS() + + oldSchema.example = newExample && isFunc(newExample.toJS) ? newExample.toJS() : newExample return oldSchema @@ -157,6 +161,7 @@ export default class Response extends React.Component { sampleSchema = schema sampleGenConfig = {...sampleGenConfig, includeWriteOnly: true} const oldOASMediaTypeExample = response.getIn(["examples", activeContentType]) + debugger if(oldOASMediaTypeExample) { mediaTypeExample = oldOASMediaTypeExample shouldOverrideSchemaExample = true From 23dabe762b4e967bc8eac67117d7c513047e8bac Mon Sep 17 00:00:00 2001 From: mathis-m Date: Thu, 8 Oct 2020 09:11:58 +0200 Subject: [PATCH 14/14] remove debugger --- src/core/components/response.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index 61e8ec7baac..8b913dfd55c 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -161,7 +161,6 @@ export default class Response extends React.Component { sampleSchema = schema sampleGenConfig = {...sampleGenConfig, includeWriteOnly: true} const oldOASMediaTypeExample = response.getIn(["examples", activeContentType]) - debugger if(oldOASMediaTypeExample) { mediaTypeExample = oldOASMediaTypeExample shouldOverrideSchemaExample = true