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:
Andreas Grub
2021-06-23 00:33:57 +02:00
committed by GitHub
parent 1032d927a5
commit 13c110a6fe
3 changed files with 225 additions and 2 deletions

View File

@@ -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>
} }

View File

@@ -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

View 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")
})
})
})