Merge branch 'master' into webpack-migration-2.x
This commit is contained in:
@@ -143,6 +143,7 @@ parameterMacro | MUST be a function. Function to set default value to parameters
|
|||||||
modelPropertyMacro | MUST be a function. Function to set default values to each property in model. Accepts one argument modelPropertyMacro(property), property is immutable
|
modelPropertyMacro | MUST be a function. Function to set default values to each property in model. Accepts one argument modelPropertyMacro(property), property is immutable
|
||||||
docExpansion | Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). The default is 'list'.
|
docExpansion | Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). The default is 'list'.
|
||||||
displayOperationId | Controls the display of operationId in operations list. The default is `false`.
|
displayOperationId | Controls the display of operationId in operations list. The default is `false`.
|
||||||
|
displayRequestDuration | Controls the display of the request duration (in milliseconds) for `Try it out` requests. The default is `false`.
|
||||||
|
|
||||||
### Plugins
|
### Plugins
|
||||||
|
|
||||||
|
|||||||
@@ -9,28 +9,40 @@ const Headers = ( { headers } )=>{
|
|||||||
<pre>{headers}</pre>
|
<pre>{headers}</pre>
|
||||||
</div>)
|
</div>)
|
||||||
}
|
}
|
||||||
|
|
||||||
Headers.propTypes = {
|
Headers.propTypes = {
|
||||||
headers: PropTypes.array.isRequired
|
headers: PropTypes.array.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Duration = ( { duration } ) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h5>Request duration</h5>
|
||||||
|
<pre>{duration} ms</pre>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Duration.propTypes = {
|
||||||
|
duration: PropTypes.number.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export default class LiveResponse extends React.Component {
|
export default class LiveResponse extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
response: PropTypes.object.isRequired,
|
response: PropTypes.object.isRequired,
|
||||||
getComponent: PropTypes.func.isRequired
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
displayRequestDuration: PropTypes.bool.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { request, response, getComponent } = this.props
|
const { request, response, getComponent, displayRequestDuration } = this.props
|
||||||
|
|
||||||
const status = response.get("status")
|
const status = response.get("status")
|
||||||
const url = response.get("url")
|
const url = response.get("url")
|
||||||
const headers = response.get("headers").toJS()
|
const headers = response.get("headers").toJS()
|
||||||
const notDocumented = response.get("notDocumented")
|
const notDocumented = response.get("notDocumented")
|
||||||
const isError = response.get("error")
|
const isError = response.get("error")
|
||||||
|
const body = response.get("text")
|
||||||
const body = isError ? response.get("response").get("text") : response.get("text")
|
const duration = response.get("duration")
|
||||||
|
|
||||||
const headersKeys = Object.keys(headers)
|
const headersKeys = Object.keys(headers)
|
||||||
const contentType = headers["content-type"]
|
const contentType = headers["content-type"]
|
||||||
|
|
||||||
@@ -81,6 +93,9 @@ export default class LiveResponse extends React.Component {
|
|||||||
{
|
{
|
||||||
hasHeaders ? <Headers headers={ returnObject }/> : null
|
hasHeaders ? <Headers headers={ returnObject }/> : null
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
displayRequestDuration && duration ? <Duration duration={ duration } /> : null
|
||||||
|
}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -118,12 +118,13 @@ class ObjectModel extends Component {
|
|||||||
class Primitive extends Component {
|
class Primitive extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
schema: PropTypes.object.isRequired,
|
schema: PropTypes.object.isRequired,
|
||||||
|
name: PropTypes.string,
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
required: PropTypes.bool
|
required: PropTypes.bool
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
let { schema, getComponent, required } = this.props
|
let { schema, getComponent, name, required } = this.props
|
||||||
|
|
||||||
if(!schema || !schema.get) {
|
if(!schema || !schema.get) {
|
||||||
// don't render if schema isn't correctly formed
|
// don't render if schema isn't correctly formed
|
||||||
@@ -134,12 +135,18 @@ class Primitive extends Component {
|
|||||||
let format = schema.get("format")
|
let format = schema.get("format")
|
||||||
let xml = schema.get("xml")
|
let xml = schema.get("xml")
|
||||||
let enumArray = schema.get("enum")
|
let enumArray = schema.get("enum")
|
||||||
|
let title = schema.get("title") || name
|
||||||
let description = schema.get("description")
|
let description = schema.get("description")
|
||||||
let properties = schema.filter( ( v, key) => ["enum", "type", "format", "description", "$$ref"].indexOf(key) === -1 )
|
let properties = schema.filter( ( v, key) => ["enum", "type", "format", "description", "$$ref"].indexOf(key) === -1 )
|
||||||
let style = required ? { fontWeight: "bold" } : {}
|
let style = required ? { fontWeight: "bold" } : {}
|
||||||
const Markdown = getComponent("Markdown")
|
const Markdown = getComponent("Markdown")
|
||||||
|
|
||||||
return <span className="prop">
|
return <span className="model">
|
||||||
|
{
|
||||||
|
title && <span className="model-title" style={{ marginRight: "2em" }}>
|
||||||
|
<span className="model-title__text">{ title }</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
<span className="prop-type" style={ style }>{ type }</span> { required && <span style={{ color: "red" }}>*</span>}
|
<span className="prop-type" style={ style }>{ type }</span> { required && <span style={{ color: "red" }}>*</span>}
|
||||||
{ format && <span className="prop-format">(${format})</span>}
|
{ format && <span className="prop-format">(${format})</span>}
|
||||||
{
|
{
|
||||||
@@ -177,17 +184,20 @@ class ArrayModel extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
let { required, schema, depth, expandDepth } = this.props
|
let { required, schema, depth, name, expandDepth } = this.props
|
||||||
let items = schema.get("items")
|
let items = schema.get("items")
|
||||||
|
let title = schema.get("title") || name
|
||||||
let properties = schema.filter( ( v, key) => ["type", "items", "$$ref"].indexOf(key) === -1 )
|
let properties = schema.filter( ( v, key) => ["type", "items", "$$ref"].indexOf(key) === -1 )
|
||||||
|
|
||||||
return <span className="model">
|
return <span className="model">
|
||||||
<span className="model-title">
|
{
|
||||||
<span className="model-title__text">{ schema.get("title") }</span>
|
title && <span className="model-title">
|
||||||
|
<span className="model-title__text">{ title }</span>
|
||||||
</span>
|
</span>
|
||||||
|
}
|
||||||
<Collapse collapsed={ depth > expandDepth } collapsedContent="[...]">
|
<Collapse collapsed={ depth > expandDepth } collapsedContent="[...]">
|
||||||
[
|
[
|
||||||
<span><Model { ...this.props } schema={ items } required={ false }/></span>
|
<span><Model { ...this.props } name="" schema={ items } required={ false }/></span>
|
||||||
]
|
]
|
||||||
{
|
{
|
||||||
properties.size ? <span>
|
properties.size ? <span>
|
||||||
@@ -250,13 +260,13 @@ class Model extends Component {
|
|||||||
name={ name || modelName }
|
name={ name || modelName }
|
||||||
isRef={ isRef!== undefined ? isRef : !!$$ref }/>
|
isRef={ isRef!== undefined ? isRef : !!$$ref }/>
|
||||||
case "array":
|
case "array":
|
||||||
return <ArrayModel className="array" { ...this.props } schema={ modelSchema } required={ required } />
|
return <ArrayModel className="array" { ...this.props } schema={ modelSchema } name={ name || modelName } required={ required } />
|
||||||
case "string":
|
case "string":
|
||||||
case "number":
|
case "number":
|
||||||
case "integer":
|
case "integer":
|
||||||
case "boolean":
|
case "boolean":
|
||||||
default:
|
default:
|
||||||
return <Primitive getComponent={ getComponent } schema={ modelSchema } required={ required }/>
|
return <Primitive { ...this.props } getComponent={ getComponent } schema={ modelSchema } name={ name || modelName } required={ required }/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export default class Operation extends PureComponent {
|
|||||||
allowTryItOut: PropTypes.bool,
|
allowTryItOut: PropTypes.bool,
|
||||||
|
|
||||||
displayOperationId: PropTypes.bool,
|
displayOperationId: PropTypes.bool,
|
||||||
|
displayRequestDuration: PropTypes.bool,
|
||||||
|
|
||||||
response: PropTypes.object,
|
response: PropTypes.object,
|
||||||
request: PropTypes.object,
|
request: PropTypes.object,
|
||||||
@@ -38,6 +39,7 @@ export default class Operation extends PureComponent {
|
|||||||
response: null,
|
response: null,
|
||||||
allowTryItOut: true,
|
allowTryItOut: true,
|
||||||
displayOperationId: false,
|
displayOperationId: false,
|
||||||
|
displayRequestDuration: false
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
@@ -108,7 +110,7 @@ export default class Operation extends PureComponent {
|
|||||||
request,
|
request,
|
||||||
allowTryItOut,
|
allowTryItOut,
|
||||||
displayOperationId,
|
displayOperationId,
|
||||||
|
displayRequestDuration,
|
||||||
fn,
|
fn,
|
||||||
getComponent,
|
getComponent,
|
||||||
specActions,
|
specActions,
|
||||||
@@ -127,6 +129,7 @@ export default class Operation extends PureComponent {
|
|||||||
let schemes = operation.get("schemes")
|
let schemes = operation.get("schemes")
|
||||||
let parameters = getList(operation, ["parameters"])
|
let parameters = getList(operation, ["parameters"])
|
||||||
let operationId = operation.get("__originalOperationId")
|
let operationId = operation.get("__originalOperationId")
|
||||||
|
let operationScheme = specSelectors.operationScheme(path, method)
|
||||||
|
|
||||||
const Responses = getComponent("responses")
|
const Responses = getComponent("responses")
|
||||||
const Parameters = getComponent( "parameters" )
|
const Parameters = getComponent( "parameters" )
|
||||||
@@ -212,7 +215,8 @@ export default class Operation extends PureComponent {
|
|||||||
<Schemes schemes={ schemes }
|
<Schemes schemes={ schemes }
|
||||||
path={ path }
|
path={ path }
|
||||||
method={ method }
|
method={ method }
|
||||||
specActions={ specActions }/>
|
specActions={ specActions }
|
||||||
|
operationScheme={ operationScheme } />
|
||||||
</div> : null
|
</div> : null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +255,7 @@ export default class Operation extends PureComponent {
|
|||||||
produces={ produces }
|
produces={ produces }
|
||||||
producesValue={ operation.get("produces_value") }
|
producesValue={ operation.get("produces_value") }
|
||||||
pathMethod={ [path, method] }
|
pathMethod={ [path, method] }
|
||||||
|
displayRequestDuration={ displayRequestDuration }
|
||||||
fn={fn} />
|
fn={fn} />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export default class Operations extends React.Component {
|
|||||||
const Collapse = getComponent("Collapse")
|
const Collapse = getComponent("Collapse")
|
||||||
|
|
||||||
let showSummary = layoutSelectors.showSummary()
|
let showSummary = layoutSelectors.showSummary()
|
||||||
let { docExpansion, displayOperationId } = getConfigs()
|
let { docExpansion, displayOperationId, displayRequestDuration } = getConfigs()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -88,6 +88,7 @@ export default class Operations extends React.Component {
|
|||||||
allowTryItOut={allowTryItOut}
|
allowTryItOut={allowTryItOut}
|
||||||
|
|
||||||
displayOperationId={displayOperationId}
|
displayOperationId={displayOperationId}
|
||||||
|
displayRequestDuration={displayRequestDuration}
|
||||||
|
|
||||||
specActions={ specActions }
|
specActions={ specActions }
|
||||||
specSelectors={ specSelectors }
|
specSelectors={ specSelectors }
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export default class ResponseBody extends React.Component {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
content: PropTypes.any.isRequired,
|
content: PropTypes.any.isRequired,
|
||||||
contentType: PropTypes.string.isRequired,
|
contentType: PropTypes.string,
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
headers: PropTypes.object,
|
headers: PropTypes.object,
|
||||||
url: PropTypes.string
|
url: PropTypes.string
|
||||||
|
|||||||
@@ -15,19 +15,21 @@ export default class Responses extends React.Component {
|
|||||||
specSelectors: PropTypes.object.isRequired,
|
specSelectors: PropTypes.object.isRequired,
|
||||||
specActions: PropTypes.object.isRequired,
|
specActions: PropTypes.object.isRequired,
|
||||||
pathMethod: PropTypes.array.isRequired,
|
pathMethod: PropTypes.array.isRequired,
|
||||||
|
displayRequestDuration: PropTypes.bool.isRequired,
|
||||||
fn: PropTypes.object.isRequired
|
fn: PropTypes.object.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
request: null,
|
request: null,
|
||||||
tryItOutResponse: null,
|
tryItOutResponse: null,
|
||||||
produces: fromJS(["application/json"])
|
produces: fromJS(["application/json"]),
|
||||||
|
displayRequestDuration: false
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue(this.props.pathMethod, val)
|
onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue(this.props.pathMethod, val)
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { responses, request, tryItOutResponse, getComponent, specSelectors, fn, producesValue } = this.props
|
let { responses, request, tryItOutResponse, getComponent, specSelectors, fn, producesValue, displayRequestDuration } = this.props
|
||||||
let defaultCode = defaultStatusCode( responses )
|
let defaultCode = defaultStatusCode( responses )
|
||||||
|
|
||||||
const ContentType = getComponent( "contentType" )
|
const ContentType = getComponent( "contentType" )
|
||||||
@@ -54,7 +56,8 @@ export default class Responses extends React.Component {
|
|||||||
: <div>
|
: <div>
|
||||||
<LiveResponse request={ request }
|
<LiveResponse request={ request }
|
||||||
response={ tryItOutResponse }
|
response={ tryItOutResponse }
|
||||||
getComponent={ getComponent } />
|
getComponent={ getComponent }
|
||||||
|
displayRequestDuration={ displayRequestDuration } />
|
||||||
<h4>Responses</h4>
|
<h4>Responses</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ export default class Schemes extends React.Component {
|
|||||||
specActions: PropTypes.object.isRequired,
|
specActions: PropTypes.object.isRequired,
|
||||||
schemes: PropTypes.object.isRequired,
|
schemes: PropTypes.object.isRequired,
|
||||||
path: PropTypes.string,
|
path: PropTypes.string,
|
||||||
method: PropTypes.string
|
method: PropTypes.string,
|
||||||
|
operationScheme: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@@ -17,6 +18,13 @@ export default class Schemes extends React.Component {
|
|||||||
this.setScheme(schemes.first())
|
this.setScheme(schemes.first())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
if ( this.props.operationScheme && !nextProps.schemes.has(this.props.operationScheme) ) {
|
||||||
|
//fire 'change' event if our selected scheme is no longer an option
|
||||||
|
this.setScheme(nextProps.schemes.first())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onChange =( e ) => {
|
onChange =( e ) => {
|
||||||
this.setScheme( e.target.value )
|
this.setScheme( e.target.value )
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { parseSeach, filterConfigs } from "core/utils"
|
|||||||
|
|
||||||
const CONFIGS = [ "url", "urls", "urls.primaryName", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
|
const CONFIGS = [ "url", "urls", "urls.primaryName", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
|
||||||
"apisSorter", "operationsSorter", "supportedSubmitMethods", "dom_id", "defaultModelRendering", "oauth2RedirectUrl",
|
"apisSorter", "operationsSorter", "supportedSubmitMethods", "dom_id", "defaultModelRendering", "oauth2RedirectUrl",
|
||||||
"showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" ]
|
"showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" , "displayRequestDuration"]
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION } = buildInfo
|
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION } = buildInfo
|
||||||
@@ -30,6 +30,7 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
configs: {},
|
configs: {},
|
||||||
custom: {},
|
custom: {},
|
||||||
displayOperationId: false,
|
displayOperationId: false,
|
||||||
|
displayRequestDuration: false,
|
||||||
|
|
||||||
// Initial set of plugins ( TODO rename this, or refactor - we don't need presets _and_ plugins. Its just there for performance.
|
// Initial set of plugins ( TODO rename this, or refactor - we don't need presets _and_ plugins. Its just there for performance.
|
||||||
// Instead, we can compile the first plugin ( it can be a collection of plugins ), then batch the rest.
|
// Instead, we can compile the first plugin ( it can be a collection of plugins ), then batch the rest.
|
||||||
|
|||||||
@@ -207,8 +207,14 @@ export const executeRequest = (req) => ({fn, specActions, specSelectors}) => {
|
|||||||
|
|
||||||
specActions.setRequest(req.pathName, req.method, parsedRequest)
|
specActions.setRequest(req.pathName, req.method, parsedRequest)
|
||||||
|
|
||||||
|
// track duration of request
|
||||||
|
const startTime = Date.now()
|
||||||
|
|
||||||
return fn.execute(req)
|
return fn.execute(req)
|
||||||
.then( res => specActions.setResponse(req.pathName, req.method, res))
|
.then( res => {
|
||||||
|
res.duration = Date.now() - startTime
|
||||||
|
specActions.setResponse(req.pathName, req.method, res)
|
||||||
|
} )
|
||||||
.catch( err => specActions.setResponse(req.pathName, req.method, { error: true, err: serializeError(err) } ) )
|
.catch( err => specActions.setResponse(req.pathName, req.method, { error: true, err: serializeError(err) } ) )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,12 @@ export default {
|
|||||||
[SET_RESPONSE]: (state, { payload: { res, path, method } } ) =>{
|
[SET_RESPONSE]: (state, { payload: { res, path, method } } ) =>{
|
||||||
let result
|
let result
|
||||||
if ( res.error ) {
|
if ( res.error ) {
|
||||||
result = Object.assign({error: true}, res.err)
|
result = Object.assign({
|
||||||
|
error: true,
|
||||||
|
name: res.err.name,
|
||||||
|
message: res.err.message,
|
||||||
|
statusCode: res.err.statusCode
|
||||||
|
}, res.err.response)
|
||||||
} else {
|
} else {
|
||||||
result = res
|
result = res
|
||||||
}
|
}
|
||||||
@@ -86,7 +91,7 @@ export default {
|
|||||||
let newState = state.setIn( [ "responses", path, method ], fromJSOrdered(result) )
|
let newState = state.setIn( [ "responses", path, method ], fromJSOrdered(result) )
|
||||||
|
|
||||||
// ImmutableJS messes up Blob. Needs to reset its value.
|
// ImmutableJS messes up Blob. Needs to reset its value.
|
||||||
if (res.data instanceof win.Blob) {
|
if (win.Blob && res.data instanceof win.Blob) {
|
||||||
newState = newState.setIn( [ "responses", path, method, "text" ], res.data)
|
newState = newState.setIn( [ "responses", path, method, "text" ], res.data)
|
||||||
}
|
}
|
||||||
return newState
|
return newState
|
||||||
|
|||||||
@@ -450,15 +450,15 @@ export const propChecker = (props, nextProps, objectList=[], ignoreList=[]) => {
|
|||||||
|| objectList.some( objectPropName => !eq(props[objectPropName], nextProps[objectPropName])))
|
|| objectList.some( objectPropName => !eq(props[objectPropName], nextProps[objectPropName])))
|
||||||
}
|
}
|
||||||
|
|
||||||
const validateNumber = ( val ) => {
|
export const validateNumber = ( val ) => {
|
||||||
if ( !/^-?\d+(.?\d+)?$/.test(val)) {
|
if ( !/^-?\d+(\.?\d+)?$/.test(val)) {
|
||||||
return "Value must be a number"
|
return "Value must be a number"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const validateInteger = ( val ) => {
|
export const validateInteger = ( val ) => {
|
||||||
if ( !/^-?\d+$/.test(val)) {
|
if ( !/^-?\d+$/.test(val)) {
|
||||||
return "Value must be integer"
|
return "Value must be an integer"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,13 +469,14 @@ export const validateParam = (param, isXml) => {
|
|||||||
let required = param.get("required")
|
let required = param.get("required")
|
||||||
let type = param.get("type")
|
let type = param.get("type")
|
||||||
|
|
||||||
if ( required && (!value || (type==="array" && Array.isArray(value) && !value.length ))) {
|
let stringCheck = type === "string" && !value
|
||||||
|
let arrayCheck = type === "array" && Array.isArray(value) && !value.length
|
||||||
|
let listCheck = type === "array" && Im.List.isList(value) && !value.count()
|
||||||
|
if ( required && (stringCheck || arrayCheck || listCheck) ) {
|
||||||
errors.push("Required field is not provided")
|
errors.push("Required field is not provided")
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !value ) return errors
|
|
||||||
|
|
||||||
if ( type === "number" ) {
|
if ( type === "number" ) {
|
||||||
let err = validateNumber(value)
|
let err = validateNumber(value)
|
||||||
if (!err) return errors
|
if (!err) return errors
|
||||||
|
|||||||
@@ -69,4 +69,56 @@ describe("spec plugin - reducer", function(){
|
|||||||
expect(result.toJS()).toEqual(state.toJS())
|
expect(result.toJS()).toEqual(state.toJS())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("set response value", function() {
|
||||||
|
it("should combine the response and error objects", () => {
|
||||||
|
const setResponse = reducer["spec_set_response"]
|
||||||
|
|
||||||
|
const path = "/pet/post"
|
||||||
|
const method = "POST"
|
||||||
|
|
||||||
|
const state = fromJS({})
|
||||||
|
const result = setResponse(state, {
|
||||||
|
payload: {
|
||||||
|
path: path,
|
||||||
|
method: method,
|
||||||
|
res: {
|
||||||
|
error: true,
|
||||||
|
err: {
|
||||||
|
message: "Not Found",
|
||||||
|
name: "Error",
|
||||||
|
response: {
|
||||||
|
data: "response data",
|
||||||
|
headers: {
|
||||||
|
key: "value"
|
||||||
|
},
|
||||||
|
ok: false,
|
||||||
|
status: 404,
|
||||||
|
statusText: "Not Found"
|
||||||
|
},
|
||||||
|
status: 404,
|
||||||
|
statusCode: 404
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let expectedResult = {
|
||||||
|
error: true,
|
||||||
|
message: "Not Found",
|
||||||
|
name: "Error",
|
||||||
|
data: "response data",
|
||||||
|
headers: {
|
||||||
|
key: "value"
|
||||||
|
},
|
||||||
|
ok: false,
|
||||||
|
status: 404,
|
||||||
|
statusCode: 404,
|
||||||
|
statusText: "Not Found"
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = result.getIn(["responses", path, method]).toJS()
|
||||||
|
expect(response).toEqual(expectedResult)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-env mocha */
|
/* eslint-env mocha */
|
||||||
import expect from "expect"
|
import expect from "expect"
|
||||||
import { fromJS } from "immutable"
|
import { fromJS } from "immutable"
|
||||||
import { mapToList } from "core/utils"
|
import { mapToList, validateNumber, validateInteger, validateParam } from "core/utils"
|
||||||
|
|
||||||
describe("utils", function(){
|
describe("utils", function(){
|
||||||
|
|
||||||
@@ -67,9 +67,181 @@ describe("utils", function(){
|
|||||||
|
|
||||||
// Then
|
// Then
|
||||||
expect(aList.toJS()).toEqual([])
|
expect(aList.toJS()).toEqual([])
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("validateNumber", function() {
|
||||||
|
let errorMessage = "Value must be a number"
|
||||||
|
|
||||||
|
it("doesn't return for whole numbers", function() {
|
||||||
|
expect(validateNumber(0)).toBeFalsy()
|
||||||
|
expect(validateNumber(1)).toBeFalsy()
|
||||||
|
expect(validateNumber(20)).toBeFalsy()
|
||||||
|
expect(validateNumber(5000000)).toBeFalsy()
|
||||||
|
expect(validateNumber("1")).toBeFalsy()
|
||||||
|
expect(validateNumber("2")).toBeFalsy()
|
||||||
|
expect(validateNumber(-1)).toBeFalsy()
|
||||||
|
expect(validateNumber(-20)).toBeFalsy()
|
||||||
|
expect(validateNumber(-5000000)).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("doesn't return for negative numbers", function() {
|
||||||
|
expect(validateNumber(-1)).toBeFalsy()
|
||||||
|
expect(validateNumber(-20)).toBeFalsy()
|
||||||
|
expect(validateNumber(-5000000)).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("doesn't return for decimal numbers", function() {
|
||||||
|
expect(validateNumber(1.1)).toBeFalsy()
|
||||||
|
expect(validateNumber(2.5)).toBeFalsy()
|
||||||
|
expect(validateNumber(-30.99)).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns a message for strings", function() {
|
||||||
|
expect(validateNumber("")).toEqual(errorMessage)
|
||||||
|
expect(validateNumber(" ")).toEqual(errorMessage)
|
||||||
|
expect(validateNumber("test")).toEqual(errorMessage)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns a message for invalid input", function() {
|
||||||
|
expect(validateNumber(undefined)).toEqual(errorMessage)
|
||||||
|
expect(validateNumber(null)).toEqual(errorMessage)
|
||||||
|
expect(validateNumber({})).toEqual(errorMessage)
|
||||||
|
expect(validateNumber([])).toEqual(errorMessage)
|
||||||
|
expect(validateNumber(true)).toEqual(errorMessage)
|
||||||
|
expect(validateNumber(false)).toEqual(errorMessage)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("validateInteger", function() {
|
||||||
|
let errorMessage = "Value must be an integer"
|
||||||
|
|
||||||
|
it("doesn't return for positive integers", function() {
|
||||||
|
expect(validateInteger(0)).toBeFalsy()
|
||||||
|
expect(validateInteger(1)).toBeFalsy()
|
||||||
|
expect(validateInteger(20)).toBeFalsy()
|
||||||
|
expect(validateInteger(5000000)).toBeFalsy()
|
||||||
|
expect(validateInteger("1")).toBeFalsy()
|
||||||
|
expect(validateInteger("2")).toBeFalsy()
|
||||||
|
expect(validateInteger(-1)).toBeFalsy()
|
||||||
|
expect(validateInteger(-20)).toBeFalsy()
|
||||||
|
expect(validateInteger(-5000000)).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("doesn't return for negative integers", function() {
|
||||||
|
expect(validateInteger(-1)).toBeFalsy()
|
||||||
|
expect(validateInteger(-20)).toBeFalsy()
|
||||||
|
expect(validateInteger(-5000000)).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns a message for decimal values", function() {
|
||||||
|
expect(validateInteger(1.1)).toEqual(errorMessage)
|
||||||
|
expect(validateInteger(2.5)).toEqual(errorMessage)
|
||||||
|
expect(validateInteger(-30.99)).toEqual(errorMessage)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns a message for strings", function() {
|
||||||
|
expect(validateInteger("")).toEqual(errorMessage)
|
||||||
|
expect(validateInteger(" ")).toEqual(errorMessage)
|
||||||
|
expect(validateInteger("test")).toEqual(errorMessage)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns a message for invalid input", function() {
|
||||||
|
expect(validateInteger(undefined)).toEqual(errorMessage)
|
||||||
|
expect(validateInteger(null)).toEqual(errorMessage)
|
||||||
|
expect(validateInteger({})).toEqual(errorMessage)
|
||||||
|
expect(validateInteger([])).toEqual(errorMessage)
|
||||||
|
expect(validateInteger(true)).toEqual(errorMessage)
|
||||||
|
expect(validateInteger(false)).toEqual(errorMessage)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("validateParam", function() {
|
||||||
|
let param = null
|
||||||
|
let result = null
|
||||||
|
|
||||||
|
it("validates required strings", function() {
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "string",
|
||||||
|
value: ""
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates required arrays", function() {
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "array",
|
||||||
|
value: []
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "array",
|
||||||
|
value: []
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates numbers", function() {
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "number",
|
||||||
|
value: "test"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Value must be a number"] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates integers", function() {
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "integer",
|
||||||
|
value: "test"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Value must be an integer"] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates arrays", function() {
|
||||||
|
// empty array
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "array",
|
||||||
|
value: []
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
|
||||||
|
// numbers
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "array",
|
||||||
|
value: ["number"],
|
||||||
|
items: {
|
||||||
|
type: "number"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [{index: 0, error: "Value must be a number"}] )
|
||||||
|
|
||||||
|
// integers
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "array",
|
||||||
|
value: ["not", "numbers"],
|
||||||
|
items: {
|
||||||
|
type: "integer"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [{index: 0, error: "Value must be an integer"}, {index: 1, error: "Value must be an integer"}] )
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user