From fdb0d13089adc58bb30020e317950c823f7017e7 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Wed, 2 Aug 2017 22:07:48 -0600 Subject: [PATCH 1/9] Fixes #3511 - Update changeParameter calls to accept `in` value to identify parameters based on `name` plus `in` value --- src/core/components/param-body.jsx | 4 ++-- src/core/components/parameter-row.jsx | 8 ++++++-- src/core/components/parameters.jsx | 4 ++-- src/core/plugins/oas3/wrap-components/parameters.jsx | 2 +- src/core/plugins/spec/actions.js | 5 ++--- src/core/plugins/spec/reducers.js | 5 +++-- src/core/plugins/spec/selectors.js | 4 ++-- 7 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/core/components/param-body.jsx b/src/core/components/param-body.jsx index e64a65cc..a6fa893e 100644 --- a/src/core/components/param-body.jsx +++ b/src/core/components/param-body.jsx @@ -47,7 +47,7 @@ export default class ParamBody extends PureComponent { updateValues = (props) => { let { specSelectors, pathMethod, param, isExecute, consumesValue="" } = props - let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name")) : {} + let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) : {} let isXml = /xml/i.test(consumesValue) let isJson = /json/i.test(consumesValue) let paramValue = isXml ? parameter.get("value_xml") : parameter.get("value") @@ -105,7 +105,7 @@ export default class ParamBody extends PureComponent { const HighlightCode = getComponent("highlightCode") const ContentType = getComponent("contentType") // for domains where specSelectors not passed - let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name")) : param + let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) : param let errors = parameter.get("errors", List()) let consumesValue = specSelectors.contentTypeValues(pathMethod).get("requestContentType") let consumes = this.props.consumes && this.props.consumes.size ? this.props.consumes : ParamBody.defaultProp.consumes diff --git a/src/core/components/parameter-row.jsx b/src/core/components/parameter-row.jsx index 7db5e4ee..d8cf37b9 100644 --- a/src/core/components/parameter-row.jsx +++ b/src/core/components/parameter-row.jsx @@ -19,13 +19,17 @@ export default class ParameterRow extends Component { let { specSelectors, pathMethod, param } = props let defaultValue = param.get("default") - let parameter = specSelectors.getParameter(pathMethod, param.get("name")) + let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) let value = parameter ? parameter.get("value") : "" if ( defaultValue !== undefined && value === undefined ) { this.onChangeWrapper(defaultValue) } } + shouldComponentUpdate(nextProps) { + return nextProps.param !== this.props.param + } + componentWillReceiveProps(props) { let { specSelectors, pathMethod, param } = props let example = param.get("example") @@ -84,7 +88,7 @@ export default class ParameterRow extends Component { let isFormDataSupported = "FormData" in win let required = param.get("required") let itemType = param.getIn(["items", "type"]) - let parameter = specSelectors.getParameter(pathMethod, param.get("name")) + let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) let value = parameter ? parameter.get("value") : "" return ( diff --git a/src/core/components/parameters.jsx b/src/core/components/parameters.jsx index a6b981e6..c2cae178 100644 --- a/src/core/components/parameters.jsx +++ b/src/core/components/parameters.jsx @@ -37,7 +37,7 @@ export default class Parameters extends Component { onChangeKey, } = this.props - changeParam( onChangeKey, param.get("name"), value, isXml) + changeParam( onChangeKey, param.get("name"), param.get("in"), value, isXml) } onChangeConsumesWrapper = ( val ) => { @@ -94,7 +94,7 @@ export default class Parameters extends Component { { diff --git a/src/core/plugins/spec/actions.js b/src/core/plugins/spec/actions.js index 31671b87..3372ad61 100644 --- a/src/core/plugins/spec/actions.js +++ b/src/core/plugins/spec/actions.js @@ -128,10 +128,10 @@ export const formatIntoYaml = () => ({specActions, specSelectors}) => { } } -export function changeParam( path, paramName, value, isXml ){ +export function changeParam( path, paramName, paramIn, value, isXml ){ return { type: UPDATE_PARAM, - payload:{ path, value, paramName, isXml } + payload:{ path, value, paramName, paramIn, isXml } } } @@ -195,7 +195,6 @@ export const executeRequest = (req) => ({fn, specActions, specSelectors}) => { // if url is relative, parseUrl makes it absolute by inferring from `window.location` req.contextUrl = parseUrl(specSelectors.url()).toString() - if(op && op.operationId) { req.operationId = op.operationId } else if(op && pathName && method) { diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index d9670d7b..3ea5a30a 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -39,9 +39,10 @@ export default { }, [UPDATE_PARAM]: ( state, {payload} ) => { - let { path, paramName, value, isXml } = payload + let { path, paramName, paramIn, value, isXml } = payload + return state.updateIn( [ "resolved", "paths", ...path, "parameters" ], fromJS([]), parameters => { - const index = parameters.findIndex(p => p.get( "name" ) === paramName ) + const index = parameters.findIndex(p => p.get( "name" ) === paramName && p.get("in") === paramIn ) if (!(value instanceof win.File)) { value = fromJSOrdered( value ) } diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index fbc12764..728caf56 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -251,10 +251,10 @@ export const allowTryItOutFor = () => { } // Get the parameter value by parameter name -export function getParameter(state, pathMethod, name) { +export function getParameter(state, pathMethod, name, inType) { let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([])) return params.filter( (p) => { - return Map.isMap(p) && p.get("name") === name + return Map.isMap(p) && p.get("name") === name && p.get("in") === inType }).first() } From 51016c33f4a9c6997d65c48e5bc4ff46e99a74f1 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Wed, 2 Aug 2017 22:37:31 -0600 Subject: [PATCH 2/9] Attach `in` value to parameters map so parameters with the same name from different `in` types do not override each other. --- src/core/plugins/spec/selectors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index 728caf56..3a2cc39c 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -271,7 +271,7 @@ export function parameterValues(state, pathMethod, isXml) { let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([])) return params.reduce( (hash, p) => { let value = isXml && p.get("in") === "body" ? p.get("value_xml") : p.get("value") - return hash.set(p.get("name"), value) + return hash.set(`${p.get("name")}-${p.get("in")}`, value) }, fromJS({})) } From ce8adb91a574ce20b91722b3c92ad88b3b0d9296 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Thu, 3 Aug 2017 07:14:03 -0600 Subject: [PATCH 3/9] Fix failing selector test --- test/core/plugins/spec/selectors.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/core/plugins/spec/selectors.js b/test/core/plugins/spec/selectors.js index 7519a42e..1816f16e 100644 --- a/test/core/plugins/spec/selectors.js +++ b/test/core/plugins/spec/selectors.js @@ -29,8 +29,8 @@ describe("spec plugin - selectors", function(){ "/one": { get: { parameters: [ - { name: "one", value: 1}, - { name: "two", value: "duos"} + { name: "one", in: "query", value: 1}, + { name: "two", in: "query", value: "duos"} ] } } @@ -43,8 +43,8 @@ describe("spec plugin - selectors", function(){ // Then expect(paramValues.toJS()).toEqual({ - one: 1, - two: "duos" + "one-query": 1, + "two-query": "duos" }) }) From 7a694e287a8e0f31b985090f488078e66ecc42a1 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Thu, 3 Aug 2017 19:29:49 -0600 Subject: [PATCH 4/9] Change name format to `in.name` and update tests --- src/core/components/parameters.jsx | 2 +- src/core/plugins/spec/selectors.js | 2 +- test/core/plugins/spec/selectors.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/components/parameters.jsx b/src/core/components/parameters.jsx index c2cae178..eff94f65 100644 --- a/src/core/components/parameters.jsx +++ b/src/core/components/parameters.jsx @@ -94,7 +94,7 @@ export default class Parameters extends Component { { let value = isXml && p.get("in") === "body" ? p.get("value_xml") : p.get("value") - return hash.set(`${p.get("name")}-${p.get("in")}`, value) + return hash.set(`${p.get("in")}.${p.get("name")}`, value) }, fromJS({})) } diff --git a/test/core/plugins/spec/selectors.js b/test/core/plugins/spec/selectors.js index 1816f16e..df6b1c21 100644 --- a/test/core/plugins/spec/selectors.js +++ b/test/core/plugins/spec/selectors.js @@ -43,8 +43,8 @@ describe("spec plugin - selectors", function(){ // Then expect(paramValues.toJS()).toEqual({ - "one-query": 1, - "two-query": "duos" + "query.one": 1, + "query.two": "duos" }) }) From 85b7b7241d6e5ae55850f02bc84f08c149073599 Mon Sep 17 00:00:00 2001 From: HelderSepu Date: Tue, 19 Sep 2017 14:31:27 -0400 Subject: [PATCH 5/9] Add validateDateTime & validateGuid Initial work to tacke some of the missing validation (Issue #993) --- src/core/utils.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/core/utils.js b/src/core/utils.js index 1a835d3f..6ff31c29 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -500,12 +500,25 @@ export const validateString = ( val ) => { } } +export const validateDateTime = (val) => { + if (val && typeof val !== "string") { + return "Value must be a DateTime" + } +} + +export const validateGuid = (val) => { + if (val && typeof val !== "string") { + return "Value must be a Guid" + } +} + // validation of parameters before execute export const validateParam = (param, isXml) => { let errors = [] let value = isXml && param.get("in") === "body" ? param.get("value_xml") : param.get("value") let required = param.get("required") let type = param.get("type") + let format = param.get("format") /* If the parameter is required OR the parameter has a value (meaning optional, but filled in) @@ -528,7 +541,14 @@ export const validateParam = (param, isXml) => { } if ( type === "string" ) { - let err = validateString(value) + let err + if (format === "date-time") { + err = validateDateTime(value) + } else if (format === "uuid") { + err = validateGuid(value) + } else { + err = validateString(value) + } if (!err) return errors errors.push(err) } else if ( type === "boolean" ) { From 11768b16bfd09bf951ccd2fd9d76a3781e471527 Mon Sep 17 00:00:00 2001 From: HelderSepu Date: Fri, 22 Sep 2017 11:30:07 -0400 Subject: [PATCH 6/9] Correct IF for validateDateTime & validateGuid --- src/core/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/utils.js b/src/core/utils.js index 6ff31c29..9495d0fe 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -501,13 +501,13 @@ export const validateString = ( val ) => { } export const validateDateTime = (val) => { - if (val && typeof val !== "string") { + if (!isNaN(Date.parse(val))) { return "Value must be a DateTime" } } export const validateGuid = (val) => { - if (val && typeof val !== "string") { + if (!/^[{(]?[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}[)}]?$/.test(val)) { return "Value must be a Guid" } } From 7d9b56255c5a3a1f602482c29e5e3c03ce10076a Mon Sep 17 00:00:00 2001 From: HelderSepu Date: Fri, 22 Sep 2017 17:44:01 -0400 Subject: [PATCH 7/9] Correction to the validateDateTime --- src/core/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/utils.js b/src/core/utils.js index 9495d0fe..338399b3 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -501,7 +501,7 @@ export const validateString = ( val ) => { } export const validateDateTime = (val) => { - if (!isNaN(Date.parse(val))) { + if (isNaN(Date.parse(val))) { return "Value must be a DateTime" } } From e08f31d6747181228a3d3a9780d5a8a76f38fdef Mon Sep 17 00:00:00 2001 From: HelderSepu Date: Fri, 22 Sep 2017 21:37:33 -0400 Subject: [PATCH 8/9] Add UnitTests for validateDateTime & validateGuid --- src/core/utils.js | 2 +- test/core/utils.js | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/core/utils.js b/src/core/utils.js index 338399b3..ac633c34 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -548,7 +548,7 @@ export const validateParam = (param, isXml) => { err = validateGuid(value) } else { err = validateString(value) - } + } if (!err) return errors errors.push(err) } else if ( type === "boolean" ) { diff --git a/test/core/utils.js b/test/core/utils.js index 42103cc1..5b481e8c 100644 --- a/test/core/utils.js +++ b/test/core/utils.js @@ -1,7 +1,7 @@ /* eslint-env mocha */ import expect from "expect" import { fromJS, OrderedMap } from "immutable" -import { mapToList, validateNumber, validateInteger, validateParam, validateFile, fromJSOrdered, getAcceptControllingResponse, createDeepLinkPath, escapeDeepLinkPath } from "core/utils" +import { mapToList, validateDateTime, validateGuid, validateNumber, validateInteger, validateParam, validateFile, fromJSOrdered, getAcceptControllingResponse, createDeepLinkPath, escapeDeepLinkPath } from "core/utils" import win from "core/window" describe("utils", function() { @@ -158,7 +158,7 @@ describe("utils", function() { }) }) - describe("validateFile", function() { + describe("validateFile", function() { let errorMessage = "Value must be a file" it("validates against objects which are instances of 'File'", function() { @@ -171,6 +171,34 @@ describe("utils", function() { }) }) + describe("validateDateTime", function() { + let errorMessage = "Value must be a DateTime" + + it("doesn't return for valid dates", function() { + expect(validateFile(fileObj)).toBeFalsy() + expect(validateFile(null)).toBeFalsy() + }) + + it("returns a message for invalid input'", function() { + expect(validateFile(1)).toEqual(errorMessage) + expect(validateFile("string")).toEqual(errorMessage) + }) + }) + + describe("validateGuid", function() { + let errorMessage = "Value must be a Guid" + + it("doesn't return for valid guid", function() { + expect(validateGuid("8ce4811e-cec5-4a29-891a-15d1917153c1")).toBeFalsy() + expect(validateGuid("{8ce4811e-cec5-4a29-891a-15d1917153c1}")).toBeFalsy() + }) + + it("returns a message for invalid input'", function() { + expect(validateGuid(1)).toEqual(errorMessage) + expect(validateGuid("string")).toEqual(errorMessage) + }) + }) + describe("validateParam", function() { let param = null let result = null From 6b59707af1e4b215b67fc157bed2ab16f8b096b4 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Fri, 22 Sep 2017 19:48:51 -0700 Subject: [PATCH 9/9] Fix tests --- test/core/utils.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/core/utils.js b/test/core/utils.js index 5b481e8c..dfe5c1ee 100644 --- a/test/core/utils.js +++ b/test/core/utils.js @@ -175,13 +175,12 @@ describe("utils", function() { let errorMessage = "Value must be a DateTime" it("doesn't return for valid dates", function() { - expect(validateFile(fileObj)).toBeFalsy() - expect(validateFile(null)).toBeFalsy() + expect(validateDateTime("Mon, 25 Dec 1995 13:30:00 +0430")).toBeFalsy() }) it("returns a message for invalid input'", function() { - expect(validateFile(1)).toEqual(errorMessage) - expect(validateFile("string")).toEqual(errorMessage) + expect(validateDateTime(null)).toEqual(errorMessage) + expect(validateDateTime("string")).toEqual(errorMessage) }) })