feat(RequestBody): set default true for 'send empty value' (#6228)
This commit is contained in:
@@ -1,22 +1,53 @@
|
||||
import React from "react"
|
||||
import React, { Component } from "react"
|
||||
import cx from "classnames"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export const ParameterIncludeEmpty = ({ isIncluded, onChange, isDisabled }) => {
|
||||
const onCheckboxChange = e => {
|
||||
onChange(e.target.checked)
|
||||
}
|
||||
return <label className={cx("parameter__empty_value_toggle", {
|
||||
"disabled": isDisabled
|
||||
})}>
|
||||
<input type="checkbox" disabled={isDisabled} checked={!isDisabled && isIncluded} onChange={onCheckboxChange} />
|
||||
Send empty value
|
||||
</label>
|
||||
}
|
||||
ParameterIncludeEmpty.propTypes = {
|
||||
|
||||
const noop = () => { }
|
||||
|
||||
const ParameterIncludeEmptyPropTypes = {
|
||||
isIncluded: PropTypes.bool.isRequired,
|
||||
isDisabled: PropTypes.bool.isRequired,
|
||||
isIncludedOptions: PropTypes.object,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
export default ParameterIncludeEmpty
|
||||
const ParameterIncludeEmptyDefaultProps = {
|
||||
onChange: noop,
|
||||
isIncludedOptions: {},
|
||||
}
|
||||
export default class ParameterIncludeEmpty extends Component {
|
||||
static propTypes = ParameterIncludeEmptyPropTypes
|
||||
static defaultProps = ParameterIncludeEmptyDefaultProps
|
||||
|
||||
componentDidMount() {
|
||||
const { isIncludedOptions, onChange } = this.props
|
||||
const { shouldDispatchInit, defaultValue } = isIncludedOptions
|
||||
if (shouldDispatchInit) {
|
||||
onChange(defaultValue)
|
||||
}
|
||||
}
|
||||
|
||||
onCheckboxChange = e => {
|
||||
const { onChange } = this.props
|
||||
onChange(e.target.checked)
|
||||
}
|
||||
|
||||
render() {
|
||||
let { isIncluded, isDisabled } = this.props
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label className={cx("parameter__empty_value_toggle", {
|
||||
"disabled": isDisabled
|
||||
})}>
|
||||
<input type="checkbox"
|
||||
disabled={isDisabled}
|
||||
checked={!isDisabled && isIncluded}
|
||||
onChange={this.onCheckboxChange} />
|
||||
Send empty value
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,19 @@ const RequestBody = ({
|
||||
const handleFile = (e) => {
|
||||
onChange(e.target.files[0])
|
||||
}
|
||||
const setIsIncludedOptions = (key) => {
|
||||
let options = {
|
||||
key,
|
||||
shouldDispatchInit: false,
|
||||
defaultValue: true
|
||||
}
|
||||
let currentInclusion = requestBodyInclusionSetting.get(key, "no value")
|
||||
if (currentInclusion === "no value") {
|
||||
options.shouldDispatchInit = true
|
||||
// future: can get/set defaultValue from a config setting
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
const Markdown = getComponent("Markdown", true)
|
||||
const ModelExample = getComponent("modelExample")
|
||||
@@ -173,7 +186,8 @@ const RequestBody = ({
|
||||
{required ? null : (
|
||||
<ParameterIncludeEmpty
|
||||
onChange={(value) => onChangeIncludeEmpty(key, value)}
|
||||
isIncluded={requestBodyInclusionSetting.get(key)}
|
||||
isIncluded={requestBodyInclusionSetting.get(key) || false}
|
||||
isIncludedOptions={setIsIncludedOptions(key)}
|
||||
isDisabled={!isEmptyValue(currentValue)}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,418 @@
|
||||
openapi: 3.0.2
|
||||
servers:
|
||||
- url: /v3
|
||||
info:
|
||||
description: |-
|
||||
This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about
|
||||
Swagger at [http://swagger.io](http://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!
|
||||
You can now help us improve the API whether it's by making changes to the definition itself or to the code.
|
||||
That way, with time, we can improve the API in general, and expose some of the new features in OAS3.
|
||||
|
||||
Some useful links:
|
||||
- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
|
||||
- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)
|
||||
version: 1.0.5-SNAPSHOT
|
||||
title: Swagger Petstore - OpenAPI 3.0
|
||||
termsOfService: 'http://swagger.io/terms/'
|
||||
contact:
|
||||
email: apiteam@swagger.io
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
|
||||
tags:
|
||||
- name: pet
|
||||
description: Everything about your Pets
|
||||
externalDocs:
|
||||
description: Find out more
|
||||
url: 'http://swagger.io'
|
||||
paths:
|
||||
/pet:
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Add a new pet to the store
|
||||
description: Add a new pet to the store
|
||||
operationId: addPet
|
||||
responses:
|
||||
'200':
|
||||
description: Successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'405':
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
description: Create a new pet in the store
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
put:
|
||||
tags:
|
||||
- pet
|
||||
summary: Update an existing pet
|
||||
description: Update an existing pet by Id
|
||||
operationId: updatePet
|
||||
responses:
|
||||
'200':
|
||||
description: Successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Pet not found
|
||||
'405':
|
||||
description: Validation exception
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
description: Update an existent pet in the store
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
/pet/findByStatus:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by status
|
||||
description: Multiple status values can be provided with comma separated strings
|
||||
operationId: findPetsByStatus
|
||||
parameters:
|
||||
- name: status
|
||||
in: query
|
||||
description: Status values that need to be considered for filter
|
||||
required: false
|
||||
explode: true
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- available
|
||||
- pending
|
||||
- sold
|
||||
default: available
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid status value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
/pet/findByTags:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by tags
|
||||
description: >-
|
||||
Multiple tags can be provided with comma separated strings. Use tag1,
|
||||
tag2, tag3 for testing.
|
||||
operationId: findPetsByTags
|
||||
parameters:
|
||||
- name: tags
|
||||
in: query
|
||||
description: Tags to filter by
|
||||
required: false
|
||||
explode: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid tag value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
'/pet/{petId}':
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Find pet by ID
|
||||
description: Returns a single pet
|
||||
operationId: getPetById
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet to return
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Pet not found
|
||||
security:
|
||||
- api_key: []
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Updates a pet in the store with form data
|
||||
description: ''
|
||||
operationId: updatePetWithForm
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet that needs to be updated
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
- name: name
|
||||
in: query
|
||||
description: Name of pet that needs to be updated
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: status
|
||||
in: query
|
||||
description: Status of pet that needs to be updated
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'405':
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
delete:
|
||||
tags:
|
||||
- pet
|
||||
summary: Deletes a pet
|
||||
description: ''
|
||||
operationId: deletePet
|
||||
parameters:
|
||||
- name: api_key
|
||||
in: header
|
||||
description: ''
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: petId
|
||||
in: path
|
||||
description: Pet id to delete
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid pet value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
'/pet/{petId}/uploadImage':
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: uploads an image
|
||||
description: ''
|
||||
operationId: uploadFile
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet to update
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
- name: additionalMetadata
|
||||
in: query
|
||||
description: Additional Metadata
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
externalDocs:
|
||||
description: Find out more about Swagger
|
||||
url: 'http://swagger.io'
|
||||
components:
|
||||
schemas:
|
||||
Category:
|
||||
x-swagger-router-model: io.swagger.petstore.model.Category
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1
|
||||
name:
|
||||
type: string
|
||||
example: Dogs
|
||||
xml:
|
||||
name: category
|
||||
type: object
|
||||
Tag:
|
||||
x-swagger-router-model: io.swagger.petstore.model.Tag
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
xml:
|
||||
name: tag
|
||||
type: object
|
||||
Pet:
|
||||
x-swagger-router-model: io.swagger.petstore.model.Pet
|
||||
required:
|
||||
- name
|
||||
- photoUrls
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 10
|
||||
name:
|
||||
type: string
|
||||
example: doggie
|
||||
category:
|
||||
$ref: '#/components/schemas/Category'
|
||||
photoUrls:
|
||||
type: array
|
||||
xml:
|
||||
wrapped: true
|
||||
items:
|
||||
type: string
|
||||
xml:
|
||||
name: photoUrl
|
||||
tags:
|
||||
type: array
|
||||
xml:
|
||||
wrapped: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Tag'
|
||||
xml:
|
||||
name: tag
|
||||
status:
|
||||
type: string
|
||||
description: pet status in the store
|
||||
enum:
|
||||
- available
|
||||
- pending
|
||||
- sold
|
||||
xml:
|
||||
name: pet
|
||||
type: object
|
||||
ApiResponse:
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
type:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
xml:
|
||||
name: '##default'
|
||||
type: object
|
||||
requestBodies:
|
||||
Pet:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
description: Pet object that needs to be added to the store
|
||||
securitySchemes:
|
||||
petstore_auth:
|
||||
type: oauth2
|
||||
flows:
|
||||
implicit:
|
||||
authorizationUrl: 'https://petstore.swagger.io/oauth/authorize'
|
||||
scopes:
|
||||
'write:pets': modify pets in your account
|
||||
'read:pets': read your pets
|
||||
api_key:
|
||||
type: apiKey
|
||||
name: api_key
|
||||
in: header
|
||||
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("OpenAPI 3.0 Allow Empty Values in Request Body", () => {
|
||||
it("should not apply or render to required fields", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Request Body
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(2) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.should("not.exist")
|
||||
})
|
||||
|
||||
it("by default, should be checked for all non-required fields", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Request Body
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(5) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.should("be.checked")
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(6) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.should("be.checked")
|
||||
})
|
||||
|
||||
it("checkbox should be toggle-able", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Request Body
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(5) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.should("be.checked")
|
||||
.uncheck()
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(5) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.should("not.be.checked")
|
||||
})
|
||||
|
||||
it("on execute, should allow send with all empty values", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .copy-paste")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .copy-paste textarea")
|
||||
.should("contains.text", "tags=&status=")
|
||||
})
|
||||
|
||||
it("on execute, should allow send with some empty values", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Request Body
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(5) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.uncheck()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .copy-paste")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .copy-paste textarea")
|
||||
.should("contains.text", "&status=")
|
||||
.should("not.contains.text", "tags=")
|
||||
})
|
||||
|
||||
it("on execute, should allow send with skip all empty values", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Request Body
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(5) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.uncheck()
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(6) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.uncheck()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .copy-paste")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .copy-paste textarea")
|
||||
.should("not.contains.text", "tags=")
|
||||
.should("not.contains.text", "status=")
|
||||
})
|
||||
|
||||
})
|
||||
Reference in New Issue
Block a user