diff --git a/package.json b/package.json
index 7186fc61..ec00dc89 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,7 @@
"lint": "eslint --cache --ext '.js,.jsx' src test",
"lint-errors": "eslint --cache --quiet --ext '.js,.jsx' src test",
"lint-fix": "eslint --cache --ext '.js,.jsx' src test --fix",
- "test": "npm run lint-errors && npm run just-test-in-node",
+ "test": "npm run just-test-in-node && npm run lint-errors",
"test-in-node": "npm run lint-errors && npm run just-test-in-node",
"just-test": "karma start --config karma.conf.js",
"just-test-in-node": "mocha --require test/setup.js --recursive --compilers js:babel-core/register test/core test/components test/bugs test/swagger-ui-dist-package test/xss",
diff --git a/src/core/json-schema-components.js b/src/core/json-schema-components.js
index 14998feb..8d7f3a3b 100644
--- a/src/core/json-schema-components.js
+++ b/src/core/json-schema-components.js
@@ -1,8 +1,10 @@
import React, { PureComponent, Component } from "react"
import PropTypes from "prop-types"
import { List, fromJS } from "immutable"
+import cx from "classnames"
import ImPropTypes from "react-immutable-proptypes"
import DebounceInput from "react-debounce-input"
+import { getSampleSchema } from "core/utils"
//import "less/json-schema-form"
const noop = ()=> {}
@@ -204,3 +206,53 @@ export class JsonSchema_boolean extends Component {
onChange={ this.onEnumChange }/>)
}
}
+
+export class JsonSchema_object extends PureComponent {
+ constructor() {
+ super()
+ }
+
+ static propTypes = JsonSchemaPropShape
+ static defaultProps = JsonSchemaDefaultProps
+
+ componentDidMount() {
+ if(!this.props.value && this.props.schema) {
+ this.resetValueToSample()
+ }
+ }
+
+ resetValueToSample = () => {
+ this.onChange(getSampleSchema(this.props.schema) )
+ }
+
+ onChange = (value) => {
+ this.props.onChange(value)
+ }
+
+ handleOnChange = e => {
+ const inputValue = e.target.value
+
+ this.onChange(inputValue)
+ }
+
+ render() {
+ let {
+ getComponent,
+ value,
+ errors
+ } = this.props
+
+ const TextArea = getComponent("TextArea")
+
+ return (
+
+
+
+ )
+
+ }
+}
diff --git a/src/core/utils.js b/src/core/utils.js
index dc966591..795e3ae9 100644
--- a/src/core/utils.js
+++ b/src/core/utils.js
@@ -503,7 +503,30 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
let numberCheck = type === "number" && (value || value === 0)
let integerCheck = type === "integer" && (value || value === 0)
- if ( required && !(stringCheck || arrayCheck || listCheck || fileCheck || booleanCheck || numberCheck || integerCheck) ) {
+ let oas3ObjectCheck = false
+
+ if(false || isOAS3 && type === "object") {
+ if(typeof value === "object") {
+ oas3ObjectCheck = true
+ } else if(typeof value === "string") {
+ try {
+ JSON.parse(value)
+ oas3ObjectCheck = true
+ } catch(e) {
+ errors.push("Parameter string value must be valid JSON")
+ return errors
+ }
+ }
+ }
+
+ const allChecks = [
+ stringCheck, arrayCheck, listCheck, fileCheck, booleanCheck,
+ numberCheck, integerCheck, oas3ObjectCheck
+ ]
+
+ const passedAnyCheck = allChecks.some(v => !!v)
+
+ if ( required && !passedAnyCheck ) {
errors.push("Required field is not provided")
return errors
}
diff --git a/src/style/_form.scss b/src/style/_form.scss
index c2c4ea24..be712eba 100644
--- a/src/style/_form.scss
+++ b/src/style/_form.scss
@@ -51,7 +51,8 @@ input[type=text],
input[type=password],
input[type=search],
input[type=email],
-input[type=file]
+input[type=file],
+textarea
{
min-width: 100px;
margin: 5px 0;
diff --git a/test/components/json-schema-form.js b/test/components/json-schema-form.js
index ba551919..41ba87a5 100644
--- a/test/components/json-schema-form.js
+++ b/test/components/json-schema-form.js
@@ -1,12 +1,13 @@
/* eslint-env mocha */
import React from "react"
+import { List } from "immutable"
import expect, { createSpy } from "expect"
-import { Select, Input } from "components/layout-utils"
-import { render } from "enzyme"
+import { Select, Input, TextArea } from "components/layout-utils"
+import { mount, render } from "enzyme"
import * as JsonSchemaComponents from "core/json-schema-components"
import { JsonSchemaForm } from "core/json-schema-components"
-const components = {...JsonSchemaComponents, Select, Input}
+const components = {...JsonSchemaComponents, Select, Input, TextArea}
const getComponentStub = (name) => {
if(components[name]) return components[name]
@@ -107,6 +108,38 @@ describe("", function(){
expect(wrapper.find("select option").first().text()).toEqual("true")
})
})
+ describe("objects", function() {
+ it("should render the correct editor for an OAS3 object parameter", function(){
+ let updateQueue = []
+
+ let props = {
+ getComponent: getComponentStub,
+ value: "",
+ onChange: (value) => {
+ updateQueue.push({ value })
+ },
+ keyName: "",
+ fn: {},
+ errors: List(),
+ schema: {
+ type: "object",
+ properties: {
+ id: {
+ type: "string",
+ example: "abc123"
+ }
+ }
+ }
+ }
+
+ let wrapper = mount()
+
+ updateQueue.forEach(newProps => wrapper.setProps(newProps))
+
+ expect(wrapper.find("textarea").length).toEqual(1)
+ expect(wrapper.find("textarea").text()).toEqual(`{\n "id": "abc123"\n}`)
+ })
+ })
describe("unknown types", function() {
it("should render unknown types as strings", function(){
diff --git a/test/core/utils.js b/test/core/utils.js
index 43bf1f47..b180b09a 100644
--- a/test/core/utils.js
+++ b/test/core/utils.js
@@ -350,6 +350,12 @@ describe("utils", function() {
expect( result ).toEqual( expectedError )
}
+ const assertValidateOas3Param = (param, expectedError) => {
+ // for cases where you _only_ want to try OAS3
+ result = validateParam( fromJS(param), false, true )
+ expect( result ).toEqual( expectedError )
+ }
+
it("should check the isOAS3 flag when validating parameters", function() {
// This should "skip" validation because there is no `schema` property
// and we are telling `validateParam` this is an OAS3 spec
@@ -361,6 +367,92 @@ describe("utils", function() {
expect( result ).toEqual( [] )
})
+ it("validates required OAS3 objects", function() {
+ // valid object
+ param = {
+ required: true,
+ schema: {
+ type: "object"
+ },
+ value: {
+ abc: 123
+ }
+ }
+ assertValidateOas3Param(param, [])
+
+ // valid object-as-string
+ param = {
+ required: true,
+ schema: {
+ type: "object"
+ },
+ value: JSON.stringify({
+ abc: 123
+ })
+ }
+ assertValidateOas3Param(param, [])
+
+ // invalid object-as-string
+ param = {
+ required: true,
+ schema: {
+ type: "object"
+ },
+ value: "{{}"
+ }
+ assertValidateOas3Param(param, ["Parameter string value must be valid JSON"])
+
+ // missing when required
+ param = {
+ required: true,
+ schema: {
+ type: "object"
+ },
+ }
+ assertValidateOas3Param(param, ["Required field is not provided"])
+ })
+
+ it("validates optional OAS3 objects", function() {
+ // valid object
+ param = {
+ schema: {
+ type: "object"
+ },
+ value: {
+ abc: 123
+ }
+ }
+ assertValidateOas3Param(param, [])
+
+ // valid object-as-string
+ param = {
+ schema: {
+ type: "object"
+ },
+ value: JSON.stringify({
+ abc: 123
+ })
+ }
+ assertValidateOas3Param(param, [])
+
+ // invalid object-as-string
+ param = {
+ schema: {
+ type: "object"
+ },
+ value: "{{}"
+ }
+ assertValidateOas3Param(param, ["Parameter string value must be valid JSON"])
+
+ // missing when not required
+ param = {
+ schema: {
+ type: "object"
+ },
+ }
+ assertValidateOas3Param(param, [])
+ })
+
it("validates required strings", function() {
// invalid string
param = {
@@ -962,7 +1054,7 @@ describe("utils", function() {
expect(result).toEqual(Map([[ "minimum", "b"]]))
})
})
-
+
describe("deeplyStripKey", function() {
it("should filter out a specified key", function() {
const input = {
@@ -1065,8 +1157,7 @@ describe("utils", function() {
})
it("should sanitize a `data:` url", function() {
- const res = sanitizeUrl(`data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGV
-sbG8iKTs8L3NjcmlwdD4=`)
+ const res = sanitizeUrl(`data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=`)
expect(res).toEqual("about:blank")
})