fix(config): cast configuration values into proper types (#9829)
Refs #9808
This commit is contained in:
@@ -142,7 +142,7 @@ SwaggerUI.defaultProps = {
|
|||||||
deepLinking: false,
|
deepLinking: false,
|
||||||
showExtensions: false,
|
showExtensions: false,
|
||||||
showCommonExtensions: false,
|
showCommonExtensions: false,
|
||||||
filter: null,
|
filter: false,
|
||||||
requestSnippetsEnabled: false,
|
requestSnippetsEnabled: false,
|
||||||
requestSnippets: {
|
requestSnippets: {
|
||||||
generators: {
|
generators: {
|
||||||
@@ -164,7 +164,7 @@ SwaggerUI.defaultProps = {
|
|||||||
},
|
},
|
||||||
tryItOutEnabled: false,
|
tryItOutEnabled: false,
|
||||||
displayRequestDuration: false,
|
displayRequestDuration: false,
|
||||||
withCredentials: undefined,
|
withCredentials: false,
|
||||||
persistAuthorization: false,
|
persistAuthorization: false,
|
||||||
oauth2RedirectUrl: undefined,
|
oauth2RedirectUrl: undefined,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,10 +73,10 @@ export default class LiveResponse extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{ curlRequest && (requestSnippetsEnabled === true || requestSnippetsEnabled === "true"
|
{ curlRequest && requestSnippetsEnabled
|
||||||
? <RequestSnippets request={ curlRequest }/>
|
? <RequestSnippets request={ curlRequest }/>
|
||||||
: <Curl request={ curlRequest } />
|
: <Curl request={ curlRequest } />
|
||||||
)}
|
}
|
||||||
{ url && <div>
|
{ url && <div>
|
||||||
<div className="request-url">
|
<div className="request-url">
|
||||||
<h4>Request URL</h4>
|
<h4>Request URL</h4>
|
||||||
|
|||||||
@@ -47,8 +47,6 @@ export default class OperationTag extends React.Component {
|
|||||||
deepLinking,
|
deepLinking,
|
||||||
} = getConfigs()
|
} = getConfigs()
|
||||||
|
|
||||||
const isDeepLinkingEnabled = deepLinking && deepLinking !== "false"
|
|
||||||
|
|
||||||
const Collapse = getComponent("Collapse")
|
const Collapse = getComponent("Collapse")
|
||||||
const Markdown = getComponent("Markdown", true)
|
const Markdown = getComponent("Markdown", true)
|
||||||
const DeepLink = getComponent("DeepLink")
|
const DeepLink = getComponent("DeepLink")
|
||||||
@@ -80,7 +78,7 @@ export default class OperationTag extends React.Component {
|
|||||||
data-is-open={showTag}
|
data-is-open={showTag}
|
||||||
>
|
>
|
||||||
<DeepLink
|
<DeepLink
|
||||||
enabled={isDeepLinkingEnabled}
|
enabled={deepLinking}
|
||||||
isShown={showTag}
|
isShown={showTag}
|
||||||
path={createDeepLinkPath(tag)}
|
path={createDeepLinkPath(tag)}
|
||||||
text={tag} />
|
text={tag} />
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ const defaultOptions = Object.freeze({
|
|||||||
urls: null,
|
urls: null,
|
||||||
layout: "BaseLayout",
|
layout: "BaseLayout",
|
||||||
docExpansion: "list",
|
docExpansion: "list",
|
||||||
maxDisplayedTags: null,
|
maxDisplayedTags: -1,
|
||||||
filter: null,
|
filter: false,
|
||||||
validatorUrl: "https://validator.swagger.io/validator",
|
validatorUrl: "https://validator.swagger.io/validator",
|
||||||
oauth2RedirectUrl: `${window.location.protocol}//${window.location.host}${window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/"))}/oauth2-redirect.html`,
|
oauth2RedirectUrl: `${window.location.protocol}//${window.location.host}${window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/"))}/oauth2-redirect.html`,
|
||||||
persistAuthorization: false,
|
persistAuthorization: false,
|
||||||
@@ -30,7 +30,7 @@ const defaultOptions = Object.freeze({
|
|||||||
defaultModelsExpandDepth: 1,
|
defaultModelsExpandDepth: 1,
|
||||||
showExtensions: false,
|
showExtensions: false,
|
||||||
showCommonExtensions: false,
|
showCommonExtensions: false,
|
||||||
withCredentials: undefined,
|
withCredentials: false,
|
||||||
requestSnippetsEnabled: false,
|
requestSnippetsEnabled: false,
|
||||||
requestSnippets: {
|
requestSnippets: {
|
||||||
generators: {
|
generators: {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* @prettier
|
* @prettier
|
||||||
*/
|
*/
|
||||||
import merge from "../merge"
|
import deepExtend from "deep-extend"
|
||||||
|
|
||||||
const storeFactorization = (options) => {
|
const storeFactorization = (options) => {
|
||||||
const state = merge(
|
const state = deepExtend(
|
||||||
{
|
{
|
||||||
layout: {
|
layout: {
|
||||||
layout: options.layout,
|
layout: options.layout,
|
||||||
|
|||||||
@@ -7,12 +7,13 @@
|
|||||||
*
|
*
|
||||||
* NOTE1: lodash.merge & lodash.mergeWith prefers to ignore undefined values
|
* NOTE1: lodash.merge & lodash.mergeWith prefers to ignore undefined values
|
||||||
* NOTE2: special handling of `domNode` option is now required as `deep-extend` will corrupt it (lodash.merge handles it correctly)
|
* NOTE2: special handling of `domNode` option is now required as `deep-extend` will corrupt it (lodash.merge handles it correctly)
|
||||||
* NOTE3: oauth2RedirectUrl and withCredentials options can be set to undefined. By expecting null instead of undefined, we can't use lodash.merge.
|
* NOTE3: oauth2RedirectUrl option can be set to undefined. By expecting null instead of undefined, we can't use lodash.merge.
|
||||||
* NOTE4: urls.primaryName needs to handled in special way, because it's an arbitrary property on Array instance
|
* NOTE4: urls.primaryName needs to handled in special way, because it's an arbitrary property on Array instance
|
||||||
*
|
*
|
||||||
* TODO(vladimir.gorej@gmail.com): remove deep-extend in favor of lodash.merge
|
* TODO(vladimir.gorej@gmail.com): remove deep-extend in favor of lodash.merge
|
||||||
*/
|
*/
|
||||||
import deepExtend from "deep-extend"
|
import deepExtend from "deep-extend"
|
||||||
|
import typeCast from "./type-cast"
|
||||||
|
|
||||||
const merge = (target, ...sources) => {
|
const merge = (target, ...sources) => {
|
||||||
let domNode = Symbol.for("domNode")
|
let domNode = Symbol.for("domNode")
|
||||||
@@ -51,7 +52,7 @@ const merge = (target, ...sources) => {
|
|||||||
merged.urls.primaryName = primaryName
|
merged.urls.primaryName = primaryName
|
||||||
}
|
}
|
||||||
|
|
||||||
return merged
|
return typeCast(merged)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default merge
|
export default merge
|
||||||
|
|||||||
24
src/core/config/type-cast/index.js
Normal file
24
src/core/config/type-cast/index.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
import has from "lodash/has"
|
||||||
|
import get from "lodash/get"
|
||||||
|
import set from "lodash/fp/set"
|
||||||
|
|
||||||
|
import typeCasters from "./mappings"
|
||||||
|
|
||||||
|
const typeCast = (options) => {
|
||||||
|
return Object.entries(typeCasters).reduce(
|
||||||
|
(acc, [optionPath, { typeCaster, defaultValue }]) => {
|
||||||
|
if (has(acc, optionPath)) {
|
||||||
|
const uncasted = get(acc, optionPath)
|
||||||
|
const casted = typeCaster(uncasted, defaultValue)
|
||||||
|
acc = set(optionPath, casted, acc)
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
{ ...options }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default typeCast
|
||||||
115
src/core/config/type-cast/mappings.js
Normal file
115
src/core/config/type-cast/mappings.js
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
import arrayTypeCaster from "./type-casters/array"
|
||||||
|
import booleanTypeCaster from "./type-casters/boolean"
|
||||||
|
import domNodeTypeCaster from "./type-casters/dom-node"
|
||||||
|
import filterTypeCaster from "./type-casters/filter"
|
||||||
|
import nullableArrayTypeCaster from "./type-casters/nullable-array"
|
||||||
|
import nullableStringTypeCaster from "./type-casters/nullable-string"
|
||||||
|
import numberTypeCaster from "./type-casters/number"
|
||||||
|
import objectTypeCaster from "./type-casters/object"
|
||||||
|
import stringTypeCaster from "./type-casters/string"
|
||||||
|
import syntaxHighlightTypeCaster from "./type-casters/syntax-highlight"
|
||||||
|
import undefinedStringTypeCaster from "./type-casters/undefined-string"
|
||||||
|
import defaultOptions from "../defaults"
|
||||||
|
|
||||||
|
const typeCasters = {
|
||||||
|
configUrl: { typeCaster: stringTypeCaster },
|
||||||
|
deepLinking: {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.deepLinking,
|
||||||
|
},
|
||||||
|
defaultModelExpandDepth: {
|
||||||
|
typeCaster: numberTypeCaster,
|
||||||
|
defaultValue: defaultOptions.defaultModelExpandDepth,
|
||||||
|
},
|
||||||
|
defaultModelRendering: { typeCaster: stringTypeCaster },
|
||||||
|
defaultModelsExpandDepth: {
|
||||||
|
typeCaster: numberTypeCaster,
|
||||||
|
defaultValue: defaultOptions.defaultModelsExpandDepth,
|
||||||
|
},
|
||||||
|
displayOperationId: {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.displayOperationId,
|
||||||
|
},
|
||||||
|
displayRequestDuration: {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.displayRequestDuration,
|
||||||
|
},
|
||||||
|
docExpansion: { typeCaster: stringTypeCaster },
|
||||||
|
dom_id: { typeCaster: nullableStringTypeCaster },
|
||||||
|
domNode: { typeCaster: domNodeTypeCaster },
|
||||||
|
filter: { typeCaster: filterTypeCaster },
|
||||||
|
layout: { typeCaster: stringTypeCaster },
|
||||||
|
maxDisplayedTags: {
|
||||||
|
typeCaster: numberTypeCaster,
|
||||||
|
defaultValue: defaultOptions.maxDisplayedTags,
|
||||||
|
},
|
||||||
|
oauth2RedirectUrl: { typeCaster: undefinedStringTypeCaster },
|
||||||
|
persistAuthorization: {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.persistAuthorization,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
typeCaster: arrayTypeCaster,
|
||||||
|
defaultValue: defaultOptions.plugins,
|
||||||
|
},
|
||||||
|
pluginsOptions: {
|
||||||
|
typeCaster: objectTypeCaster,
|
||||||
|
pluginsOptions: defaultOptions.pluginsOptions,
|
||||||
|
},
|
||||||
|
"pluginsOptions.pluginsLoadType": { typeCaster: stringTypeCaster },
|
||||||
|
presets: {
|
||||||
|
typeCaster: arrayTypeCaster,
|
||||||
|
defaultValue: defaultOptions.presets,
|
||||||
|
},
|
||||||
|
requestSnippets: {
|
||||||
|
typeCaster: objectTypeCaster,
|
||||||
|
defaultValue: defaultOptions.requestSnippets,
|
||||||
|
},
|
||||||
|
requestSnippetsEnabled: {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.requestSnippetsEnabled,
|
||||||
|
},
|
||||||
|
showCommonExtensions: {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.showCommonExtensions,
|
||||||
|
},
|
||||||
|
showExtensions: {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.showExtensions,
|
||||||
|
},
|
||||||
|
showMutatedRequest: {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.showMutatedRequest,
|
||||||
|
},
|
||||||
|
spec: { typeCaster: objectTypeCaster, defaultValue: defaultOptions.spec },
|
||||||
|
supportedSubmitMethods: {
|
||||||
|
typeCaster: arrayTypeCaster,
|
||||||
|
defaultValue: defaultOptions.supportedSubmitMethods,
|
||||||
|
},
|
||||||
|
syntaxHighlight: {
|
||||||
|
typeCaster: syntaxHighlightTypeCaster,
|
||||||
|
defaultValue: defaultOptions.syntaxHighlight,
|
||||||
|
},
|
||||||
|
"syntaxHighlight.activated": {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.syntaxHighlight.activated,
|
||||||
|
},
|
||||||
|
"syntaxHighlight.theme": { typeCaster: stringTypeCaster },
|
||||||
|
tryItOutEnabled: {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.tryItOutEnabled,
|
||||||
|
},
|
||||||
|
url: { typeCaster: stringTypeCaster },
|
||||||
|
urls: { typeCaster: nullableArrayTypeCaster },
|
||||||
|
"urls.primaryName": { typeCaster: stringTypeCaster },
|
||||||
|
validatorUrl: { typeCaster: nullableStringTypeCaster },
|
||||||
|
withCredentials: {
|
||||||
|
typeCaster: booleanTypeCaster,
|
||||||
|
defaultValue: defaultOptions.withCredentials,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default typeCasters
|
||||||
7
src/core/config/type-cast/type-casters/array.js
Normal file
7
src/core/config/type-cast/type-casters/array.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
const arrayTypeCaster = (value, defaultValue = []) =>
|
||||||
|
Array.isArray(value) ? value : defaultValue
|
||||||
|
|
||||||
|
export default arrayTypeCaster
|
||||||
11
src/core/config/type-cast/type-casters/boolean.js
Normal file
11
src/core/config/type-cast/type-casters/boolean.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
const booleanTypeCaster = (value, defaultValue = false) =>
|
||||||
|
value === true || value === "true" || value === 1 || value === "1"
|
||||||
|
? true
|
||||||
|
: value === false || value === "false" || value === 0 || value === "0"
|
||||||
|
? false
|
||||||
|
: defaultValue
|
||||||
|
|
||||||
|
export default booleanTypeCaster
|
||||||
7
src/core/config/type-cast/type-casters/dom-node.js
Normal file
7
src/core/config/type-cast/type-casters/dom-node.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
const domNodeTypeCaster = (value) =>
|
||||||
|
value === null || value === "null" ? null : value
|
||||||
|
|
||||||
|
export default domNodeTypeCaster
|
||||||
11
src/core/config/type-cast/type-casters/filter.js
Normal file
11
src/core/config/type-cast/type-casters/filter.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
import booleanTypeCaster from "./boolean"
|
||||||
|
|
||||||
|
const filterTypeCaster = (value) => {
|
||||||
|
const defaultValue = String(value)
|
||||||
|
return booleanTypeCaster(value, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default filterTypeCaster
|
||||||
6
src/core/config/type-cast/type-casters/nullable-array.js
Normal file
6
src/core/config/type-cast/type-casters/nullable-array.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
const nullableArrayTypeCaster = (value) => (Array.isArray(value) ? value : null)
|
||||||
|
|
||||||
|
export default nullableArrayTypeCaster
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
const nullableStringTypeCaster = (value) =>
|
||||||
|
value === null || value === "null" ? null : String(value)
|
||||||
|
|
||||||
|
export default nullableStringTypeCaster
|
||||||
9
src/core/config/type-cast/type-casters/number.js
Normal file
9
src/core/config/type-cast/type-casters/number.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
const numberTypeCaster = (value, defaultValue = -1) => {
|
||||||
|
const parsedValue = parseInt(value, 10)
|
||||||
|
return Number.isNaN(parsedValue) ? defaultValue : parsedValue
|
||||||
|
}
|
||||||
|
|
||||||
|
export default numberTypeCaster
|
||||||
9
src/core/config/type-cast/type-casters/object.js
Normal file
9
src/core/config/type-cast/type-casters/object.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
import isPlainObject from "lodash/isPlainObject"
|
||||||
|
|
||||||
|
const objectTypeCaster = (value, defaultValue = {}) =>
|
||||||
|
isPlainObject(value) ? value : defaultValue
|
||||||
|
|
||||||
|
export default objectTypeCaster
|
||||||
6
src/core/config/type-cast/type-casters/string.js
Normal file
6
src/core/config/type-cast/type-casters/string.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
const stringTypeCaster = (value) => String(value)
|
||||||
|
|
||||||
|
export default stringTypeCaster
|
||||||
14
src/core/config/type-cast/type-casters/syntax-highlight.js
Normal file
14
src/core/config/type-cast/type-casters/syntax-highlight.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
import isPlainObject from "lodash/isPlainObject"
|
||||||
|
|
||||||
|
const syntaxHighlightTypeCaster = (value, defaultValue) => {
|
||||||
|
return isPlainObject(value)
|
||||||
|
? value
|
||||||
|
: value === false || value === "false" || value === 0 || value === "0"
|
||||||
|
? { activated: false }
|
||||||
|
: defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
export default syntaxHighlightTypeCaster
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
const undefinedStringTypeCaster = (value) =>
|
||||||
|
value === undefined || value === "undefined" ? undefined : String(value)
|
||||||
|
|
||||||
|
export default undefinedStringTypeCaster
|
||||||
@@ -11,7 +11,7 @@ export default class OperationContainer extends PureComponent {
|
|||||||
const { tryItOutEnabled } = props.getConfigs()
|
const { tryItOutEnabled } = props.getConfigs()
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
tryItOutEnabled: tryItOutEnabled === true || tryItOutEnabled === "true",
|
tryItOutEnabled,
|
||||||
executeInProgress: false
|
executeInProgress: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,14 +61,13 @@ export default class OperationContainer extends PureComponent {
|
|||||||
const showSummary = layoutSelectors.showSummary()
|
const showSummary = layoutSelectors.showSummary()
|
||||||
const operationId = op.getIn(["operation", "__originalOperationId"]) || op.getIn(["operation", "operationId"]) || opId(op.get("operation"), props.path, props.method) || op.get("id")
|
const operationId = op.getIn(["operation", "__originalOperationId"]) || op.getIn(["operation", "operationId"]) || opId(op.get("operation"), props.path, props.method) || op.get("id")
|
||||||
const isShownKey = ["operations", props.tag, operationId]
|
const isShownKey = ["operations", props.tag, operationId]
|
||||||
const isDeepLinkingEnabled = deepLinking && deepLinking !== "false"
|
|
||||||
const allowTryItOut = supportedSubmitMethods.indexOf(props.method) >= 0 && (typeof props.allowTryItOut === "undefined" ?
|
const allowTryItOut = supportedSubmitMethods.indexOf(props.method) >= 0 && (typeof props.allowTryItOut === "undefined" ?
|
||||||
props.specSelectors.allowTryItOutFor(props.path, props.method) : props.allowTryItOut)
|
props.specSelectors.allowTryItOutFor(props.path, props.method) : props.allowTryItOut)
|
||||||
const security = op.getIn(["operation", "security"]) || props.specSelectors.security()
|
const security = op.getIn(["operation", "security"]) || props.specSelectors.security()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
operationId,
|
operationId,
|
||||||
isDeepLinkingEnabled,
|
isDeepLinkingEnabled: deepLinking,
|
||||||
showSummary,
|
showSummary,
|
||||||
displayOperationId,
|
displayOperationId,
|
||||||
displayRequestDuration,
|
displayRequestDuration,
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ export default class FilterContainer extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{filter === null || filter === false || filter === "false" ? null :
|
{filter === false ? null :
|
||||||
<div className="filter-container">
|
<div className="filter-container">
|
||||||
<Col className="filter wrapper" mobile={12}>
|
<Col className="filter wrapper" mobile={12}>
|
||||||
<input className={classNames.join(" ")} placeholder="Filter by tag" type="text"
|
<input className={classNames.join(" ")} placeholder="Filter by tag" type="text"
|
||||||
onChange={this.onFilterChange} value={filter === true || filter === "true" ? "" : filter}
|
onChange={this.onFilterChange} value={typeof filter === "string" ? filter : ""}
|
||||||
disabled={isLoading}/>
|
disabled={isLoading}/>
|
||||||
</Col>
|
</Col>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ export const taggedOperations = (oriSelector, system) => (state, ...args) => {
|
|||||||
// Filter, if requested
|
// Filter, if requested
|
||||||
let filter = layoutSelectors.currentFilter()
|
let filter = layoutSelectors.currentFilter()
|
||||||
if (filter) {
|
if (filter) {
|
||||||
if (filter !== true && filter !== "true" && filter !== "false") {
|
if (filter !== true) {
|
||||||
taggedOps = fn.opsFilter(taggedOps, filter)
|
taggedOps = fn.opsFilter(taggedOps, filter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Limit to [max] items, if specified
|
// Limit to [max] items, if specified
|
||||||
if (maxDisplayedTags && !isNaN(maxDisplayedTags) && maxDisplayedTags >= 0) {
|
if (maxDisplayedTags >= 0) {
|
||||||
taggedOps = taggedOps.slice(0, maxDisplayedTags)
|
taggedOps = taggedOps.slice(0, maxDisplayedTags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,5 @@ export const loaded = (ori, system) => (...args) => {
|
|||||||
ori(...args)
|
ori(...args)
|
||||||
const value = system.getConfigs().withCredentials
|
const value = system.getConfigs().withCredentials
|
||||||
|
|
||||||
if(value !== undefined) {
|
system.fn.fetch.withCredentials = value
|
||||||
system.fn.fetch.withCredentials = typeof value === "string" ? (value === "true") : !!value
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import ReactSyntaxHighlighter from "react-syntax-highlighter/dist/esm/light"
|
import ReactSyntaxHighlighter from "react-syntax-highlighter/dist/esm/light"
|
||||||
import get from "lodash/get"
|
|
||||||
|
|
||||||
const SyntaxHighlighter = ({
|
const SyntaxHighlighter = ({
|
||||||
language,
|
language,
|
||||||
@@ -13,8 +12,7 @@ const SyntaxHighlighter = ({
|
|||||||
syntaxHighlighting = {},
|
syntaxHighlighting = {},
|
||||||
children = "",
|
children = "",
|
||||||
}) => {
|
}) => {
|
||||||
const configs = getConfigs()
|
const theme = getConfigs().syntaxHighlight.theme
|
||||||
const theme = get(configs, "syntaxHighlight.theme")
|
|
||||||
const { styles, defaultStyle } = syntaxHighlighting
|
const { styles, defaultStyle } = syntaxHighlighting
|
||||||
const style = styles?.[theme] ?? defaultStyle
|
const style = styles?.[theme] ?? defaultStyle
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,10 @@
|
|||||||
*/
|
*/
|
||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import get from "lodash/get"
|
|
||||||
|
|
||||||
const SyntaxHighlighterWrapper = (Original, system) => {
|
const SyntaxHighlighterWrapper = (Original, system) => {
|
||||||
const SyntaxHighlighter = ({ renderPlainText, children, ...rest }) => {
|
const SyntaxHighlighter = ({ renderPlainText, children, ...rest }) => {
|
||||||
const configs = system.getConfigs()
|
const canSyntaxHighlight = system.getConfigs().syntaxHighlight.activated
|
||||||
const canSyntaxHighlight = !!get(configs, "syntaxHighlight.activated")
|
|
||||||
const PlainTextViewer = system.getComponent("PlainTextViewer")
|
const PlainTextViewer = system.getComponent("PlainTextViewer")
|
||||||
|
|
||||||
if (!canSyntaxHighlight && typeof renderPlainText === "function") {
|
if (!canSyntaxHighlight && typeof renderPlainText === "function") {
|
||||||
|
|||||||
@@ -30,21 +30,6 @@ describe("<FilterContainer/>", function(){
|
|||||||
expect(renderedColInsideFilter.length).toEqual(1)
|
expect(renderedColInsideFilter.length).toEqual(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("does not render FilterContainer if filter is null", function(){
|
|
||||||
|
|
||||||
// Given
|
|
||||||
let props = {...mockedProps}
|
|
||||||
props.layoutSelectors = {...mockedProps.specSelectors}
|
|
||||||
props.layoutSelectors.currentFilter = function() {return null}
|
|
||||||
|
|
||||||
// When
|
|
||||||
let wrapper = mount(<FilterContainer {...props}/>)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
const renderedColInsideFilter = wrapper.find(Col)
|
|
||||||
expect(renderedColInsideFilter.length).toEqual(0)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("does not render FilterContainer if filter is false", function(){
|
it("does not render FilterContainer if filter is false", function(){
|
||||||
|
|
||||||
// Given
|
// Given
|
||||||
|
|||||||
104
test/unit/core/config/type-cast/index.js
Normal file
104
test/unit/core/config/type-cast/index.js
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
import typeCast from "core/config/type-cast"
|
||||||
|
|
||||||
|
jest.mock("core/presets/apis", () => {})
|
||||||
|
|
||||||
|
describe("typeCast", () => {
|
||||||
|
it("should cast stringified `true` and `false` values to `boolean`", () => {
|
||||||
|
const config = {
|
||||||
|
deepLinking: "true",
|
||||||
|
tryItOutEnabled: "false",
|
||||||
|
withCredentials: "true",
|
||||||
|
filter: "false",
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedConfig = {
|
||||||
|
deepLinking: true,
|
||||||
|
tryItOutEnabled: false,
|
||||||
|
withCredentials: true,
|
||||||
|
filter: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(typeCast(config)).toStrictEqual(expectedConfig)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should cast stringified `number` values to `number`", () => {
|
||||||
|
const config = {
|
||||||
|
defaultModelExpandDepth: "5",
|
||||||
|
defaultModelsExpandDepth: "-1",
|
||||||
|
maxDisplayedTags: "1",
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedConfig = {
|
||||||
|
defaultModelExpandDepth: 5,
|
||||||
|
defaultModelsExpandDepth: -1,
|
||||||
|
maxDisplayedTags: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(typeCast(config)).toStrictEqual(expectedConfig)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should cast stringified `null` values to `null`", () => {
|
||||||
|
const config = {
|
||||||
|
validatorUrl: "null",
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedConfig = {
|
||||||
|
validatorUrl: null,
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(typeCast(config)).toStrictEqual(expectedConfig)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should cast `string` values to `string`", () => {
|
||||||
|
const config = { defaultModelRendering: "model", filter: "pet" }
|
||||||
|
|
||||||
|
const expectedConfig = { defaultModelRendering: "model", filter: "pet" }
|
||||||
|
|
||||||
|
expect(typeCast(config)).toStrictEqual(expectedConfig)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should cast stringified values to correct type", () => {
|
||||||
|
const config = {
|
||||||
|
dom_id: "null",
|
||||||
|
oauth2RedirectUrl: "undefined",
|
||||||
|
syntaxHighlight: "false",
|
||||||
|
urls: "null",
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedConfig = {
|
||||||
|
dom_id: null,
|
||||||
|
oauth2RedirectUrl: undefined,
|
||||||
|
syntaxHighlight: { activated: false },
|
||||||
|
urls: null,
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(typeCast(config)).toStrictEqual(expectedConfig)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should cast incorrect value types to default value", () => {
|
||||||
|
const config = {
|
||||||
|
deepLinking: "deepLinking",
|
||||||
|
urls: "urls",
|
||||||
|
syntaxHighlight: "syntaxHighlight",
|
||||||
|
spec: "spec",
|
||||||
|
maxDisplayedTags: "null",
|
||||||
|
defaultModelExpandDepth: {},
|
||||||
|
defaultModelsExpandDepth: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedConfig = {
|
||||||
|
deepLinking: false,
|
||||||
|
urls: null,
|
||||||
|
syntaxHighlight: { activated: true, theme: "agate" },
|
||||||
|
spec: {},
|
||||||
|
maxDisplayedTags: -1,
|
||||||
|
defaultModelExpandDepth: 1,
|
||||||
|
defaultModelsExpandDepth: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(typeCast(config)).toStrictEqual(expectedConfig)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -49,44 +49,6 @@ describe("swagger-client plugin - withCredentials", () => {
|
|||||||
const loadedFn = loaded(oriExecute, system)
|
const loadedFn = loaded(oriExecute, system)
|
||||||
loadedFn()
|
loadedFn()
|
||||||
|
|
||||||
expect(oriExecute.mock.calls.length).toBe(1)
|
|
||||||
expect(system.fn.fetch.withCredentials).toBe(false)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should allow setting flag to true via config as string", () => {
|
|
||||||
// for query string config
|
|
||||||
const system = {
|
|
||||||
fn: {
|
|
||||||
fetch: jest.fn().mockImplementation(() => Promise.resolve())
|
|
||||||
},
|
|
||||||
getConfigs: () => ({
|
|
||||||
withCredentials: "true"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const oriExecute = jest.fn()
|
|
||||||
|
|
||||||
const loadedFn = loaded(oriExecute, system)
|
|
||||||
loadedFn()
|
|
||||||
|
|
||||||
expect(oriExecute.mock.calls.length).toBe(1)
|
|
||||||
expect(system.fn.fetch.withCredentials).toBe(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should allow setting flag to false via config as string", () => {
|
|
||||||
// for query string config
|
|
||||||
const system = {
|
|
||||||
fn: {
|
|
||||||
fetch: jest.fn().mockImplementation(() => Promise.resolve())
|
|
||||||
},
|
|
||||||
getConfigs: () => ({
|
|
||||||
withCredentials: "false"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const oriExecute = jest.fn()
|
|
||||||
|
|
||||||
const loadedFn = loaded(oriExecute, system)
|
|
||||||
loadedFn()
|
|
||||||
|
|
||||||
expect(oriExecute.mock.calls.length).toBe(1)
|
expect(oriExecute.mock.calls.length).toBe(1)
|
||||||
expect(system.fn.fetch.withCredentials).toBe(false)
|
expect(system.fn.fetch.withCredentials).toBe(false)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user