feature: allowEmptyValue controls (#4788)
* add baseline tests * coerce empty strings to null when updating parameter values * add ParameterIncludeEmpty * add redux management for empty parameter value inclusion state * use name+in keying for state management instead of hash keying * update new redux method usages to name+in keying * coerce empty Immutable iterables in onChangeWrapper * OAS3 tests & support * add included empty parameters to requests before dispatching to Swagger Client * make empty inclusion interface prettier * add tests for #4587 * linter fixes * check for truthy value before reaching into property
This commit is contained in:
27
src/core/components/parameter-include-empty.jsx
Normal file
27
src/core/components/parameter-include-empty.jsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from "react"
|
||||
import cx from "classnames"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
|
||||
export const ParameterIncludeEmpty = ({ param, isIncluded, onChange, isDisabled }) => {
|
||||
const onCheckboxChange = e => {
|
||||
onChange(e.target.checked)
|
||||
}
|
||||
if(!param.get("allowEmptyValue")) {
|
||||
return null
|
||||
}
|
||||
return <div className={cx("parameter__empty_value_toggle", {
|
||||
"disabled": isDisabled
|
||||
})}>
|
||||
<input type="checkbox" disabled={isDisabled} checked={!isDisabled && isIncluded} onChange={onCheckboxChange} />
|
||||
Send empty value
|
||||
</div>
|
||||
}
|
||||
ParameterIncludeEmpty.propTypes = {
|
||||
param: ImPropTypes.map.isRequired,
|
||||
isIncluded: PropTypes.bool.isRequired,
|
||||
isDisabled: PropTypes.bool.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
export default ParameterIncludeEmpty
|
||||
@@ -15,6 +15,7 @@ export default class ParameterRow extends Component {
|
||||
isExecute: PropTypes.bool,
|
||||
onChangeConsumes: PropTypes.func.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
specActions: PropTypes.object.isRequired,
|
||||
pathMethod: PropTypes.array.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specPath: ImPropTypes.list.isRequired
|
||||
@@ -61,7 +62,23 @@ export default class ParameterRow extends Component {
|
||||
|
||||
onChangeWrapper = (value, isXml = false) => {
|
||||
let { onChange, rawParam } = this.props
|
||||
return onChange(rawParam, value, isXml)
|
||||
let valueForUpstream
|
||||
|
||||
// Coerce empty strings and empty Immutable objects to null
|
||||
if(value === "" || (value && value.size === 0)) {
|
||||
valueForUpstream = null
|
||||
} else {
|
||||
valueForUpstream = value
|
||||
}
|
||||
|
||||
return onChange(rawParam, valueForUpstream, isXml)
|
||||
}
|
||||
|
||||
onChangeIncludeEmpty = (newValue) => {
|
||||
let { specActions, param, pathMethod } = this.props
|
||||
const paramName = param.get("name")
|
||||
const paramIn = param.get("in")
|
||||
return specActions.updateEmptyParamInclusion(pathMethod, paramName, paramIn, newValue)
|
||||
}
|
||||
|
||||
setDefaultValue = () => {
|
||||
@@ -120,6 +137,7 @@ export default class ParameterRow extends Component {
|
||||
const ModelExample = getComponent("modelExample")
|
||||
const Markdown = getComponent("Markdown")
|
||||
const ParameterExt = getComponent("ParameterExt")
|
||||
const ParameterIncludeEmpty = getComponent("ParameterIncludeEmpty")
|
||||
|
||||
let paramWithMeta = specSelectors.parameterWithMetaByIdentity(pathMethod, rawParam)
|
||||
let format = param.get("format")
|
||||
@@ -225,6 +243,16 @@ export default class ParameterRow extends Component {
|
||||
: null
|
||||
}
|
||||
|
||||
{
|
||||
!bodyParam && isExecute ?
|
||||
<ParameterIncludeEmpty
|
||||
onChange={this.onChangeIncludeEmpty}
|
||||
isIncluded={specSelectors.parameterInclusionSettingFor(pathMethod, param.get("name"), param.get("in"))}
|
||||
isDisabled={value && value.size !== 0}
|
||||
param={param} />
|
||||
: null
|
||||
}
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
@@ -65,7 +65,8 @@ export default class Parameters extends Component {
|
||||
fn,
|
||||
getComponent,
|
||||
getConfigs,
|
||||
specSelectors,
|
||||
specSelectors,
|
||||
specActions,
|
||||
pathMethod
|
||||
} = this.props
|
||||
|
||||
@@ -107,6 +108,7 @@ export default class Parameters extends Component {
|
||||
onChange={ this.onChange }
|
||||
onChangeConsumes={this.onChangeConsumesWrapper}
|
||||
specSelectors={ specSelectors }
|
||||
specActions={specActions}
|
||||
pathMethod={ pathMethod }
|
||||
isExecute={ isExecute }/>
|
||||
)).toArray()
|
||||
|
||||
@@ -90,6 +90,7 @@ class Parameters extends Component {
|
||||
getComponent,
|
||||
getConfigs,
|
||||
specSelectors,
|
||||
specActions,
|
||||
oas3Actions,
|
||||
oas3Selectors,
|
||||
pathMethod,
|
||||
@@ -151,6 +152,7 @@ class Parameters extends Component {
|
||||
onChange={ this.onChange }
|
||||
onChangeConsumes={this.onChangeConsumesWrapper}
|
||||
specSelectors={ specSelectors }
|
||||
specActions={ specActions }
|
||||
pathMethod={ pathMethod }
|
||||
isExecute={ isExecute }/>
|
||||
)).toArray()
|
||||
|
||||
@@ -14,6 +14,7 @@ export const UPDATE_SPEC = "spec_update_spec"
|
||||
export const UPDATE_URL = "spec_update_url"
|
||||
export const UPDATE_JSON = "spec_update_json"
|
||||
export const UPDATE_PARAM = "spec_update_param"
|
||||
export const UPDATE_EMPTY_PARAM_INCLUSION = "spec_update_empty_param_inclusion"
|
||||
export const VALIDATE_PARAMS = "spec_validate_param"
|
||||
export const SET_RESPONSE = "spec_set_response"
|
||||
export const SET_REQUEST = "spec_set_request"
|
||||
@@ -270,6 +271,18 @@ export const validateParams = ( payload, isOAS3 ) =>{
|
||||
}
|
||||
}
|
||||
|
||||
export const updateEmptyParamInclusion = ( pathMethod, paramName, paramIn, includeEmptyValue ) =>{
|
||||
return {
|
||||
type: UPDATE_EMPTY_PARAM_INCLUSION,
|
||||
payload:{
|
||||
pathMethod,
|
||||
paramName,
|
||||
paramIn,
|
||||
includeEmptyValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function clearValidateParams( payload ){
|
||||
return {
|
||||
type: CLEAR_VALIDATE_PARAMS,
|
||||
@@ -327,7 +340,28 @@ export const executeRequest = (req) =>
|
||||
let { pathName, method, operation } = req
|
||||
let { requestInterceptor, responseInterceptor } = getConfigs()
|
||||
|
||||
|
||||
let op = operation.toJS()
|
||||
|
||||
// ensure that explicitly-included params are in the request
|
||||
|
||||
if(op && op.parameters && op.parameters.length) {
|
||||
op.parameters
|
||||
.filter(param => param && param.allowEmptyValue === true)
|
||||
.forEach(param => {
|
||||
if (specSelectors.parameterInclusionSettingFor([pathName, method], param.name, param.in)) {
|
||||
req.parameters = req.parameters || {}
|
||||
const paramValue = req.parameters[param.name]
|
||||
|
||||
// if the value is falsy or an empty Immutable iterable...
|
||||
if(!paramValue || (paramValue && paramValue.size === 0)) {
|
||||
// set it to empty string, so Swagger Client will treat it as
|
||||
// present but empty.
|
||||
req.parameters[param.name] = ""
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// if url is relative, parseUrl makes it absolute by inferring from `window.location`
|
||||
req.contextUrl = parseUrl(specSelectors.url()).toString()
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
UPDATE_URL,
|
||||
UPDATE_JSON,
|
||||
UPDATE_PARAM,
|
||||
UPDATE_EMPTY_PARAM_INCLUSION,
|
||||
VALIDATE_PARAMS,
|
||||
SET_RESPONSE,
|
||||
SET_REQUEST,
|
||||
@@ -70,6 +71,22 @@ export default {
|
||||
)
|
||||
},
|
||||
|
||||
[UPDATE_EMPTY_PARAM_INCLUSION]: ( state, {payload} ) => {
|
||||
let { pathMethod, paramName, paramIn, includeEmptyValue } = payload
|
||||
|
||||
if(!paramName || !paramIn) {
|
||||
console.warn("Warning: UPDATE_EMPTY_PARAM_INCLUSION could not generate a paramKey.")
|
||||
return state
|
||||
}
|
||||
|
||||
const paramKey = `${paramName}.${paramIn}`
|
||||
|
||||
return state.setIn(
|
||||
["meta", "paths", ...pathMethod, "parameter_inclusions", paramKey],
|
||||
includeEmptyValue
|
||||
)
|
||||
},
|
||||
|
||||
[VALIDATE_PARAMS]: ( state, { payload: { pathMethod, isOAS3 } } ) => {
|
||||
let meta = state.getIn( [ "meta", "paths", ...pathMethod ], fromJS({}) )
|
||||
let isXml = /xml/i.test(meta.get("consumes_value"))
|
||||
|
||||
@@ -311,6 +311,11 @@ export const parameterWithMetaByIdentity = (state, pathMethod, param) => {
|
||||
return mergedParams.find(curr => curr.get("in") === param.get("in") && curr.get("name") === param.get("name"), OrderedMap())
|
||||
}
|
||||
|
||||
export const parameterInclusionSettingFor = (state, pathMethod, paramName, paramIn) => {
|
||||
const paramKey = `${paramName}.${paramIn}`
|
||||
return state.getIn(["meta", "paths", ...pathMethod, "parameter_inclusions", paramKey], false)
|
||||
}
|
||||
|
||||
|
||||
export const parameterWithMeta = (state, pathMethod, paramName, paramIn) => {
|
||||
const opParams = specJsonWithResolvedSubtrees(state).getIn(["paths", ...pathMethod, "parameters"], OrderedMap())
|
||||
|
||||
@@ -42,6 +42,7 @@ import Response from "core/components/response"
|
||||
import ResponseBody from "core/components/response-body"
|
||||
import Parameters from "core/components/parameters"
|
||||
import ParameterExt from "core/components/parameter-extension"
|
||||
import ParameterIncludeEmpty from "core/components/parameter-include-empty"
|
||||
import ParameterRow from "core/components/parameter-row"
|
||||
import Execute from "core/components/execute"
|
||||
import Headers from "core/components/headers"
|
||||
@@ -143,6 +144,7 @@ export default function() {
|
||||
OperationExt,
|
||||
OperationExtRow,
|
||||
ParameterExt,
|
||||
ParameterIncludeEmpty,
|
||||
OperationTag,
|
||||
OperationContainer,
|
||||
DeepLink,
|
||||
|
||||
@@ -139,6 +139,20 @@ table
|
||||
@include text_code($table-parameter-deprecated-font-color);
|
||||
}
|
||||
|
||||
.parameter__empty_value_toggle {
|
||||
font-size: 13px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 12px;
|
||||
|
||||
input {
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.table-container
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-env mocha */
|
||||
import expect, { createSpy } from "expect"
|
||||
import { fromJS } from "immutable"
|
||||
import { execute, executeRequest, changeParamByIdentity } from "corePlugins/spec/actions"
|
||||
import { execute, executeRequest, changeParamByIdentity, updateEmptyParamInclusion } from "corePlugins/spec/actions"
|
||||
|
||||
describe("spec plugin - actions", function(){
|
||||
|
||||
@@ -207,4 +207,22 @@ describe("spec plugin - actions", function(){
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("updateEmptyParamInclusion", function () {
|
||||
it("should map its arguments to a payload", function () {
|
||||
const pathMethod = ["/one", "get"]
|
||||
|
||||
const result = updateEmptyParamInclusion(pathMethod, "param", "query", true)
|
||||
|
||||
expect(result).toEqual({
|
||||
type: "spec_update_empty_param_inclusion",
|
||||
payload: {
|
||||
pathMethod,
|
||||
paramName: "param",
|
||||
paramIn: "query",
|
||||
includeEmptyValue: true
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -178,4 +178,26 @@ describe("spec plugin - reducer", function(){
|
||||
expect(value).toEqual(`{ "a": 123 }`)
|
||||
})
|
||||
})
|
||||
describe("SPEC_UPDATE_EMPTY_PARAM_INCLUSION", function() {
|
||||
it("should store parameter values by name+in", () => {
|
||||
const updateParam = reducer["spec_update_empty_param_inclusion"]
|
||||
|
||||
const path = "/pet/post"
|
||||
const method = "POST"
|
||||
|
||||
const state = fromJS({})
|
||||
|
||||
const result = updateParam(state, {
|
||||
payload: {
|
||||
pathMethod: [path, method],
|
||||
paramName: "param",
|
||||
paramIn: "query",
|
||||
includeEmptyValue: true
|
||||
}
|
||||
})
|
||||
|
||||
const response = result.getIn(["meta", "paths", path, method, "parameter_inclusions", "param.query"])
|
||||
expect(response).toEqual(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -14,7 +14,8 @@ import Petstore from "./assets/petstore.json"
|
||||
import {
|
||||
operationWithMeta,
|
||||
parameterWithMeta,
|
||||
parameterWithMetaByIdentity
|
||||
parameterWithMetaByIdentity,
|
||||
parameterInclusionSettingFor
|
||||
} from "../../../../src/core/plugins/spec/selectors"
|
||||
|
||||
describe("spec plugin - selectors", function(){
|
||||
@@ -712,4 +713,42 @@ describe("spec plugin - selectors", function(){
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("parameterInclusionSettingFor", function() {
|
||||
it("should support getting name+in param inclusion settings", function () {
|
||||
const param = fromJS({
|
||||
name: "param",
|
||||
in: "query",
|
||||
allowEmptyValue: true
|
||||
})
|
||||
|
||||
const state = fromJS({
|
||||
json: {
|
||||
paths: {
|
||||
"/": {
|
||||
"get": {
|
||||
parameters: [
|
||||
param
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
meta: {
|
||||
paths: {
|
||||
"/": {
|
||||
"get": {
|
||||
"parameter_inclusions": {
|
||||
[`param.query`]: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const result = parameterInclusionSettingFor(state, ["/", "get"], "param", "query")
|
||||
|
||||
expect(result).toEqual(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
36
test/e2e/scenarios/bugs/4587.js
Normal file
36
test/e2e/scenarios/bugs/4587.js
Normal file
@@ -0,0 +1,36 @@
|
||||
describe("bug #4587: clearing header param values", function () {
|
||||
let mainPage
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input:not([disabled])", 5000)
|
||||
.pause(2000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/bugs/4587.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
|
||||
it("sets a required initial value based the first enum value", function (client) {
|
||||
client.waitForElementVisible(".opblock-tag-section", 10000)
|
||||
.click("#operations-sql-execSql")
|
||||
.waitForElementVisible(".opblock.is-open", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.setValue(`tr[data-param-name="x-irest-conn"] input`, "hi")
|
||||
.click("button.btn.execute")
|
||||
.waitForElementVisible(".request-url", 2000)
|
||||
.setValue(`tr[data-param-name="x-irest-conn"] input`, `\u0008\u0008\u0008`) // backspaces
|
||||
.pause(900)
|
||||
.click("button.btn.execute")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.not.contain(`x-irest-conn`)
|
||||
})
|
||||
})
|
||||
433
test/e2e/scenarios/features/allow-empty-value.openapi.js
Normal file
433
test/e2e/scenarios/features/allow-empty-value.openapi.js
Normal file
@@ -0,0 +1,433 @@
|
||||
describe("feature: OpenAPI 3 allowEmptyValue", function () {
|
||||
beforeEach(function (client, done) {
|
||||
client
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input:not([disabled])", 5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "/test-specs/features/allow-empty-value.openapi.yaml")
|
||||
.click("button.download-url-button")
|
||||
.waitForElementVisible(".opblock", 10000)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
|
||||
describe("regular parameters", function () {
|
||||
it("should set and unset an integer value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="int"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_regularParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/regularParams"`)
|
||||
})
|
||||
it("should set and unset a string value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="str"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_regularParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/regularParams"`)
|
||||
})
|
||||
it("should set and unset a number value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="num"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_regularParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/regularParams"`)
|
||||
})
|
||||
it("should set and unset a boolean value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="bool"] select`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_regularParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${inputSelector} [value="true"]`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.click(`${inputSelector} [value=""]`)
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/regularParams"`)
|
||||
})
|
||||
it("should set and unset an array value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="arr"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_regularParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${inputSelector} .json-schema-form-item-add`)
|
||||
.setValue(`${inputSelector} input`, "asdf")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.click(`${inputSelector} .json-schema-form-item-remove`)
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/regularParams"`)
|
||||
})
|
||||
})
|
||||
|
||||
describe("allowEmptyValue parameters", function () {
|
||||
describe("normal behavior", function () {
|
||||
it("should set and unset an integer value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="int"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams"`)
|
||||
})
|
||||
it("should set and unset a string value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="str"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams"`)
|
||||
})
|
||||
it("should set and unset a number value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="num"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams"`)
|
||||
})
|
||||
it("should set and unset a boolean value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="bool"] select`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${inputSelector} [value="true"]`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.click(`${inputSelector} [value=""]`)
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams"`)
|
||||
})
|
||||
it("should set and unset an array value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="arr"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${inputSelector} .json-schema-form-item-add`)
|
||||
.setValue(`${inputSelector} input`, "asdf")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.click(`${inputSelector} .json-schema-form-item-remove`)
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams"`)
|
||||
})
|
||||
})
|
||||
describe("send empty inital value behavior", function () {
|
||||
it("should send an empty integer value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="int"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // tick "send empty value" box and execute
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?int="`)
|
||||
})
|
||||
it("should send an empty string value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="str"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // tick "send empty value" box and execute
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?str="`)
|
||||
})
|
||||
it("should send an empty number value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="num"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // tick "send empty value" box and execute
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?num="`)
|
||||
})
|
||||
it("should send an empty boolean value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="bool"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // tick "send empty value" box and execute
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?bool="`)
|
||||
})
|
||||
it("should send an empty array value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="arr"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // tick "send empty value" box and execute
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?arr="`)
|
||||
})
|
||||
})
|
||||
describe("modify and send empty behavior", function () {
|
||||
it("should set, unset and send an empty integer value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="int"]`
|
||||
const inputSelector = `${paramSelector} input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, click "send empty", execute again, assert
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(400)
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?int="`)
|
||||
})
|
||||
it("should set, unset and send an empty string value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="str"]`
|
||||
const inputSelector = `${paramSelector} input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, click "send empty", execute again, assert
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(400)
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?str="`)
|
||||
})
|
||||
it("should set, unset and send an empty number value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="num"]`
|
||||
const inputSelector = `${paramSelector} input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, click "send empty", execute again, assert
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(400)
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?num="`)
|
||||
})
|
||||
it("should set, unset and send an empty boolean value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="bool"]`
|
||||
const inputSelector = `${paramSelector} select`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${inputSelector} option[value="true"]`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, click "send empty", execute again, assert
|
||||
.click(`${inputSelector} option[value=""]`)
|
||||
.pause(400)
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?bool="`)
|
||||
})
|
||||
it("should set, unset and send an empty array value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="arr"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${paramSelector} .json-schema-form-item-add`)
|
||||
.setValue(`${paramSelector} input`, "asdf")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.click(`${paramSelector} .json-schema-form-item-remove`)
|
||||
.pause(400)
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?arr="`)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
433
test/e2e/scenarios/features/allow-empty-value.swagger.js
Normal file
433
test/e2e/scenarios/features/allow-empty-value.swagger.js
Normal file
@@ -0,0 +1,433 @@
|
||||
describe("feature: Swagger 2 allowEmptyValue", function () {
|
||||
beforeEach(function (client, done) {
|
||||
client
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input:not([disabled])", 5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "/test-specs/features/allow-empty-value.swagger.yaml")
|
||||
.click("button.download-url-button")
|
||||
.waitForElementVisible(".opblock", 10000)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
|
||||
describe("regular parameters", function () {
|
||||
it("should set and unset an integer value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="int"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_regularParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/regularParams"`)
|
||||
})
|
||||
it("should set and unset a string value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="str"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_regularParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/regularParams"`)
|
||||
})
|
||||
it("should set and unset a number value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="num"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_regularParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/regularParams"`)
|
||||
})
|
||||
it("should set and unset a boolean value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="bool"] select`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_regularParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${inputSelector} [value="true"]`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.click(`${inputSelector} [value=""]`)
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/regularParams"`)
|
||||
})
|
||||
it("should set and unset an array value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="arr"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_regularParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${inputSelector} .json-schema-form-item-add`)
|
||||
.setValue(`${inputSelector} input`, "asdf")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.click(`${inputSelector} .json-schema-form-item-remove`)
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/regularParams"`)
|
||||
})
|
||||
})
|
||||
|
||||
describe("allowEmptyValue parameters", function () {
|
||||
describe("normal behavior", function () {
|
||||
it("should set and unset an integer value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="int"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams"`)
|
||||
})
|
||||
it("should set and unset a string value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="str"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams"`)
|
||||
})
|
||||
it("should set and unset a number value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="num"] input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams"`)
|
||||
})
|
||||
it("should set and unset a boolean value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="bool"] select`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${inputSelector} [value="true"]`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.click(`${inputSelector} [value=""]`)
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams"`)
|
||||
})
|
||||
it("should set and unset an array value", function (client) {
|
||||
const inputSelector = `tr[data-param-name="arr"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${inputSelector} .json-schema-form-item-add`)
|
||||
.setValue(`${inputSelector} input`, "asdf")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.click(`${inputSelector} .json-schema-form-item-remove`)
|
||||
.pause(200)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams"`)
|
||||
})
|
||||
})
|
||||
describe("send empty inital value behavior", function () {
|
||||
it("should send an empty integer value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="int"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // tick "send empty value" box and execute
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?int="`)
|
||||
})
|
||||
it("should send an empty string value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="str"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // tick "send empty value" box and execute
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?str="`)
|
||||
})
|
||||
it("should send an empty number value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="num"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // tick "send empty value" box and execute
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?num="`)
|
||||
})
|
||||
it("should send an empty boolean value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="bool"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // tick "send empty value" box and execute
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?bool="`)
|
||||
})
|
||||
it("should send an empty array value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="arr"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // tick "send empty value" box and execute
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?arr="`)
|
||||
})
|
||||
})
|
||||
describe("modify and send empty behavior", function () {
|
||||
it("should set, unset and send an empty integer value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="int"]`
|
||||
const inputSelector = `${paramSelector} input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, click "send empty", execute again, assert
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(400)
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?int="`)
|
||||
})
|
||||
it("should set, unset and send an empty string value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="str"]`
|
||||
const inputSelector = `${paramSelector} input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, click "send empty", execute again, assert
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(400)
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?str="`)
|
||||
})
|
||||
it("should set, unset and send an empty number value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="num"]`
|
||||
const inputSelector = `${paramSelector} input`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.setValue(inputSelector, "123")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, click "send empty", execute again, assert
|
||||
.setValue(inputSelector, "\u0008\u0008\u0008") // backspaces
|
||||
.pause(400)
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?num="`)
|
||||
})
|
||||
it("should set, unset and send an empty boolean value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="bool"]`
|
||||
const inputSelector = `${paramSelector} select`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${inputSelector} option[value="true"]`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, click "send empty", execute again, assert
|
||||
.click(`${inputSelector} option[value=""]`)
|
||||
.pause(400)
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?bool="`)
|
||||
})
|
||||
it("should set, unset and send an empty array value", function (client) {
|
||||
const paramSelector = `tr[data-param-name="arr"]`
|
||||
|
||||
client // open try-it-out
|
||||
.click("#operations-default-get_emptyValueParams")
|
||||
.waitForElementVisible("button.btn.try-out__btn", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.pause(200)
|
||||
|
||||
client // set parameter, to ensure an initial value is set
|
||||
.click(`${paramSelector} .json-schema-form-item-add`)
|
||||
.setValue(`${paramSelector} input`, "asdf")
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.pause(200)
|
||||
|
||||
client // remove initial value, execute again
|
||||
.click(`${paramSelector} .json-schema-form-item-remove`)
|
||||
.pause(400)
|
||||
.click(`${paramSelector} .parameter__empty_value_toggle input`)
|
||||
.click("button.btn.execute.opblock-control__btn")
|
||||
.expect.element("textarea.curl").text
|
||||
.to.contain(`GET "http://localhost:3230/emptyValueParams?arr="`)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
126
test/e2e/specs/bugs/4587.yaml
Normal file
126
test/e2e/specs/bugs/4587.yaml
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
swagger: '2.0'
|
||||
info:
|
||||
version: 0.0.1
|
||||
title: DDErl REST interface
|
||||
description: RESTful access to IMEM DB and DDErl
|
||||
schemes:
|
||||
- http
|
||||
- https
|
||||
securityDefinitions:
|
||||
basicAuth:
|
||||
type: basic
|
||||
description: HTTP Basic Authentication Username:Password
|
||||
basePath: "/dderlrest/0.0.1"
|
||||
paths:
|
||||
"/sql/":
|
||||
get:
|
||||
tags:
|
||||
- sql
|
||||
security:
|
||||
- basicAuth: []
|
||||
summary: execute sql
|
||||
operationId: execSql
|
||||
description: Prepare and execute SQL statements
|
||||
parameters:
|
||||
- name: x-irest-conn
|
||||
in: header
|
||||
required: false
|
||||
description: ErlImem connection identifier
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
schema:
|
||||
type: object
|
||||
headers:
|
||||
x-irest-conn:
|
||||
description: ErlImem connection identifier
|
||||
type: string
|
||||
'403':
|
||||
description: Malformed/Invalid
|
||||
schema:
|
||||
"$ref": "#/definitions/ErrorResponse"
|
||||
definitions:
|
||||
ErrorResponse:
|
||||
readOnly: true
|
||||
type: object
|
||||
required:
|
||||
- errorCode
|
||||
- errorMessage
|
||||
- errorDetails
|
||||
properties:
|
||||
errorCode:
|
||||
description: Error Code
|
||||
type: number
|
||||
example: 1400
|
||||
errorMessage:
|
||||
description: Error Message
|
||||
type: string
|
||||
example: malformed
|
||||
errorDetails:
|
||||
description: Error Details
|
||||
type: string
|
||||
example: mandatory properties missing or bad type
|
||||
ViewParams:
|
||||
readOnly: true
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- typ
|
||||
- value
|
||||
- name
|
||||
properties:
|
||||
name:
|
||||
description: Name
|
||||
type: string
|
||||
example: ":atom_user"
|
||||
value:
|
||||
description: Value
|
||||
type: string
|
||||
example: system
|
||||
typ:
|
||||
description: Datatype
|
||||
type: string
|
||||
enum:
|
||||
- atom
|
||||
- binary
|
||||
- raw
|
||||
- blob
|
||||
- rowid
|
||||
- binstr
|
||||
- clob
|
||||
- nclob
|
||||
- varchar2
|
||||
- nvarchar2
|
||||
- char
|
||||
- nchar
|
||||
- boolean
|
||||
- datetime
|
||||
- decimal
|
||||
- float
|
||||
- fun
|
||||
- integer
|
||||
- ipaddr
|
||||
- list
|
||||
- map
|
||||
- number
|
||||
- pid
|
||||
- ref
|
||||
- string
|
||||
- term
|
||||
- binterm
|
||||
- timestamp
|
||||
- tuple
|
||||
- userid
|
||||
example: atom
|
||||
dir:
|
||||
description: Direction
|
||||
type: string
|
||||
enum:
|
||||
- in
|
||||
- out
|
||||
default: in
|
||||
64
test/e2e/specs/features/allow-empty-value.openapi.yaml
Normal file
64
test/e2e/specs/features/allow-empty-value.openapi.yaml
Normal file
@@ -0,0 +1,64 @@
|
||||
openapi: "3.0.0"
|
||||
|
||||
paths:
|
||||
/regularParams:
|
||||
get:
|
||||
parameters:
|
||||
- name: int
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
- name: str
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
- name: num
|
||||
in: query
|
||||
schema:
|
||||
type: number
|
||||
- name: bool
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
- name: arr
|
||||
in: query
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: ok
|
||||
/emptyValueParams:
|
||||
get:
|
||||
parameters:
|
||||
- name: int
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
allowEmptyValue: true
|
||||
- name: str
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
allowEmptyValue: true
|
||||
- name: num
|
||||
in: query
|
||||
schema:
|
||||
type: number
|
||||
allowEmptyValue: true
|
||||
- name: bool
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
allowEmptyValue: true
|
||||
- name: arr
|
||||
in: query
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
allowEmptyValue: true
|
||||
responses:
|
||||
200:
|
||||
description: ok
|
||||
57
test/e2e/specs/features/allow-empty-value.swagger.yaml
Normal file
57
test/e2e/specs/features/allow-empty-value.swagger.yaml
Normal file
@@ -0,0 +1,57 @@
|
||||
swagger: "2.0"
|
||||
|
||||
consumes:
|
||||
- application/json
|
||||
- multipart/form-data
|
||||
paths:
|
||||
/regularParams:
|
||||
get:
|
||||
parameters:
|
||||
- name: int
|
||||
in: query
|
||||
type: integer
|
||||
- name: str
|
||||
in: query
|
||||
type: string
|
||||
- name: num
|
||||
in: query
|
||||
type: number
|
||||
- name: bool
|
||||
in: query
|
||||
type: boolean
|
||||
- name: arr
|
||||
in: query
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: ok
|
||||
/emptyValueParams:
|
||||
get:
|
||||
parameters:
|
||||
- name: int
|
||||
in: query
|
||||
type: integer
|
||||
allowEmptyValue: true
|
||||
- name: str
|
||||
in: query
|
||||
type: string
|
||||
allowEmptyValue: true
|
||||
- name: num
|
||||
in: query
|
||||
type: number
|
||||
allowEmptyValue: true
|
||||
- name: bool
|
||||
in: query
|
||||
type: boolean
|
||||
allowEmptyValue: true
|
||||
- name: arr
|
||||
in: query
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
allowEmptyValue: true
|
||||
responses:
|
||||
200:
|
||||
description: ok
|
||||
Reference in New Issue
Block a user