Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/core/plugins/oas3/components/request-body.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,22 @@ const RequestBody = ({
const Input = getComponent("Input")

if(!isExecute) {
return <i>
Example values are not available for <code>{contentType}</code> media types.
</i>
return <div>
{ requestBodyDescription &&
<Markdown source={requestBodyDescription} />
}
<i>
Example values are not available for <code>{contentType}</code> media types.
</i>
</div>
}

return <Input type={"file"} onChange={handleFile} />
return <div>
{ requestBodyDescription &&
<Markdown source={requestBodyDescription} />
}
<Input type={"file"} onChange={handleFile} />
</div>
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/**
* @prettier
*/

describe("OpenAPI 3.0 Request Body description on file upload content types", () => {
beforeEach(() => {
cy.visit(
"/?url=/documents/features/oas3-request-body-file-upload-description.yaml"
)
})

describe("application/octet-stream (with schema)", () => {
beforeEach(() => {
cy.get("#operations-default-uploadApplicationOctetStream").click()
})

it("renders the Markdown description before Try it out is enabled", () => {
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown"
)
.should("exist")
.and("contain.text", "Upload a binary blob")
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown strong"
).should("have.text", "Upload a binary blob")
cy.get(
".opblock-section-request-body .opblock-description-wrapper i"
).should(
"have.text",
"Example values are not available for application/octet-stream media types."
)
})

it("renders the Markdown description after Try it out is enabled", () => {
cy.get(".try-out__btn").click()
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown"
)
.should("exist")
.and("contain.text", "Upload a binary blob")
cy.get(
".opblock-section-request-body .opblock-description-wrapper input"
).should("have.prop", "type", "file")
})
})

describe("image/png", () => {
beforeEach(() => {
cy.get("#operations-default-uploadImagePng").click()
})

it("renders the Markdown description before Try it out is enabled", () => {
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown"
)
.should("exist")
.and("contain.text", "Upload a PNG image")
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown em"
).should("have.text", "Upload a PNG image")
})

it("renders the Markdown description after Try it out is enabled", () => {
cy.get(".try-out__btn").click()
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown"
)
.should("exist")
.and("contain.text", "Upload a PNG image")
cy.get(
".opblock-section-request-body .opblock-description-wrapper input"
).should("have.prop", "type", "file")
})
})

describe("application/octet-stream with empty Media Type Object", () => {
beforeEach(() => {
cy.get("#operations-default-uploadApplicationOctetStreamEmpty").click()
})

it("renders the Markdown description before Try it out is enabled", () => {
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown"
)
.should("exist")
.and("contain.text", "Empty media type object")
})

it("renders the Markdown description after Try it out is enabled", () => {
cy.get(".try-out__btn").click()
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown"
)
.should("exist")
.and("contain.text", "Empty media type object")
cy.get(
".opblock-section-request-body .opblock-description-wrapper input"
).should("have.prop", "type", "file")
})
})

describe("schema type string and format binary", () => {
beforeEach(() => {
cy.get("#operations-default-uploadSchemaFormatBinary").click()
})

it("renders the Markdown description before Try it out is enabled", () => {
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown"
)
.should("exist")
.and("contain.text", "application/x-custom")
})

it("renders the Markdown description after Try it out is enabled", () => {
cy.get(".try-out__btn").click()
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown"
)
.should("exist")
.and("contain.text", "application/x-custom")
cy.get(
".opblock-section-request-body .opblock-description-wrapper input"
).should("have.prop", "type", "file")
})
})

describe("file upload without a requestBody description", () => {
beforeEach(() => {
cy.get("#operations-default-uploadWithoutDescription").click()
})

it("does not render a Markdown block when description is absent (before Try it out)", () => {
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown"
).should("not.exist")
cy.get(
".opblock-section-request-body .opblock-description-wrapper i"
).should(
"have.text",
"Example values are not available for application/octet-stream media types."
)
})

it("does not render a Markdown block when description is absent (after Try it out)", () => {
cy.get(".try-out__btn").click()
cy.get(
".opblock-section-request-body .opblock-description-wrapper .renderedMarkdown"
).should("not.exist")
cy.get(
".opblock-section-request-body .opblock-description-wrapper input"
).should("have.prop", "type", "file")
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
openapi: 3.0.4
info:
title: "Request body description on file upload content types"
description: |-
This document exercises rendering of `requestBody.description` (Markdown)
on file-upload-intended content types. The description should render both
before and after "Try it out" is enabled.
version: "1.0.0"
paths:
/upload-application-octet-stream:
post:
operationId: uploadApplicationOctetStream
requestBody:
description: |-
**Upload a binary blob** as `application/octet-stream`.
See [the docs](https://example.com) for details.
content:
application/octet-stream:
schema:
type: string
/upload-image-png:
post:
operationId: uploadImagePng
requestBody:
description: "*Upload a PNG image* of the user avatar."
content:
image/png:
schema:
type: string
/upload-application-octet-stream-empty:
post:
operationId: uploadApplicationOctetStreamEmpty
requestBody:
description: "Empty media type object with **octet-stream** description."
content:
application/octet-stream: {}
/upload-schema-format-binary:
post:
operationId: uploadSchemaFormatBinary
requestBody:
description: "`application/x-custom` with **binary** format."
content:
application/x-custom:
schema:
type: string
format: binary
/upload-without-description:
post:
operationId: uploadWithoutDescription
requestBody:
content:
application/octet-stream:
schema:
type: string
145 changes: 145 additions & 0 deletions test/unit/core/plugins/oas3/components/request-body.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
import { shallow } from "enzyme"
import { fromJS, List } from "immutable"

import RequestBody from "core/plugins/oas3/components/request-body"

describe("<RequestBody/>", function () {
const Markdown = ({ source }) => <div className="markdown-stub">{source}</div>
Markdown.propTypes = { source: PropTypes.string }
const Input = () => null
const RequestBodyEditor = () => null
const HighlightCode = () => null
const ModelExample = () => null
const ExamplesSelectValueRetainer = () => null
const Example = () => null
const ParameterIncludeEmpty = () => null

const components = {
Markdown,
Input,
RequestBodyEditor,
HighlightCode,
modelExample: ModelExample,
ExamplesSelectValueRetainer,
Example,
ParameterIncludeEmpty,
}

const getComponentStub = (name) => components[name] || null

const baseProps = {
userHasEditedBody: false,
requestBodyValue: fromJS({}),
requestBodyInclusionSetting: fromJS({}),
requestBodyErrors: List(),
getComponent: getComponentStub,
getConfigs: () => ({}),
specSelectors: {},
fn: {
isFileUploadIntended: () => true,
hasSchemaType: () => false,
getSampleSchema: () => "",
},
specPath: List(),
onChange: () => {},
onChangeIncludeEmpty: () => {},
updateActiveExamplesKey: () => {},
setRetainRequestBodyValueFlag: () => {},
oas3Actions: {},
}

it("renders the request body description for file upload content types when isExecute is true", function () {
const props = {
...baseProps,
isExecute: true,
contentType: "application/octet-stream",
requestBody: fromJS({
description: "A zip file containing files that will be unzipped",
content: {
"application/octet-stream": {
schema: { type: "string", format: "binary" },
},
},
}),
}

const wrapper = shallow(<RequestBody {...props} />)

const markdown = wrapper.find(Markdown)
expect(markdown.length).toEqual(1)
expect(markdown.prop("source")).toEqual(
"A zip file containing files that will be unzipped"
)
expect(wrapper.find(Input).length).toEqual(1)
})

it("renders the request body description for file upload content types when isExecute is false", function () {
const props = {
...baseProps,
isExecute: false,
contentType: "application/octet-stream",
requestBody: fromJS({
description: "A zip file containing files that will be unzipped",
content: {
"application/octet-stream": {
schema: { type: "string", format: "binary" },
},
},
}),
}

const wrapper = shallow(<RequestBody {...props} />)

const markdown = wrapper.find(Markdown)
expect(markdown.length).toEqual(1)
expect(markdown.prop("source")).toEqual(
"A zip file containing files that will be unzipped"
)
expect(wrapper.text()).toContain("Example values are not available")
})

it("does not render a Markdown description when the request body has none (isExecute true)", function () {
const props = {
...baseProps,
isExecute: true,
contentType: "application/octet-stream",
requestBody: fromJS({
content: {
"application/octet-stream": {
schema: { type: "string", format: "binary" },
},
},
}),
}

const wrapper = shallow(<RequestBody {...props} />)

expect(wrapper.find(Markdown).length).toEqual(0)
expect(wrapper.find(Input).length).toEqual(1)
})

it("does not render a Markdown description when the request body has none (isExecute false)", function () {
const props = {
...baseProps,
isExecute: false,
contentType: "application/octet-stream",
requestBody: fromJS({
content: {
"application/octet-stream": {
schema: { type: "string", format: "binary" },
},
},
}),
}

const wrapper = shallow(<RequestBody {...props} />)

expect(wrapper.find(Markdown).length).toEqual(0)
expect(wrapper.text()).toContain("Example values are not available")
})
})
Loading