feat(oas31): display file upload input when contentMediaType or contentEncoding is present (#10412)

Refs #9278
This commit is contained in:
Oliwia Rogala
2025-04-11 15:38:35 +02:00
committed by GitHub
parent c29e7126c9
commit 26967308e9
3 changed files with 146 additions and 1 deletions

View File

@@ -1,12 +1,45 @@
/** /**
* @prettier * @prettier
*/ */
import { Map } from "immutable"
import isPlainObject from "lodash/isPlainObject"
export const makeIsFileUploadIntended = (getSystem) => { export const makeIsFileUploadIntended = (getSystem) => {
const isFileUploadIntended = (schema, mediaType = null) => { const isFileUploadIntended = (schema, mediaType = null) => {
const { fn } = getSystem() const { fn } = getSystem()
return fn.isFileUploadIntendedOAS30(schema, mediaType) /**
* Return `true` early if the media type indicates a file upload
* or if a combination of type: `string` and format: `binary/byte` is detected.
* This ensures support for empty Media Type Objects,
* as the schema check is performed later.
*/
const isFileUploadIntendedOAS30 = fn.isFileUploadIntendedOAS30(
schema,
mediaType
)
if (isFileUploadIntendedOAS30) {
return true
}
const isSchemaImmutable = Map.isMap(schema)
if (!isSchemaImmutable && !isPlainObject(schema)) {
return false
}
const contentMediaType = isSchemaImmutable
? schema.get("contentMediaType")
: schema.contentMediaType
const contentEncoding = isSchemaImmutable
? schema.get("contentEncoding")
: schema.contentEncoding
return (
(typeof contentMediaType === "string" && contentMediaType !== "") ||
(typeof contentEncoding === "string" && contentEncoding !== "")
)
} }
return isFileUploadIntended return isFileUploadIntended

View File

@@ -199,6 +199,50 @@ describe("OpenAPI 3.1 Request Body upload file button", () => {
}) })
}) })
describe("schema contentMediaType is a non-empty string", () => {
beforeEach(() => {
cy.get("#operations-default-uploadSchemaContentMediaType").click()
})
it("should display description with the correct content type", () => {
cy.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.get(".try-out__btn").click()
cy.get(
".opblock-section-request-body .opblock-description-wrapper input"
).should("have.prop", "type", "file")
})
})
describe("schema contentEncoding is a non-empty string", () => {
beforeEach(() => {
cy.get("#operations-default-uploadSchemaContentEncoding").click()
})
it("should display description with the correct content type", () => {
cy.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.get(".try-out__btn").click()
cy.get(
".opblock-section-request-body .opblock-description-wrapper input"
).should("have.prop", "type", "file")
})
})
describe("multipart/form-data object property with schema type string and format binary", () => { describe("multipart/form-data object property with schema type string and format binary", () => {
beforeEach(() => { beforeEach(() => {
cy.get("#operations-default-uploadPropertySchemaFormatBinary").click() cy.get("#operations-default-uploadPropertySchemaFormatBinary").click()
@@ -254,4 +298,30 @@ describe("OpenAPI 3.1 Request Body upload file button", () => {
).should("have.prop", "type", "file") ).should("have.prop", "type", "file")
}) })
}) })
describe("multipart/form-data object property schema has contentMediaType with non-empty string", () => {
beforeEach(() => {
cy.get("#operations-default-uploadPropertySchemaContentMediaType").click()
})
it("should display a file upload button", () => {
cy.get(".try-out__btn").click()
cy.get(
".opblock-section-request-body .opblock-description-wrapper input"
).should("have.prop", "type", "file")
})
})
describe("multipart/form-data object property schema has contentEncoding with non-empty string", () => {
beforeEach(() => {
cy.get("#operations-default-uploadPropertySchemaContentEncoding").click()
})
it("should display a file upload button", () => {
cy.get(".try-out__btn").click()
cy.get(
".opblock-section-request-body .opblock-description-wrapper input"
).should("have.prop", "type", "file")
})
})
}) })

View File

@@ -12,10 +12,14 @@ info:
* schema type is `string` and format is `binary` (no matter what content type) * schema type is `string` and format is `binary` (no matter what content type)
* schema union type includes `string` and format is `byte` (no matter what content type) * schema union type includes `string` and format is `byte` (no matter what content type)
* schema union type includes `string` and format is `binary` (no matter what content type) * schema union type includes `string` and format is `binary` (no matter what content type)
* schema `contentMediaType` is present and is a non-empty `string`
* schema `contentEncoding` is present and is a non-empty `string`
* multipart/form-data object property schema type is `string` and format is `byte` * multipart/form-data object property schema type is `string` and format is `byte`
* multipart/form-data object property schema type is `string` and format is `binary` * multipart/form-data object property schema type is `string` and format is `binary`
* multipart/form-data object property schema union type includes `string` and format is `byte` * multipart/form-data object property schema union type includes `string` and format is `byte`
* multipart/form-data object property schema union type includes `string` and format is `binary` * multipart/form-data object property schema union type includes `string` and format is `binary`
* multipart/form-data object property schema `contentMediaType` is present and is a non-empty `string`
* multipart/form-data object property schema `contentEncoding` is present and is a non-empty `string`
version: "1.0.0" version: "1.0.0"
paths: paths:
/upload-application-octet-stream: /upload-application-octet-stream:
@@ -96,6 +100,22 @@ paths:
- object - object
- string - string
format: byte format: byte
/upload-schema-contentMediaType:
post:
operationId: uploadSchemaContentMediaType
requestBody:
content:
application/x-custom:
schema:
contentMediaType: application/x-custom
/upload-schema-contentEncoding:
post:
operationId: uploadSchemaContentEncoding
requestBody:
content:
application/x-custom:
schema:
contentEncoding: base64
/upload-property-schema-format-binary: /upload-property-schema-format-binary:
post: post:
operationId: uploadPropertySchemaFormatBinary operationId: uploadPropertySchemaFormatBinary
@@ -148,3 +168,25 @@ paths:
- object - object
- string - string
format: byte format: byte
/upload-property-schema-contentMediaType:
post:
operationId: uploadPropertySchemaContentMediaType
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
file:
contentMediaType: application/x-custom
/upload-property-schema-contentEncoding:
post:
operationId: uploadPropertySchemaContentEncoding
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
file:
contentEncoding: base64