feat(oas3): Show file upload for schema binary format (#7325)
* fix(ux): display actual content type instead of hard-coded application/octet-stream * feat(ux): show file upload when schema has "format: binary", fixes #5636 * feat(ux): show file upload when schema has "format: base64" According to https://github.com/swagger-api/swagger-ui/pull/7325#issuecomment-861684260 the uploaded file should be converted to base64 automatically. * feat(ux): add cypress tests for displaying an upload button
This commit is contained in:
@@ -107,18 +107,22 @@ const RequestBody = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isObjectContent = mediaTypeValue.getIn(["schema", "type"]) === "object"
|
const isObjectContent = mediaTypeValue.getIn(["schema", "type"]) === "object"
|
||||||
|
const isBinaryFormat = mediaTypeValue.getIn(["schema", "format"]) === "binary"
|
||||||
|
const isBase64Format = mediaTypeValue.getIn(["schema", "format"]) === "base64"
|
||||||
|
|
||||||
if(
|
if(
|
||||||
contentType === "application/octet-stream"
|
contentType === "application/octet-stream"
|
||||||
|| contentType.indexOf("image/") === 0
|
|| contentType.indexOf("image/") === 0
|
||||||
|| contentType.indexOf("audio/") === 0
|
|| contentType.indexOf("audio/") === 0
|
||||||
|| contentType.indexOf("video/") === 0
|
|| contentType.indexOf("video/") === 0
|
||||||
|
|| isBinaryFormat
|
||||||
|
|| isBase64Format
|
||||||
) {
|
) {
|
||||||
const Input = getComponent("Input")
|
const Input = getComponent("Input")
|
||||||
|
|
||||||
if(!isExecute) {
|
if(!isExecute) {
|
||||||
return <i>
|
return <i>
|
||||||
Example values are not available for <code>application/octet-stream</code> media types.
|
Example values are not available for <code>{contentType}</code> media types.
|
||||||
</i>
|
</i>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
openapi: 3.0.0
|
||||||
|
info:
|
||||||
|
title: "Request body file upload"
|
||||||
|
description: |-
|
||||||
|
This document has examples for examining the `schema` or content type for request bodies requiring a file upload
|
||||||
|
* `application/octect-stream` content type (no matter what schema format)
|
||||||
|
* `audio/*` content type (no matter what schema format)
|
||||||
|
* `image/*` content type (no matter what schema format)
|
||||||
|
* `video/*` content type (no matter what schema format)
|
||||||
|
* schema format is `base64` (no matter what content type)
|
||||||
|
* schema format is `binary` (no matter what content type)
|
||||||
|
version: "1.0.0"
|
||||||
|
paths:
|
||||||
|
/upload-application-octet-stream:
|
||||||
|
post:
|
||||||
|
operationId: uploadApplicationOctetStream
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/octet-stream:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
text/plain:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
/upload-image-png:
|
||||||
|
post:
|
||||||
|
operationId: uploadImagePng
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
image/png:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
text/plain:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
/upload-audio-wav:
|
||||||
|
post:
|
||||||
|
operationId: uploadAudioWav
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
audio/wav:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
text/plain:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
/upload-video-mpeg:
|
||||||
|
post:
|
||||||
|
operationId: uploadVideoMpeg
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
video/mpeg:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
text/plain:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
/upload-schema-format-binary:
|
||||||
|
post:
|
||||||
|
operationId: uploadSchemaFormatBinary
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/x-custom:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
text/plain:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
/upload-schema-format-base64:
|
||||||
|
post:
|
||||||
|
operationId: uploadSchemaFormatBase64
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/x-custom:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: base64
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
text/plain:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
114
test/e2e-cypress/tests/features/request-body-upload-file.js
Normal file
114
test/e2e-cypress/tests/features/request-body-upload-file.js
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
|
||||||
|
describe("OpenAPI 3.0 Request Body upload file button", () => {
|
||||||
|
describe("application/octet-stream", () => {
|
||||||
|
it("should display description with the correct content type", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadApplicationOctetStream")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||||
|
.should("have.text", "Example values are not available for application/octet-stream media types.")
|
||||||
|
})
|
||||||
|
it("should display a file upload button", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadApplicationOctetStream")
|
||||||
|
.click()
|
||||||
|
.get(".try-out__btn")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||||
|
.should("have.prop", "type", "file")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe("image/png", () => {
|
||||||
|
it("should display description with the correct content type", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadImagePng")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||||
|
.should("have.text", "Example values are not available for image/png media types.")
|
||||||
|
})
|
||||||
|
it("should display a file upload button", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadApplicationOctetStream")
|
||||||
|
.click()
|
||||||
|
.get(".try-out__btn")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||||
|
.should("have.prop", "type", "file")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe("audio/wav", () => {
|
||||||
|
it("should display description with the correct content type", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadAudioWav")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||||
|
.should("have.text", "Example values are not available for audio/wav media types.")
|
||||||
|
})
|
||||||
|
it("should display a file upload button", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadApplicationOctetStream")
|
||||||
|
.click()
|
||||||
|
.get(".try-out__btn")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||||
|
.should("have.prop", "type", "file")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe("video/mpeg", () => {
|
||||||
|
it("should display description with the correct content type", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadVideoMpeg")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||||
|
.should("have.text", "Example values are not available for video/mpeg media types.")
|
||||||
|
})
|
||||||
|
it("should display a file upload button", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadApplicationOctetStream")
|
||||||
|
.click()
|
||||||
|
.get(".try-out__btn")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||||
|
.should("have.prop", "type", "file")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe("schema format binary", () => {
|
||||||
|
it("should display description with the correct content type", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadSchemaFormatBinary")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||||
|
.should("have.text", "Example values are not available for application/x-custom media types.")
|
||||||
|
})
|
||||||
|
it("should display a file upload button", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadSchemaFormatBinary")
|
||||||
|
.click()
|
||||||
|
.get(".try-out__btn")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||||
|
.should("have.prop", "type", "file")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe("schema format base64", () => {
|
||||||
|
it("should display description with the correct content type", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadSchemaFormatBase64")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||||
|
.should("have.text", "Example values are not available for application/x-custom media types.")
|
||||||
|
})
|
||||||
|
it("should display a file upload button", () => {
|
||||||
|
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||||
|
.get("#operations-default-uploadSchemaFormatBinary")
|
||||||
|
.click()
|
||||||
|
.get(".try-out__btn")
|
||||||
|
.click()
|
||||||
|
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||||
|
.should("have.prop", "type", "file")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user