bug: JsonSchema components should validate schema properties exists - schema - type - format - enum bug: fix a debounce error in JsonSchema_string if value is null ft: new simplified JsonSchemaArrayItemText component test: use immutableJS for `json-schema-form` test test: add dev scripts to run `cypress open` test: new cypress `schema-form` testsbubble
@@ -39,6 +39,8 @@ | |||
"hot-e2e-cypress-server": "webpack-dev-server --config webpack/dev-e2e.babel.js --content-base test/e2e-cypress/static", | |||
"hot-e2e-selenium-server": "webpack-dev-server --config webpack/dev-e2e.babel.js --content-base test/e2e-selenium/static", | |||
"e2e-cypress": "run-p -r hot-e2e-cypress-server mock-api test-e2e-cypress", | |||
"dev-test-e2e-cypress-open": "cypress open", | |||
"dev-e2e-cypress": "run-p -r hot-e2e-cypress-server mock-api dev-e2e-cypress-open", | |||
"e2e-selenium": "run-p -r hot-e2e-selenium-server mock-api test-e2e-selenium", | |||
"open-static": "node -e \"require('open')('http://localhost:3002')\"", | |||
"security-audit": "run-s -sc security-audit:all security-audit:prod", | |||
@@ -42,7 +42,7 @@ export default class ParameterRow extends Component { | |||
if(isOAS3) { | |||
let { schema } = getParameterSchema(parameterWithMeta, { isOAS3 }) | |||
enumValue = schema.get("enum") | |||
enumValue = schema ? schema.get("enum") : undefined | |||
} else { | |||
enumValue = parameterWithMeta ? parameterWithMeta.get("enum") : undefined | |||
} | |||
@@ -59,7 +59,7 @@ export default class ParameterRow extends Component { | |||
if ( value !== undefined && value !== paramValue ) { | |||
this.onChangeWrapper(numberToString(value)) | |||
} | |||
// todo: could check if schema here; if not, do not call. impact? | |||
this.setDefaultValue() | |||
} | |||
@@ -97,17 +97,16 @@ export default class ParameterRow extends Component { | |||
let { specSelectors, pathMethod, rawParam, oas3Selectors } = this.props | |||
const paramWithMeta = specSelectors.parameterWithMetaByIdentity(pathMethod, rawParam) || Map() | |||
const { schema } = getParameterSchema(paramWithMeta, { isOAS3: specSelectors.isOAS3() }) | |||
const parameterMediaType = paramWithMeta | |||
.get("content", Map()) | |||
.keySeq() | |||
.first() | |||
const generatedSampleValue = getSampleSchema(schema.toJS(), parameterMediaType, { | |||
// getSampleSchema could return null | |||
const generatedSampleValue = schema ? getSampleSchema(schema.toJS(), parameterMediaType, { | |||
includeWriteOnly: true | |||
}) | |||
}) : null | |||
if (!paramWithMeta || paramWithMeta.get("value") !== undefined) { | |||
return | |||
@@ -121,14 +120,14 @@ export default class ParameterRow extends Component { | |||
if (specSelectors.isSwagger2()) { | |||
initialValue = paramWithMeta.get("x-example") | |||
|| paramWithMeta.getIn(["schema", "example"]) | |||
|| schema.getIn(["default"]) | |||
|| (schema && schema.getIn(["default"])) | |||
} else if (specSelectors.isOAS3()) { | |||
const currentExampleKey = oas3Selectors.activeExamplesMember(...pathMethod, "parameters", this.getParamKey()) | |||
initialValue = paramWithMeta.getIn(["examples", currentExampleKey, "value"]) | |||
|| paramWithMeta.getIn(["content", parameterMediaType, "example"]) | |||
|| paramWithMeta.get("example") | |||
|| schema.get("example") | |||
|| schema.get("default") | |||
|| (schema && schema.get("example")) | |||
|| (schema && schema.get("default")) | |||
|| paramWithMeta.get("default") // ensures support for `parameterMacro` | |||
} | |||
@@ -144,7 +143,7 @@ export default class ParameterRow extends Component { | |||
if(initialValue !== undefined) { | |||
this.onChangeWrapper(initialValue) | |||
} else if( | |||
schema.get("type") === "object" | |||
schema && schema.get("type") === "object" | |||
&& generatedSampleValue | |||
&& !paramWithMeta.get("examples") | |||
) { | |||
@@ -212,12 +211,12 @@ export default class ParameterRow extends Component { | |||
let { schema } = getParameterSchema(param, { isOAS3 }) | |||
let paramWithMeta = specSelectors.parameterWithMetaByIdentity(pathMethod, rawParam) || Map() | |||
let format = schema.get("format") | |||
let type = schema.get("type") | |||
let format = schema ? schema.get("format") : null | |||
let type = schema ? schema.get("type") : null | |||
let itemType = schema ? schema.getIn(["items", "type"]) : null | |||
let isFormData = inType === "formData" | |||
let isFormDataSupported = "FormData" in win | |||
let required = param.get("required") | |||
let itemType = schema.getIn(["items", "type"]) | |||
let value = paramWithMeta ? paramWithMeta.get("value") : "" | |||
let commonExt = showCommonExtensions ? getCommonExtensions(schema) : null | |||
@@ -229,24 +228,26 @@ export default class ParameterRow extends Component { | |||
let paramExample // undefined | |||
let isDisplayParamEnum = false | |||
if ( param !== undefined ) { | |||
if ( param !== undefined && schema ) { | |||
paramItems = schema.get("items") | |||
} | |||
if (paramItems !== undefined) { | |||
paramEnum = paramItems.get("enum") | |||
paramDefaultValue = paramItems.get("default") | |||
} else { | |||
} else if (schema) { | |||
paramEnum = schema.get("enum") | |||
} | |||
if ( paramEnum !== undefined && paramEnum.size > 0) { | |||
if ( paramEnum && paramEnum.size && paramEnum.size > 0) { | |||
isDisplayParamEnum = true | |||
} | |||
// Default and Example Value for readonly doc | |||
if ( param !== undefined ) { | |||
paramDefaultValue = schema.get("default") | |||
if (schema) { | |||
paramDefaultValue = schema.get("default") | |||
} | |||
if (paramDefaultValue === undefined) { | |||
paramDefaultValue = param.get("default") | |||
} | |||
@@ -45,37 +45,37 @@ export class JsonSchemaForm extends Component { | |||
render() { | |||
let { schema, errors, value, onChange, getComponent, fn, disabled } = this.props | |||
if(schema.toJS) | |||
schema = schema.toJS() | |||
let { type, format="" } = schema | |||
// In the json schema rendering code, we optimistically query our system for a number of components. | |||
// If the component doesn't exist, we optionally suppress these warnings. | |||
const format = schema && schema.get ? schema.get("format") : null | |||
const type = schema && schema.get ? schema.get("type") : null | |||
let getComponentSilently = (name) => getComponent(name, false, { failSilently: true }) | |||
let Comp = (format ? | |||
let Comp = type ? format ? | |||
getComponentSilently(`JsonSchema_${type}_${format}`) : | |||
getComponentSilently(`JsonSchema_${type}`)) || | |||
getComponentSilently("JsonSchema_string") | |||
getComponentSilently(`JsonSchema_${type}`) : | |||
getComponent("JsonSchema_string") | |||
if (!Comp) { | |||
Comp = getComponent("JsonSchema_string") | |||
} | |||
return <Comp { ...this.props } errors={errors} fn={fn} getComponent={getComponent} value={value} onChange={onChange} schema={schema} disabled={disabled}/> | |||
} | |||
} | |||
export class JsonSchema_string extends Component { | |||
static propTypes = JsonSchemaPropShape | |||
static defaultProps = JsonSchemaDefaultProps | |||
onChange = (e) => { | |||
const value = this.props.schema["type"] === "file" ? e.target.files[0] : e.target.value | |||
const value = this.props.schema && this.props.schema["type"] === "file" ? e.target.files[0] : e.target.value | |||
this.props.onChange(value, this.props.keyName) | |||
} | |||
onEnumChange = (val) => this.props.onChange(val) | |||
render() { | |||
let { getComponent, value, schema, errors, required, description, disabled } = this.props | |||
let enumValue = schema["enum"] | |||
const enumValue = schema && schema.get ? schema.get("enum") : null | |||
const format = schema && schema.get ? schema.get("format") : null | |||
const type = schema && schema.get ? schema.get("type") : null | |||
const schemaIn = schema && schema.get ? schema.get("in") : null | |||
if (!value) { | |||
value = "" // value should not be null; this fixes a Debounce error | |||
} | |||
errors = errors.toJS ? errors.toJS() : [] | |||
if ( enumValue ) { | |||
@@ -89,9 +89,9 @@ export class JsonSchema_string extends Component { | |||
onChange={ this.onEnumChange }/>) | |||
} | |||
const isDisabled = disabled || (schema["in"] === "formData" && !("FormData" in window)) | |||
const isDisabled = disabled || (schemaIn && schemaIn === "formData" && !("FormData" in window)) | |||
const Input = getComponent("Input") | |||
if (schema["type"] === "file") { | |||
if (type && type === "file") { | |||
return (<Input type="file" | |||
className={ errors.length ? "invalid" : ""} | |||
title={ errors.length ? errors : ""} | |||
@@ -100,7 +100,7 @@ export class JsonSchema_string extends Component { | |||
} | |||
else { | |||
return (<DebounceInput | |||
type={ schema.format === "password" ? "password" : "text" } | |||
type={ format && format === "password" ? "password" : "text" } | |||
className={ errors.length ? "invalid" : ""} | |||
title={ errors.length ? errors : ""} | |||
value={value} | |||
@@ -120,35 +120,35 @@ export class JsonSchema_array extends PureComponent { | |||
constructor(props, context) { | |||
super(props, context) | |||
this.state = { value: valueOrEmptyList(props.value)} | |||
this.state = { value: valueOrEmptyList(props.value) } | |||
} | |||
componentWillReceiveProps(props) { | |||
if(props.value !== this.state.value) | |||
this.setState({value: props.value}) | |||
this.setState({ value: props.value }) | |||
} | |||
onChange = () => this.props.onChange(this.state.value) | |||
onChange = () => { | |||
this.props.onChange(this.state.value) | |||
} | |||
onItemChange = (itemVal, i) => { | |||
this.setState(state => ({ | |||
value: state.value.set(i, itemVal) | |||
this.setState(({ value }) => ({ | |||
value: value.set(i, itemVal) | |||
}), this.onChange) | |||
} | |||
removeItem = (i) => { | |||
this.setState(state => ({ | |||
value: state.value.remove(i) | |||
this.setState(({ value }) => ({ | |||
value: value.delete(i) | |||
}), this.onChange) | |||
} | |||
addItem = () => { | |||
this.setState(state => { | |||
state.value = valueOrEmptyList(state.value) | |||
return { | |||
value: state.value.push("") | |||
} | |||
}, this.onChange) | |||
let newValue = valueOrEmptyList(this.state.value) | |||
this.setState(() => ({ | |||
value: newValue.push("") | |||
}), this.onChange) | |||
} | |||
onEnumChange = (value) => { | |||
@@ -161,69 +161,120 @@ export class JsonSchema_array extends PureComponent { | |||
let { getComponent, required, schema, errors, fn, disabled } = this.props | |||
errors = errors.toJS ? errors.toJS() : [] | |||
const value = this.state.value // expect Im List | |||
const shouldRenderValue = | |||
value && value.count && value.count() > 0 ? true : false | |||
const schemaItemsEnum = schema.getIn(["items", "enum"]) | |||
const schemaItemsType = schema.getIn(["items", "type"]) | |||
const schemaItemsFormat = schema.getIn(["items", "format"]) | |||
const schemaItemsSchema = schema.getIn(["items", "schema"]) | |||
let ArrayItemsComponent | |||
let isArrayItemText = false | |||
if (schemaItemsType && schemaItemsFormat) { | |||
ArrayItemsComponent = getComponent(`JsonSchema_${schemaItemsType}_${schemaItemsFormat}`) | |||
} else if (schemaItemsType === "boolean" || schemaItemsType === "array" || schemaItemsType === "object") { | |||
ArrayItemsComponent = getComponent(`JsonSchema_${schemaItemsType}`) | |||
} | |||
// if ArrayItemsComponent not assigned or does not exist, | |||
// use default schemaItemsType === "string" & JsonSchemaArrayItemText component | |||
if (!ArrayItemsComponent) { | |||
isArrayItemText = true | |||
} | |||
let itemSchema = fn.inferSchema(schema.items) | |||
const JsonSchemaForm = getComponent("JsonSchemaForm") | |||
const Button = getComponent("Button") | |||
let enumValue = itemSchema["enum"] | |||
let value = this.state.value | |||
if ( enumValue ) { | |||
if ( schemaItemsEnum ) { | |||
const Select = getComponent("Select") | |||
return (<Select className={ errors.length ? "invalid" : ""} | |||
title={ errors.length ? errors : ""} | |||
multiple={ true } | |||
value={ value } | |||
disabled={disabled} | |||
allowedValues={ enumValue } | |||
allowedValues={ schemaItemsEnum } | |||
allowEmptyValue={ !required } | |||
onChange={ this.onEnumChange }/>) | |||
} | |||
const Button = getComponent("Button") | |||
return ( | |||
<div className="json-schema-array"> | |||
{ !value || !value.count || value.count() < 1 ? null : | |||
value.map( (item,i) => { | |||
let schema = Object.assign({}, itemSchema) | |||
if ( errors.length ) { | |||
{shouldRenderValue ? | |||
(value.map((item, i) => { | |||
if (errors.length) { | |||
let err = errors.filter((err) => err.index === i) | |||
if (err.length) errors = [ err[0].error + i ] | |||
if (err.length) errors = [err[0].error + i] | |||
} | |||
return ( | |||
<div key={i} className="json-schema-form-item"> | |||
<JsonSchemaForm | |||
fn={fn} | |||
getComponent={getComponent} | |||
value={item} | |||
onChange={(val) => this.onItemChange(val, i)} | |||
schema={schema} | |||
disabled={disabled} | |||
/> | |||
{ !disabled ? ( | |||
<Button | |||
className="btn btn-sm json-schema-form-item-remove" | |||
onClick={()=> this.removeItem(i)} | |||
> - </Button> | |||
) : null } | |||
</div> | |||
return ( | |||
<div key={i} className="json-schema-form-item"> | |||
{ | |||
isArrayItemText ? | |||
<JsonSchemaArrayItemText | |||
value={item} | |||
onChange={(val) => this.onItemChange(val, i)} | |||
disabled={disabled} | |||
errors={errors} | |||
/> | |||
: <ArrayItemsComponent {...this.props} | |||
value={item} | |||
onChange={(val) => this.onItemChange(val, i)} | |||
disabled={disabled} | |||
errors={errors} | |||
schema={schemaItemsSchema} | |||
getComponent={getComponent} | |||
fn={fn} | |||
/> | |||
} | |||
{!disabled ? ( | |||
<Button | |||
className="btn btn-sm json-schema-form-item-remove" | |||
onClick={() => this.removeItem(i)} | |||
> - </Button> | |||
) : null} | |||
</div> | |||
) | |||
}).toArray() | |||
}) | |||
) : null | |||
} | |||
{ !disabled ? ( | |||
{!disabled ? ( | |||
<Button | |||
className={`btn btn-sm json-schema-form-item-add ${errors.length ? "invalid" : null}`} | |||
onClick={this.addItem} | |||
> | |||
Add item | |||
</Button> | |||
) : null } | |||
) : null} | |||
</div> | |||
) | |||
} | |||
} | |||
export class JsonSchemaArrayItemText extends Component { | |||
static propTypes = JsonSchemaPropShape | |||
static defaultProps = JsonSchemaDefaultProps | |||
onChange = (e) => { | |||
const value = e.target.value | |||
this.props.onChange(value, this.props.keyName) | |||
} | |||
render() { | |||
let { value, errors, description, disabled } = this.props | |||
if (!value) { | |||
value = "" // value should not be null | |||
} | |||
errors = errors.toJS ? errors.toJS() : [] | |||
return (<DebounceInput | |||
type={"text"} | |||
className={errors.length ? "invalid" : ""} | |||
title={errors.length ? errors : ""} | |||
value={value} | |||
minLength={0} | |||
debounceTimeout={350} | |||
placeholder={description} | |||
onChange={this.onChange} | |||
disabled={disabled} />) | |||
} | |||
} | |||
export class JsonSchema_boolean extends Component { | |||
static propTypes = JsonSchemaPropShape | |||
static defaultProps = JsonSchemaDefaultProps | |||
@@ -232,15 +283,19 @@ export class JsonSchema_boolean extends Component { | |||
render() { | |||
let { getComponent, value, errors, schema, required, disabled } = this.props | |||
errors = errors.toJS ? errors.toJS() : [] | |||
let enumValue = schema && schema.get ? schema.get("enum") : null | |||
if (!enumValue) { | |||
// in case schema.get() also returns undefined/null | |||
enumValue = fromJS(["true", "false"]) | |||
} | |||
const Select = getComponent("Select") | |||
return (<Select className={ errors.length ? "invalid" : ""} | |||
title={ errors.length ? errors : ""} | |||
value={ String(value) } | |||
disabled={disabled} | |||
allowedValues={ fromJS(schema.enum || ["true", "false"]) } | |||
allowEmptyValue={ !schema.enum || !required } | |||
disabled={ disabled } | |||
allowedValues={ enumValue } | |||
allowEmptyValue={ !required } | |||
onChange={ this.onEnumChange }/>) | |||
} | |||
} | |||
@@ -9,10 +9,11 @@ export default OAS3ComponentWrapFactory(({ Ori, ...props }) => { | |||
onChange | |||
} = props | |||
const { type, format } = schema | |||
const format = schema && schema.get ? schema.get("format") : null | |||
const type = schema && schema.get ? schema.get("type") : null | |||
const Input = getComponent("Input") | |||
if(type === "string" && (format === "binary" || format === "base64")) { | |||
if(type && type === "string" && (format && (format === "binary" || format === "base64"))) { | |||
return <Input type="file" | |||
className={ errors.length ? "invalid" : ""} | |||
title={ errors.length ? errors : ""} | |||
@@ -100,7 +100,6 @@ const wrapRender = (component) => { | |||
return target | |||
} | |||
export const getComponent = (getSystem, getStore, getComponents, componentName, container, config = {}) => { | |||
if(typeof componentName !== "string") | |||
@@ -0,0 +1,339 @@ | |||
openapi: 3.0.0 | |||
info: | |||
title: "Schema in Parameters" | |||
description: |- | |||
This document has examples for examining the `schema` within a set of parameters | |||
* String Enum (/pet/findByStatus) | |||
* Array of Strings (/pet/findByTags) | |||
* Array of Boolean (/petOwner/listOfServiceTrainer) | |||
* Array of Objects (/petOwners/createWithList) | |||
* Array of Enum (/petOwner/findByPreference) | |||
This document also covers a debounce test for `schema` type `string | |||
* String (/petOwner) | |||
This documents does not cover: | |||
* Array of Arrays | |||
Additional notes | |||
* Provides additional coverage and examples not covered in the Multiple Examples Core Document (Test) | |||
* Code component reference `JsonSchemaForm` | |||
* `pet` and `tag` schemas are reduced from Swagger Petstore | |||
version: "1.0.0" | |||
paths: | |||
/pet/findByStatus: | |||
get: | |||
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' | |||
'/petOwner/{petOwnerId}': | |||
get: | |||
tags: | |||
- petOwner | |||
summary: Find pet owner by ID | |||
description: Returns a single pet owner if ID found, list if no ID provided | |||
operationId: getPetOwnerById | |||
parameters: | |||
- name: petOwnerId | |||
in: path | |||
description: ID of pet owner to return | |||
required: false | |||
schema: | |||
type: integer | |||
format: int64 | |||
responses: | |||
'200': | |||
description: successful operation | |||
content: | |||
application/xml: | |||
schema: | |||
$ref: '#/components/schemas/PetOwner' | |||
application/json: | |||
schema: | |||
$ref: '#/components/schemas/PetOwner' | |||
'400': | |||
description: Invalid ID supplied | |||
'404': | |||
description: Pet not found | |||
/petOwner/listOfServiceTrainer: | |||
get: | |||
tags: | |||
- petOwner | |||
summary: List of Service Trainers | |||
description: >- | |||
Expect boolean, but allow both true and false | |||
operationId: listOfServiceTrainer | |||
parameters: | |||
- name: tags | |||
in: query | |||
description: Boolean to filter by | |||
required: false | |||
explode: true | |||
schema: | |||
type: array | |||
items: | |||
type: boolean | |||
responses: | |||
'200': | |||
description: successful operation | |||
content: | |||
application/xml: | |||
schema: | |||
type: array | |||
items: | |||
$ref: '#/components/schemas/PetOwner' | |||
application/json: | |||
schema: | |||
type: array | |||
items: | |||
$ref: '#/components/schemas/PetOwner' | |||
'400': | |||
description: Invalid tag value | |||
/petOwner/findByPreference: | |||
get: | |||
tags: | |||
- petOwner | |||
summary: Find by Pet Owner Preferences | |||
description: >- | |||
Expect enum | |||
operationId: findByPreference | |||
parameters: | |||
- name: tags | |||
in: query | |||
description: Enum to filter by | |||
required: false | |||
explode: true | |||
schema: | |||
type: array | |||
items: | |||
type: string | |||
enum: | |||
- dog | |||
- cat | |||
- bird | |||
- fish | |||
- other | |||
default: dog | |||
responses: | |||
'200': | |||
description: successful operation | |||
content: | |||
application/xml: | |||
schema: | |||
type: array | |||
items: | |||
$ref: '#/components/schemas/PetOwner' | |||
application/json: | |||
schema: | |||
type: array | |||
items: | |||
$ref: '#/components/schemas/PetOwner' | |||
'400': | |||
description: Invalid tag value | |||
components: | |||
/petOwner/createWithList: | |||
post: | |||
tags: | |||
- petOwner | |||
summary: Creates list of pet owners with given input array | |||
operationId: petOwnerCreateWithList | |||
requestBody: | |||
content: | |||
application/json: | |||
schema: | |||
type: array | |||
items: | |||
$ref: '#/components/schemas/PetOwner' | |||
responses: | |||
'200': | |||
description: successful operation | |||
content: | |||
application/xml: | |||
schema: | |||
type: array | |||
items: | |||
$ref: '#/components/schemas/PetOwner' | |||
application/json: | |||
schema: | |||
type: array | |||
items: | |||
$ref: '#/components/schemas/PetOwner' | |||
'400': | |||
description: Invalid values | |||
schemas: | |||
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 | |||
# remove category property | |||
petOwners: | |||
type: array | |||
items: | |||
$ref: '#/components/schemas/PetOwner' | |||
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 | |||
# remove ApiResponse | |||
PetOwner: | |||
type: "object" | |||
properties: | |||
id: | |||
type: "integer" | |||
format: "int64" | |||
example: 10 | |||
petId: | |||
type: "integer" | |||
format: "int64" | |||
example: 201 | |||
petOwnerFirstName: | |||
type: "string" | |||
example: "John" | |||
petOwnerLastName: | |||
type: "string" | |||
example: "Smith" | |||
petOwnerContact: | |||
type: "string" | |||
example: "john.smith@fakeemail.co" | |||
petOwnerStatus: | |||
type: "integer" | |||
format: "int32" | |||
description: "Pet Owner Status" | |||
example: 302 | |||
petOwnerPreferences: | |||
type: "string" | |||
description: "Pet Owner Preferred Pet Types" | |||
enum: | |||
- "dog" | |||
- "cat" | |||
- "bird" | |||
- "fish" | |||
- "other" | |||
petOwnerServiceTrainer: | |||
type: "boolean" | |||
description: "Pet Onwer is Service Trainer" | |||
default: false | |||
Tag: | |||
x-swagger-router-model: io.swagger.petstore.model.Tag | |||
properties: | |||
id: | |||
type: integer | |||
format: int64 | |||
name: | |||
type: string | |||
xml: | |||
name: tag | |||
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 |
@@ -0,0 +1,119 @@ | |||
openapi: 3.0.0 | |||
info: | |||
description: No type for schema | |||
version: "1" | |||
title: "No type" | |||
paths: | |||
/case-one-no-schema: | |||
parameters: | |||
- name: namespace | |||
description: The custom resource's namespace | |||
# schema: | |||
in: path | |||
required: true | |||
get: | |||
description: sf | |||
responses: | |||
default: | |||
description: one | |||
/case-one-no-type-or-format: | |||
parameters: | |||
- name: namespace | |||
description: The custom resource's namespace | |||
schema: | |||
in: path | |||
required: true | |||
get: | |||
description: sf | |||
responses: | |||
default: | |||
description: one | |||
/case-one-type-only-no-format: | |||
parameters: | |||
- name: namespace | |||
description: The custom resource's namespace | |||
schema: | |||
type: integer | |||
in: path | |||
required: true | |||
get: | |||
description: sf | |||
responses: | |||
default: | |||
description: one | |||
/case-one-format-only-no-type: | |||
parameters: | |||
- name: namespace | |||
description: The custom resource's namespace | |||
schema: | |||
format: int64 | |||
in: path | |||
required: true | |||
get: | |||
description: sf | |||
responses: | |||
default: | |||
description: one | |||
/case-two-no-schema: | |||
get: | |||
description: sf | |||
responses: | |||
default: | |||
description: one | |||
parameters: | |||
- name: namespace | |||
in: path | |||
description: The custom resource's namespace | |||
required: true | |||
# schema: | |||
/case-two-no-type-or-format: | |||
get: | |||
description: sf | |||
responses: | |||
default: | |||
description: one | |||
parameters: | |||
- name: namespace | |||
in: path | |||
description: The custom resource's namespace | |||
required: true | |||
schema: | |||
/case-two-type-only-no-format: | |||
get: | |||
description: sf | |||
responses: | |||
default: | |||
description: one | |||
parameters: | |||
- name: namespace | |||
in: path | |||
description: The custom resource's namespace | |||
required: true | |||
schema: | |||
type: integer | |||
/case-two-format-only-no-type: | |||
get: | |||
description: sf | |||
responses: | |||
default: | |||
description: one | |||
parameters: | |||
- name: namespace | |||
in: path | |||
description: The custom resource's namespace | |||
required: true | |||
schema: | |||
format: int64 | |||
/case-two-not-a-real-type: | |||
get: | |||
description: sf | |||
responses: | |||
default: | |||
description: one | |||
parameters: | |||
- name: namespace | |||
in: path | |||
description: The custom resource's namespace | |||
required: true | |||
schema: | |||
type: "NotARealType" |
@@ -0,0 +1,879 @@ | |||
/** | |||
* @prettier | |||
*/ | |||
describe("OpenAPI 3.0 Additional JsonSchemaForm in a Parameter", () => { | |||
describe("incomplete API definition with missing schema key or schema value(s)", () => { | |||
describe("parameter exists as global", () => { | |||
it("should render when parameter exists as global, but missing schema key", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-missing-values.yaml" | |||
) | |||
.get("#operations-default-get_case_one_no_schema") | |||
.click() | |||
.get(".opblock-description .renderedMarkdown p") | |||
.should("have.text", "sf") | |||
}) | |||
it("should render when parameter exists as global, but missing all schema values", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-missing-values.yaml" | |||
) | |||
.get("#operations-default-get_case_one_no_type_or_format") | |||
.click() | |||
.get(".opblock-description .renderedMarkdown p") | |||
.should("have.text", "sf") | |||
}) | |||
it("should render when parameter exists as global, schema key exists, but missing schema values: format", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-missing-values.yaml" | |||
) | |||
.get("#operations-default-get_case_one_format_only_no_type") | |||
.click() | |||
.get(".opblock-description .renderedMarkdown p") | |||
.should("have.text", "sf") | |||
}) | |||
it("should render when parameter exists as global, schema key exists, but missing schema value: type", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-missing-values.yaml" | |||
) | |||
.get("#operations-default-get_case_one_type_only_no_format") | |||
.click() | |||
.get(".opblock-description .renderedMarkdown p") | |||
.should("have.text", "sf") | |||
}) | |||
}) | |||
describe("parameter exists in method", () => { | |||
it("should render when parameter exists in method, but missing schema key", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-missing-values.yaml" | |||
) | |||
.get("#operations-default-get_case_two_no_schema") | |||
.click() | |||
.get(".opblock-description .renderedMarkdown p") | |||
.should("have.text", "sf") | |||
}) | |||
it("should render when parameter exists in method, schema key exists, but missing all schema values", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-missing-values.yaml" | |||
) | |||
.get("#operations-default-get_case_two_no_type_or_format") | |||
.click() | |||
.get(".opblock-description .renderedMarkdown p") | |||
.should("have.text", "sf") | |||
}) | |||
it("should render when parameter exists in method, schema key exists, but missing schema value: format", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-missing-values.yaml" | |||
) | |||
.get("#operations-default-get_case_one_type_only_no_format") | |||
.click() | |||
.get(".opblock-description .renderedMarkdown p") | |||
.should("have.text", "sf") | |||
}) | |||
it("should render when parameter exists in method, schema key exists, but missing schema value: type", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-missing-values.yaml" | |||
) | |||
.get("#operations-default-get_case_one_format_only_no_type") | |||
.click() | |||
.get(".opblock-description .renderedMarkdown p") | |||
.should("have.text", "sf") | |||
}) | |||
}) | |||
}) | |||
describe("/Array", () => { | |||
describe("in a Parameter", () => { | |||
it("should allow modification of values in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/multiple-examples-core.openapi.yaml" | |||
) | |||
.get("#operations-default-post_Array") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
.get(".parameters-col_description .examples-select > select") | |||
.select("ArrayExampleB") | |||
// Add a new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > input") | |||
.type("5") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"1", | |||
"2", | |||
"3", | |||
"4", | |||
"5", | |||
]) | |||
}) | |||
.get(".parameters-col_description .examples-select > select") | |||
.find(":selected") | |||
.should("have.text", "[Modified value]") | |||
}) | |||
it("should allow removal of added value in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/multiple-examples-core.openapi.yaml" | |||
) | |||
.get("#operations-default-post_Array") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
.get(".parameters-col_description .examples-select > select") | |||
.select("ArrayExampleB") | |||
// Add a new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > input") | |||
.type("5") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"1", | |||
"2", | |||
"3", | |||
"4", | |||
"5", | |||
]) | |||
}) | |||
.get(".parameters-col_description .examples-select > select") | |||
.find(":selected") | |||
.should("have.text", "[Modified value]") | |||
// Remove the last item that was just added | |||
.get(".json-schema-form-item:last-of-type > .json-schema-form-item-remove") | |||
.click() | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"1", | |||
"2", | |||
"3", | |||
"4", | |||
]) | |||
}) | |||
}) | |||
it("should allow removal of nth of values in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/multiple-examples-core.openapi.yaml" | |||
) | |||
.get("#operations-default-post_Array") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
.get(".parameters-col_description .examples-select > select") | |||
.select("ArrayExampleB") | |||
// Add a new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > input") | |||
.type("5") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"1", | |||
"2", | |||
"3", | |||
"4", | |||
"5", | |||
]) | |||
}) | |||
.get(".parameters-col_description .examples-select > select") | |||
.find(":selected") | |||
.should("have.text", "[Modified value]") | |||
// Remove the second item in list | |||
.get(".json-schema-form-item:nth-child(2) > .json-schema-form-item-remove") | |||
.click() | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"1", | |||
"3", | |||
"4", | |||
"5" | |||
]) | |||
}) | |||
}) | |||
it("should allow execution of operation in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/multiple-examples-core.openapi.yaml" | |||
) | |||
.get("#operations-default-post_Array") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
.get(".parameters-col_description .examples-select > select") | |||
.select("ArrayExampleB") | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
}) | |||
it("should add empty item and allow execution of operation in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/multiple-examples-core.openapi.yaml" | |||
) | |||
.get("#operations-default-post_Array") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
.get(".parameters-col_description .examples-select > select") | |||
.select("ArrayExampleB") | |||
// Add a new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
// Execute without prior typing a value | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
}) | |||
}) | |||
}) | |||
describe("Petstore", () => { | |||
describe("/pet/findByStatus", () => { | |||
it("should render the operation, execute with default value", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-default-findPetsByStatus") | |||
.click() | |||
// Expand operation | |||
.get(".opblock-title span") | |||
.should("have.text", "Parameters") | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "available") | |||
}) | |||
it("should render the operation, modify value, and execute with modfied value", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-default-findPetsByStatus") | |||
.click() | |||
// Expand operation | |||
.get(".opblock-title span") | |||
.should("have.text", "Parameters") | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Select | |||
.get(".parameters-col_description > select") | |||
.select("pending") | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "pending") | |||
}) | |||
}) | |||
describe("/pet/findByTags", () => { | |||
it("should allow modification of values in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-pet-findPetsByTags") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Add a new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item > input") | |||
.type("spotted") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
]) | |||
}) | |||
}) | |||
it("should allow removal of added value in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-pet-findPetsByTags") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Add a new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > input") | |||
.type("spotted") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
]) | |||
}) | |||
// Remove the last item that was just added | |||
.get(".json-schema-form-item:last-of-type > .json-schema-form-item-remove") | |||
.click() | |||
.get(".json-schema-form-item > input") | |||
.should("not.exist") | |||
}) | |||
it("should allow removal of nth of values in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-pet-findPetsByTags") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Add a new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > input") | |||
.type("spotted") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
]) | |||
}) | |||
// Add a 2nd new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > input") | |||
.type("large") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
"large" | |||
]) | |||
}) | |||
// Add a 3rd new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > input") | |||
.type("puppy") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
"large", | |||
"puppy" | |||
]) | |||
}) | |||
// Remove the second item in list | |||
.get(".json-schema-form-item:nth-child(2) > .json-schema-form-item-remove") | |||
.click() | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
"puppy" | |||
]) | |||
}) | |||
}) | |||
it("should allow execution of operation without modifications in Try-It-Out (debounce)", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-pet-findPetsByTags") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "findByTags") | |||
}) | |||
it("should add empty item and allow execution of operation in Try-It-Out (debounce)", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-pet-findPetsByTags") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Add a new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
// Execute without prior typing a value | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "findByTags") | |||
}) | |||
it("should add modified item and allow execution of operation in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-pet-findPetsByTags") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Add a new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item > input") | |||
.type("spotted") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
]) | |||
}) | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "spotted") | |||
}) | |||
it("should add 3 modified items, remove the middle child, and allow execution of operation Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-pet-findPetsByTags") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Add a new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > input") | |||
.type("spotted") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
]) | |||
}) | |||
// Add a 2nd new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > input") | |||
.type("large") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
"large" | |||
]) | |||
}) | |||
// Add a 3rd new item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > input") | |||
.type("puppy") | |||
// Assert against the input fields | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
"large", | |||
"puppy" | |||
]) | |||
}) | |||
// Remove the second item in list | |||
.get(".json-schema-form-item:nth-child(2) > .json-schema-form-item-remove") | |||
.click() | |||
.get(".json-schema-form-item > input") | |||
.then(inputs => { | |||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([ | |||
"spotted", | |||
"puppy" | |||
]) | |||
}) | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "tags=spotted&tags=puppy") | |||
.should("not.have.text", "large") | |||
}) | |||
}) | |||
describe("/petOwner/{petOwnerId}", () => { | |||
// This is a (GET) debounce test for schema type: string | |||
it("should render the operation, and allow execute of operation with empty value (debounce)", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-getPetOwnerById") | |||
.click() | |||
// Expand operation | |||
.get(".opblock-title span") | |||
.should("have.text", "Parameters") | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "petOwner") | |||
}) | |||
it("should render the operation, and input field, and allow execute of operation", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-getPetOwnerById") | |||
.click() | |||
// Expand operation | |||
.get(".opblock-title span") | |||
.should("have.text", "Parameters") | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
.get(".parameters-col_description > input") | |||
.type("123") | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "petOwner") | |||
.should("contain.text", "123") | |||
}) | |||
}) | |||
describe("/petOwner/listOfServiceTrainer", () => { | |||
it("should allow execution of operation with value=true in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-listOfServiceTrainer") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// add 1st item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item > select") | |||
.select("true") | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "tags=true") | |||
}) | |||
it("should allow execution of operation with value=false in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-listOfServiceTrainer") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// add 1st item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item > select") | |||
.select("false") | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "tags=false") | |||
}) | |||
it("should allow execution of operation with value=true&value=false in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-listOfServiceTrainer") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// add 1st item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item > select") | |||
.select("true") | |||
// add 2nd item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > select") | |||
.select("false") | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "tags=true&tags=false") | |||
}) | |||
it("should allow execution of operation with value=false after removing value=true in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-listOfServiceTrainer") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// add 1st item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item > select") | |||
.select("true") | |||
// add 2nd item | |||
.get(".json-schema-form-item-add") | |||
.click() | |||
.get(".json-schema-form-item:last-of-type > select") | |||
.select("false") | |||
// remove 1st item | |||
.get(".json-schema-form-item:nth-child(1) > .json-schema-form-item-remove") | |||
.click() | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "tags=false") | |||
}) | |||
it("should allow execution of operation with value=(empty) in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-listOfServiceTrainer") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "listOfServiceTrainer") | |||
}) | |||
}) | |||
describe("/petOwner/findByPreference", () => { | |||
it("should allow execution of operation with value=(empty) in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-findByPreference") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "findByPreference") | |||
}) | |||
it("should allow execution of operation with selected value in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-findByPreference") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Select | |||
.get(".parameters-col_description > select") | |||
.select("dog") | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "findByPreference") | |||
.should("contain.text", "dog") | |||
}) | |||
it("should allow execution of operation with multiple selected values in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-findByPreference") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Select | |||
.get(".parameters-col_description > select") | |||
.select(["dog", "cat"]) | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "findByPreference") | |||
.should("contain.text", "dog") | |||
.should("contain.text", "cat") | |||
}) | |||
}) | |||
describe("/petOwner/createWithList", () => { | |||
it("should allow execution of operation with default text in textArea in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-petOwnerCreateWithList") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "createWithList") | |||
}) | |||
it("should allow execution of operation with cleared textArea in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-petOwnerCreateWithList") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
.get(".body-param__text") | |||
.clear() | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "createWithList") | |||
}) | |||
it("should allow execution of operation with modified textArea in Try-It-Out", () => { | |||
cy.visit( | |||
"/?url=/documents/features/schema-form-core.yaml" | |||
) | |||
.get("#operations-petOwner-petOwnerCreateWithList") | |||
.click() | |||
// Expand Try It Out | |||
.get(".try-out__btn") | |||
.click() | |||
.get(".body-param__text") | |||
.clear() | |||
// note: adding this much type adds 6+ seconds to test | |||
.type(`[ | |||
{ | |||
"id": 10, | |||
"petId": 201, | |||
"petOwnerFirstName": "John", | |||
}, | |||
{ | |||
"id": 11, | |||
"petId": 201, | |||
"petOwnerFirstName": "Jane", | |||
} | |||
]` | |||
) | |||
.should("contain.text", "Jane") | |||
.should("contain.text", "201") | |||
// Execute | |||
.get(".execute.opblock-control__btn") | |||
.click() | |||
// Expect new element to be visible after Execute | |||
.get(".btn-clear.opblock-control__btn") | |||
.should("have.text", "Clear") | |||
// Compare Request URL | |||
.get(".request-url pre.microlight") | |||
.should("contain.text", "createWithList") | |||
// Compare Curl | |||
.get(".curl") | |||
.should("contain.text", "Jane") | |||
.should("contain.text", "201") | |||
}) | |||
}) | |||
}) | |||
}) | |||
@@ -1,6 +1,6 @@ | |||
/* eslint-env mocha */ | |||
import React from "react" | |||
import { List } from "immutable" | |||
import Immutable, { List } from "immutable" | |||
import expect, { createSpy } from "expect" | |||
import { Select, Input, TextArea } from "components/layout-utils" | |||
import { mount, render } from "enzyme" | |||
@@ -25,10 +25,10 @@ describe("<JsonSchemaForm/>", function(){ | |||
onChange: () => {}, | |||
keyName: "", | |||
fn: {}, | |||
schema: { | |||
schema: Immutable.fromJS({ | |||
type: "string", | |||
enum: ["one", "two"] | |||
} | |||
}) | |||
} | |||
let wrapper = render(<JsonSchemaForm {...props}/>) | |||
@@ -48,10 +48,10 @@ describe("<JsonSchemaForm/>", function(){ | |||
onChange: () => {}, | |||
keyName: "", | |||
fn: {}, | |||
schema: { | |||
schema: Immutable.fromJS({ | |||
type: "string", | |||
enum: ["one", "two"] | |||
}, | |||
}), | |||
disabled: true | |||
} | |||
@@ -70,10 +70,10 @@ describe("<JsonSchemaForm/>", function(){ | |||
keyName: "", | |||
fn: {}, | |||
required: true, | |||
schema: { | |||
schema: Immutable.fromJS({ | |||
type: "string", | |||
enum: ["one", "two"] | |||
} | |||
}) | |||
} | |||
let wrapper = render(<JsonSchemaForm {...props}/>) | |||
@@ -93,9 +93,9 @@ describe("<JsonSchemaForm/>", function(){ | |||
onChange: () => {}, | |||
keyName: "", | |||
fn: {}, | |||
schema: { | |||
schema: Immutable.fromJS({ | |||
type: "boolean" | |||
} | |||
}) | |||
} | |||
let wrapper = render(<JsonSchemaForm {...props}/>) | |||
@@ -116,10 +116,10 @@ describe("<JsonSchemaForm/>", function(){ | |||
onChange: () => {}, | |||
keyName: "", | |||
fn: {}, | |||
schema: { | |||
schema: Immutable.fromJS({ | |||
type: "boolean", | |||
enum: ["true"] | |||
} | |||
}) | |||
} | |||
let wrapper = render(<JsonSchemaForm {...props}/>) | |||
@@ -139,10 +139,10 @@ describe("<JsonSchemaForm/>", function(){ | |||
onChange: () => {}, | |||
keyName: "", | |||
fn: {}, | |||
schema: { | |||
schema: Immutable.fromJS({ | |||
type: "boolean", | |||
required: true | |||
} | |||
}) | |||
} | |||
let wrapper = render(<JsonSchemaForm {...props}/>) | |||
@@ -164,10 +164,10 @@ describe("<JsonSchemaForm/>", function(){ | |||
keyName: "", | |||
fn: {}, | |||
required: true, | |||
schema: { | |||
schema: Immutable.fromJS({ | |||
type: "boolean", | |||
enum: ["true"] | |||
} | |||
}) | |||
} | |||
let wrapper = render(<JsonSchemaForm {...props}/>) | |||
@@ -191,7 +191,7 @@ describe("<JsonSchemaForm/>", function(){ | |||
keyName: "", | |||
fn: {}, | |||
errors: List(), | |||
schema: { | |||
schema: Immutable.fromJS({ | |||
type: "object", | |||
properties: { | |||
id: { | |||
@@ -199,7 +199,7 @@ describe("<JsonSchemaForm/>", function(){ | |||
example: "abc123" | |||
} | |||
} | |||
} | |||
}) | |||
} | |||
let wrapper = mount(<JsonSchemaForm {...props}/>) | |||
@@ -219,9 +219,9 @@ describe("<JsonSchemaForm/>", function(){ | |||
onChange: () => {}, | |||
keyName: "", | |||
fn: {}, | |||
schema: { | |||
schema: Immutable.fromJS({ | |||
type: "NotARealType" | |||
} | |||
}) | |||
} | |||
@@ -240,10 +240,10 @@ describe("<JsonSchemaForm/>", function(){ | |||
onChange: () => {}, | |||
keyName: "", | |||
fn: {}, | |||
schema: { | |||
schema: Immutable.fromJS({ | |||
type: "NotARealType", | |||
format: "NotARealFormat" | |||
} | |||
}) | |||
} | |||