Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1f29aa7e1 | ||
|
|
cdf3dfa075 | ||
|
|
8f73519cc7 | ||
|
|
3ee4f8d6e3 | ||
|
|
213f6d7080 | ||
|
|
7254e8b3fa | ||
|
|
13eed0d0f7 | ||
|
|
0256b97855 | ||
|
|
61eb86ed50 | ||
|
|
bb57fd2406 | ||
|
|
6f5649c6ba | ||
|
|
d7d061b5af | ||
|
|
0f86524514 | ||
|
|
ba90c70b34 | ||
|
|
ef3ccd7a23 | ||
|
|
0c0c9a6519 | ||
|
|
945d7a3a0f | ||
|
|
b3c549055d | ||
|
|
efd02106a2 | ||
|
|
7e9d8f0b37 | ||
|
|
ab7af75ab4 | ||
|
|
5d3efbb5f7 | ||
|
|
0997c5e5d4 | ||
|
|
21ff236e43 | ||
|
|
07a9410ee5 | ||
|
|
25b9fb28dc | ||
|
|
9603905d1d | ||
|
|
a7a50b8457 | ||
|
|
00a059b8dd | ||
|
|
d003df2e5a | ||
|
|
50153487ba | ||
|
|
d5a4cab383 | ||
|
|
e6ecb201c7 | ||
|
|
ec787cfeb6 | ||
|
|
67132ca920 | ||
|
|
0fa532d35c | ||
|
|
15cf495452 | ||
|
|
5224932cf9 | ||
|
|
8d1d15ca4a | ||
|
|
e17a5f40f5 | ||
|
|
2325118540 | ||
|
|
ade47ca40e | ||
|
|
8223710e92 | ||
|
|
de7e0910bb | ||
|
|
713d1a1bb8 | ||
|
|
40bd720eb4 | ||
|
|
a6dd9d60e7 | ||
|
|
5db4131046 | ||
|
|
52693254e9 | ||
|
|
51a68c0d8e | ||
|
|
469b4d6323 | ||
|
|
f697e45362 | ||
|
|
3c2af93589 | ||
|
|
7c1126ce51 | ||
|
|
2831c59e70 | ||
|
|
f929d4fdd6 |
@@ -13,6 +13,7 @@ ENV OAUTH_APP_NAME "**None**"
|
||||
ENV OAUTH_ADDITIONAL_PARAMS "**None**"
|
||||
ENV SWAGGER_JSON "/app/swagger.json"
|
||||
ENV PORT 80
|
||||
ENV BASE_URL ""
|
||||
|
||||
RUN apk add --update nginx
|
||||
RUN mkdir -p /run/nginx
|
||||
|
||||
@@ -22,7 +22,7 @@ The OpenAPI Specification has undergone 5 revisions since initial creation in 20
|
||||
|
||||
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes
|
||||
------------------ | ------------ | -------------------------- | -----
|
||||
3.5.0 | 2017-11-23 | 2.0, 3.0 | [tag v3.5.0](https://github.com/swagger-api/swagger-ui/tree/v3.5.0)
|
||||
3.6.0 | 2017-12-01 | 2.0, 3.0 | [tag v3.5=6.0](https://github.com/swagger-api/swagger-ui/tree/v3.6.0)
|
||||
3.0.21 | 2017-07-26 | 2.0 | [tag v3.0.21](https://github.com/swagger-api/swagger-ui/tree/v3.0.21)
|
||||
2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10)
|
||||
2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5)
|
||||
@@ -49,6 +49,14 @@ Or you can provide your own swagger.json on your host
|
||||
docker run -p 80:8080 -e SWAGGER_JSON=/foo/swagger.json -v /bar:/foo swaggerapi/swagger-ui
|
||||
```
|
||||
|
||||
The base URL of the web application can be changed by specifying the `BASE_URL` environment variable:
|
||||
|
||||
```
|
||||
docker run -p 80:8080 -e BASE_URL=/swagger -e SWAGGER_JSON=/foo/swagger.json -v /bar:/foo swaggerapi/swagger-ui
|
||||
```
|
||||
|
||||
This will serve Swagger UI at `/swagger` instead of `/`.
|
||||
|
||||
##### Prerequisites
|
||||
- Node 6.x
|
||||
- NPM 3.x
|
||||
@@ -162,8 +170,8 @@ displayRequestDuration | Controls the display of the request duration (in millis
|
||||
maxDisplayedTags | If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.
|
||||
filter | If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be true/false to enable or disable, or an explicit filter string in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag.
|
||||
deepLinking | If set to `true`, enables dynamic deep linking for tags and operations. [Docs](https://github.com/swagger-api/swagger-ui/blob/master/docs/deep-linking.md)
|
||||
requestInterceptor | MUST be a function. Function to intercept try-it-out requests. Accepts one argument requestInterceptor(request) and must return the potentially modified request.
|
||||
responseInterceptor | MUST be a function. Function to intercept try-it-out responses. Accepts one argument responseInterceptor(response) and must return the potentially modified response.
|
||||
requestInterceptor | MUST be a function. Function to intercept remote definition, Try-It-Out, and OAuth2 requests. Accepts one argument requestInterceptor(request) and must return the potentially modified request.
|
||||
responseInterceptor | MUST be a function. Function to intercept remote definition, Try-It-Out, and OAuth2 responses. Accepts one argument responseInterceptor(response) and must return the potentially modified response.
|
||||
showMutatedRequest | If set to `true` (the default), uses the mutated request returned from a rquestInterceptor to produce the curl command in the UI, otherwise the request before the requestInterceptor was applied is used.
|
||||
showExtensions | Controls the display of vendor extension (`x-`) fields and values for Operations, Parameters, and Schema. The default is `false`.
|
||||
|
||||
|
||||
Vendored
+15
-15
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -21,6 +21,16 @@ replace_or_delete_in_index () {
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "${BASE_URL}" ]; then
|
||||
NGINX_WITH_BASE_URL="${NGINX_ROOT}${BASE_URL}"
|
||||
|
||||
mkdir -p ${NGINX_WITH_BASE_URL}
|
||||
mv ${NGINX_ROOT}/*.* ${NGINX_WITH_BASE_URL}/
|
||||
|
||||
INDEX_FILE=$NGINX_WITH_BASE_URL/index.html
|
||||
NGINX_ROOT=$NGINX_WITH_BASE_URL
|
||||
fi
|
||||
|
||||
replace_in_index myApiKeyXXXX123456789 $API_KEY
|
||||
replace_or_delete_in_index your-client-id $OAUTH_CLIENT_ID
|
||||
replace_or_delete_in_index your-client-secret-if-required $OAUTH_CLIENT_SECRET
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "swagger-ui",
|
||||
"version": "3.5.0",
|
||||
"version": "3.6.0",
|
||||
"main": "dist/swagger-ui.js",
|
||||
"repository": "git@github.com:swagger-api/swagger-ui.git",
|
||||
"contributors": [
|
||||
@@ -81,7 +81,7 @@
|
||||
"scroll-to-element": "^2.0.0",
|
||||
"serialize-error": "2.0.0",
|
||||
"shallowequal": "0.2.2",
|
||||
"swagger-client": "^3.3.5",
|
||||
"swagger-client": "^3.4.0",
|
||||
"url-parse": "^1.1.8",
|
||||
"whatwg-fetch": "0.11.1",
|
||||
"worker-loader": "^0.7.1",
|
||||
|
||||
@@ -2,20 +2,24 @@ import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import Im from "immutable"
|
||||
|
||||
const propStyle = { color: "#999", fontStyle: "italic" }
|
||||
|
||||
export default class Headers extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
headers: PropTypes.object.isRequired
|
||||
headers: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
let { headers } = this.props
|
||||
let { headers, getComponent } = this.props
|
||||
const Property = getComponent("Property")
|
||||
|
||||
if ( !headers || !headers.size )
|
||||
return null
|
||||
|
||||
return (
|
||||
return (
|
||||
<div className="headers-wrapper">
|
||||
<h4 className="headers__title">Headers:</h4>
|
||||
<table className="headers">
|
||||
@@ -32,10 +36,13 @@ export default class Headers extends React.Component {
|
||||
if(!Im.Map.isMap(header)) {
|
||||
return null
|
||||
}
|
||||
const type = header.getIn(["schema"]) ? header.getIn(["schema", "type"]) : header.getIn(["type"])
|
||||
const schemaExample = header.getIn(["schema", "example"])
|
||||
|
||||
return (<tr key={ key }>
|
||||
<td className="header-col">{ key }</td>
|
||||
<td className="header-col">{ header.get( "description" ) }</td>
|
||||
<td className="header-col">{ header.get( "type" ) }</td>
|
||||
<td className="header-col">{ type } { schemaExample ? <Property propKey={ "Example" } propVal={ schemaExample } propStyle={ propStyle } /> : null }</td>
|
||||
</tr>)
|
||||
}).toArray()
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ export class Select extends React.Component {
|
||||
{ allowEmptyValue ? <option value="">--</option> : null }
|
||||
{
|
||||
allowedValues.map(function (item, key) {
|
||||
return <option key={ key } value={ String(item) }>{ item }</option>
|
||||
return <option key={ key } value={ String(item) }>{ String(item) }</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
|
||||
@@ -94,8 +94,9 @@ export default class BaseLayout extends React.Component {
|
||||
) : null }
|
||||
|
||||
{ servers && servers.size ? (
|
||||
<div className="server-container">
|
||||
<div className="global-server-container">
|
||||
<Col className="servers wrapper" mobile={12}>
|
||||
<span className="servers-title">Server</span>
|
||||
<Servers
|
||||
servers={servers}
|
||||
currentServer={oas3Selectors.selectedServer()}
|
||||
|
||||
@@ -22,6 +22,7 @@ export default class Operation extends PureComponent {
|
||||
specActions: PropTypes.object.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
oas3Actions: PropTypes.object.isRequired,
|
||||
oas3Selectors: PropTypes.object.isRequired,
|
||||
layoutActions: PropTypes.object.isRequired,
|
||||
layoutSelectors: PropTypes.object.isRequired,
|
||||
fn: PropTypes.object.isRequired
|
||||
@@ -48,7 +49,8 @@ export default class Operation extends PureComponent {
|
||||
specSelectors,
|
||||
authActions,
|
||||
authSelectors,
|
||||
oas3Actions
|
||||
oas3Actions,
|
||||
oas3Selectors
|
||||
} = this.props
|
||||
let operationProps = this.props.operation
|
||||
|
||||
@@ -96,6 +98,7 @@ export default class Operation extends PureComponent {
|
||||
const Collapse = getComponent( "Collapse" )
|
||||
const Markdown = getComponent( "Markdown" )
|
||||
const Schemes = getComponent( "schemes" )
|
||||
const OperationServers = getComponent( "OperationServers" )
|
||||
const OperationExt = getComponent( "OperationExt" )
|
||||
|
||||
const { showExtensions } = getConfigs()
|
||||
@@ -182,6 +185,21 @@ export default class Operation extends PureComponent {
|
||||
getConfigs={ getConfigs }
|
||||
/>
|
||||
|
||||
{ !tryItOutEnabled ? null :
|
||||
<OperationServers
|
||||
getComponent={getComponent}
|
||||
path={path}
|
||||
method={method}
|
||||
operationServers={operation.get("servers")}
|
||||
pathServers={specSelectors.paths().getIn([path, "servers"])}
|
||||
getSelectedServer={oas3Selectors.selectedServer}
|
||||
setSelectedServer={oas3Actions.setSelectedServer}
|
||||
setServerVariableValue={oas3Actions.setServerVariableValue}
|
||||
getServerVariable={oas3Selectors.serverVariableValue}
|
||||
getEffectiveServerValue={oas3Selectors.serverEffectiveValue}
|
||||
/>
|
||||
}
|
||||
|
||||
{!tryItOutEnabled || !allowTryItOut ? null : schemes && schemes.size ? <div className="opblock-schemes">
|
||||
<Schemes schemes={ schemes }
|
||||
path={ path }
|
||||
|
||||
@@ -57,9 +57,6 @@ export default class ResponseBody extends React.Component {
|
||||
(headers["Content-Description"] && (/File Transfer/i).test(headers["Content-Description"])) ||
|
||||
(headers["content-description"] && (/File Transfer/i).test(headers["content-description"]))) {
|
||||
|
||||
let contentLength = headers["content-length"] || headers["Content-Length"]
|
||||
if ( !(+contentLength) ) return null
|
||||
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
|
||||
|
||||
if (!isSafari && "Blob" in window) {
|
||||
|
||||
@@ -153,7 +153,10 @@ export default class Response extends React.Component {
|
||||
) : null}
|
||||
|
||||
{ headers ? (
|
||||
<Headers headers={ headers }/>
|
||||
<Headers
|
||||
headers={ headers }
|
||||
getComponent={ getComponent }
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ export default class OperationContainer extends PureComponent {
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
authActions: PropTypes.object,
|
||||
oas3Actions: PropTypes.object,
|
||||
oas3Selectors: PropTypes.object,
|
||||
authSelectors: PropTypes.object,
|
||||
specActions: PropTypes.object.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
@@ -149,6 +150,7 @@ export default class OperationContainer extends PureComponent {
|
||||
authActions,
|
||||
authSelectors,
|
||||
oas3Actions,
|
||||
oas3Selectors,
|
||||
fn
|
||||
} = this.props
|
||||
|
||||
@@ -189,6 +191,7 @@ export default class OperationContainer extends PureComponent {
|
||||
specActions={ specActions }
|
||||
specSelectors={ specSelectors }
|
||||
oas3Actions={oas3Actions}
|
||||
oas3Selectors={oas3Selectors}
|
||||
layoutActions={ layoutActions }
|
||||
layoutSelectors={ layoutSelectors }
|
||||
authActions={ authActions }
|
||||
|
||||
@@ -36,7 +36,7 @@ export class JsonSchemaForm extends Component {
|
||||
|
||||
let { type, format="" } = schema
|
||||
|
||||
let Comp = getComponent(`JsonSchema_${type}_${format}`) || getComponent(`JsonSchema_${type}`) || getComponent("JsonSchema_string")
|
||||
let Comp = (format ? getComponent(`JsonSchema_${type}_${format}`) : getComponent(`JsonSchema_${type}`)) || getComponent("JsonSchema_string")
|
||||
return <Comp { ...this.props } fn={fn} getComponent={getComponent} value={value} onChange={onChange} schema={schema}/>
|
||||
}
|
||||
|
||||
@@ -68,19 +68,19 @@ export class JsonSchema_string extends Component {
|
||||
const isDisabled = schema["in"] === "formData" && !("FormData" in window)
|
||||
const Input = getComponent("Input")
|
||||
if (schema["type"] === "file") {
|
||||
return (<Input type="file"
|
||||
className={ errors.length ? "invalid" : ""}
|
||||
return (<Input type="file"
|
||||
className={ errors.length ? "invalid" : ""}
|
||||
title={ errors.length ? errors : ""}
|
||||
onChange={ this.onChange }
|
||||
onChange={ this.onChange }
|
||||
disabled={isDisabled}/>)
|
||||
}
|
||||
else {
|
||||
return (<Input type={ schema.format === "password" ? "password" : "text" }
|
||||
className={ errors.length ? "invalid" : ""}
|
||||
return (<Input type={ schema.format === "password" ? "password" : "text" }
|
||||
className={ errors.length ? "invalid" : ""}
|
||||
title={ errors.length ? errors : ""}
|
||||
value={value}
|
||||
placeholder={description}
|
||||
onChange={ this.onChange }
|
||||
value={value}
|
||||
placeholder={description}
|
||||
onChange={ this.onChange }
|
||||
disabled={isDisabled}/>)
|
||||
}
|
||||
}
|
||||
@@ -189,8 +189,8 @@ export class JsonSchema_boolean extends Component {
|
||||
return (<Select className={ errors.length ? "invalid" : ""}
|
||||
title={ errors.length ? errors : ""}
|
||||
value={ String(value) }
|
||||
allowedValues={ fromJS(["true", "false"]) }
|
||||
allowEmptyValue={ true }
|
||||
allowedValues={ fromJS(schema.enum || ["true", "false"]) }
|
||||
allowEmptyValue={ !this.props.required }
|
||||
onChange={ this.onEnumChange }/>)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ export const authorizeAccessCodeWithBasicAuthentication = ( { auth, redirectUrl
|
||||
return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get("tokenUrl"), auth, headers})
|
||||
}
|
||||
|
||||
export const authorizeRequest = ( data ) => ( { fn, authActions, errActions, authSelectors } ) => {
|
||||
export const authorizeRequest = ( data ) => ( { fn, getConfigs, authActions, errActions, authSelectors } ) => {
|
||||
let { body, query={}, headers={}, name, url, auth } = data
|
||||
let { additionalQueryStringParams } = authSelectors.getConfigs() || {}
|
||||
let fetchUrl = url
|
||||
@@ -158,7 +158,9 @@ export const authorizeRequest = ( data ) => ( { fn, authActions, errActions, aut
|
||||
method: "post",
|
||||
headers: _headers,
|
||||
query: query,
|
||||
body: body
|
||||
body: body,
|
||||
requestInterceptor: getConfigs().requestInterceptor,
|
||||
responseInterceptor: getConfigs().responseInterceptor
|
||||
})
|
||||
.then(function (response) {
|
||||
let token = JSON.parse(response.data)
|
||||
|
||||
@@ -7,10 +7,10 @@ export const UPDATE_REQUEST_CONTENT_TYPE = "oas3_set_request_content_type"
|
||||
export const UPDATE_RESPONSE_CONTENT_TYPE = "oas3_set_response_content_type"
|
||||
export const UPDATE_SERVER_VARIABLE_VALUE = "oas3_set_server_variable_value"
|
||||
|
||||
export function setSelectedServer (selectedServerUrl) {
|
||||
export function setSelectedServer (selectedServerUrl, namespace) {
|
||||
return {
|
||||
type: UPDATE_SELECTED_SERVER,
|
||||
payload: selectedServerUrl
|
||||
payload: {selectedServerUrl, namespace}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ export function setResponseContentType ({ value, path, method }) {
|
||||
}
|
||||
}
|
||||
|
||||
export function setServerVariableValue ({ server, key, val }) {
|
||||
export function setServerVariableValue ({ server, namespace, key, val }) {
|
||||
return {
|
||||
type: UPDATE_SERVER_VARIABLE_VALUE,
|
||||
payload: { server, key, val }
|
||||
payload: { server, namespace, key, val }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import OperationLink from "./operation-link.jsx"
|
||||
import Servers from "./servers"
|
||||
import RequestBodyEditor from "./request-body-editor"
|
||||
import HttpAuth from "./http-auth"
|
||||
import OperationServers from "./operation-servers"
|
||||
|
||||
export default {
|
||||
Callbacks,
|
||||
@@ -11,5 +12,6 @@ export default {
|
||||
RequestBody,
|
||||
Servers,
|
||||
RequestBodyEditor,
|
||||
OperationServers,
|
||||
operationLink: OperationLink
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
|
||||
export default class OperationServers extends React.Component {
|
||||
static propTypes = {
|
||||
// for self
|
||||
path: PropTypes.string.isRequired,
|
||||
method: PropTypes.string.isRequired,
|
||||
operationServers: ImPropTypes.list,
|
||||
pathServers: ImPropTypes.list,
|
||||
setSelectedServer: PropTypes.func.isRequired,
|
||||
setServerVariableValue: PropTypes.func.isRequired,
|
||||
getSelectedServer: PropTypes.func.isRequired,
|
||||
getServerVariable: PropTypes.func.isRequired,
|
||||
getEffectiveServerValue: PropTypes.func.isRequired,
|
||||
|
||||
// utils
|
||||
getComponent: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
setSelectedServer = (server) => {
|
||||
const { path, method } = this.props
|
||||
// FIXME: we should be keeping up with this in props/state upstream of us
|
||||
// instead of cheating™ with `forceUpdate`
|
||||
this.forceUpdate()
|
||||
return this.props.setSelectedServer(server, `${path}:${method}`)
|
||||
}
|
||||
|
||||
setServerVariableValue = (obj) => {
|
||||
const { path, method } = this.props
|
||||
// FIXME: we should be keeping up with this in props/state upstream of us
|
||||
// instead of cheating™ with `forceUpdate`
|
||||
this.forceUpdate()
|
||||
return this.props.setServerVariableValue({
|
||||
...obj,
|
||||
namespace: `${path}:${method}`
|
||||
})
|
||||
}
|
||||
|
||||
getSelectedServer = () => {
|
||||
const { path, method } = this.props
|
||||
return this.props.getSelectedServer(`${path}:${method}`)
|
||||
}
|
||||
|
||||
getServerVariable = (server, key) => {
|
||||
const { path, method } = this.props
|
||||
return this.props.getServerVariable({
|
||||
namespace: `${path}:${method}`,
|
||||
server
|
||||
}, key)
|
||||
}
|
||||
|
||||
getEffectiveServerValue = (server) => {
|
||||
const { path, method } = this.props
|
||||
return this.props.getEffectiveServerValue({
|
||||
server,
|
||||
namespace: `${path}:${method}`
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
// for self
|
||||
operationServers,
|
||||
pathServers,
|
||||
|
||||
// util
|
||||
getComponent
|
||||
} = this.props
|
||||
|
||||
if(!operationServers && !pathServers) {
|
||||
return null
|
||||
}
|
||||
|
||||
const Servers = getComponent("Servers")
|
||||
|
||||
const serversToDisplay = operationServers || pathServers
|
||||
const displaying = operationServers ? "operation" : "path"
|
||||
|
||||
return <div className="opblock-section operation-servers">
|
||||
<div className="opblock-section-header">
|
||||
<div className="tab-header">
|
||||
<h4 className="opblock-title">Servers</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div className="opblock-description-wrapper">
|
||||
<h4 className="message">
|
||||
These {displaying}-level options override the global server options.
|
||||
</h4>
|
||||
<Servers
|
||||
servers={serversToDisplay}
|
||||
currentServer={this.getSelectedServer()}
|
||||
setSelectedServer={this.setSelectedServer}
|
||||
setServerVariableValue={this.setServerVariableValue}
|
||||
getServerVariable={this.getServerVariable}
|
||||
getEffectiveServerValue={this.getEffectiveServerValue}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,11 @@ export default class Servers extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { servers } = this.props
|
||||
let { servers, currentServer } = this.props
|
||||
|
||||
if(currentServer) {
|
||||
return
|
||||
}
|
||||
|
||||
//fire 'change' event to set default 'value' of select
|
||||
this.setServer(servers.first().get("url"))
|
||||
@@ -93,9 +97,8 @@ export default class Servers extends React.Component {
|
||||
let shouldShowVariableUI = currentServerVariableDefs.size !== 0
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="servers">
|
||||
<label htmlFor="servers">
|
||||
<span className="servers-title">Servers</span>
|
||||
<select onChange={ this.onServerChange }>
|
||||
{ servers.valueSeq().map(
|
||||
( server ) =>
|
||||
@@ -109,13 +112,14 @@ export default class Servers extends React.Component {
|
||||
</label>
|
||||
{ shouldShowVariableUI ?
|
||||
<div>
|
||||
<h4>Server variables</h4>
|
||||
|
||||
<div className={"computed-url"}>
|
||||
Computed URL:
|
||||
<code>
|
||||
{getEffectiveServerValue(currentServer)}
|
||||
</code>
|
||||
</div>
|
||||
<h4>Server variables</h4>
|
||||
<table>
|
||||
<tbody>
|
||||
{
|
||||
|
||||
@@ -7,8 +7,9 @@ import {
|
||||
} from "./actions"
|
||||
|
||||
export default {
|
||||
[UPDATE_SELECTED_SERVER]: (state, { payload: selectedServerUrl } ) =>{
|
||||
return state.setIn( [ "selectedServer" ], selectedServerUrl)
|
||||
[UPDATE_SELECTED_SERVER]: (state, { payload: { selectedServerUrl, namespace } } ) =>{
|
||||
const path = namespace ? [ namespace, "selectedServer"] : [ "selectedServer"]
|
||||
return state.setIn( path, selectedServerUrl)
|
||||
},
|
||||
[UPDATE_REQUEST_BODY_VALUE]: (state, { payload: { value, pathMethod } } ) =>{
|
||||
let [path, method] = pathMethod
|
||||
@@ -21,7 +22,8 @@ export default {
|
||||
[UPDATE_RESPONSE_CONTENT_TYPE]: (state, { payload: { value, path, method } } ) =>{
|
||||
return state.setIn( [ "requestData", path, method, "responseContentType" ], value)
|
||||
},
|
||||
[UPDATE_SERVER_VARIABLE_VALUE]: (state, { payload: { server, key, val } } ) =>{
|
||||
return state.setIn( [ "serverVariableValues", server, key ], val)
|
||||
[UPDATE_SERVER_VARIABLE_VALUE]: (state, { payload: { server, namespace, key, val } } ) =>{
|
||||
const path = namespace ? [ namespace, "serverVariableValues", server, key ] : [ "serverVariableValues", server, key ]
|
||||
return state.setIn(path, val)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@ function onlyOAS3(selector) {
|
||||
}
|
||||
}
|
||||
|
||||
export const selectedServer = onlyOAS3(state => {
|
||||
return state.getIn(["selectedServer"]) || ""
|
||||
export const selectedServer = onlyOAS3((state, namespace) => {
|
||||
const path = namespace ? [namespace, "selectedServer"] : ["selectedServer"]
|
||||
return state.getIn(path) || ""
|
||||
}
|
||||
)
|
||||
|
||||
@@ -35,19 +36,68 @@ export const responseContentType = onlyOAS3((state, path, method) => {
|
||||
}
|
||||
)
|
||||
|
||||
export const serverVariableValue = onlyOAS3((state, server, key) => {
|
||||
return state.getIn(["serverVariableValues", server, key]) || null
|
||||
export const serverVariableValue = onlyOAS3((state, locationData, key) => {
|
||||
let path
|
||||
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if(typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
if(namespace) {
|
||||
path = [namespace, "serverVariableValues", server, key]
|
||||
} else {
|
||||
path = ["serverVariableValues", server, key]
|
||||
}
|
||||
} else {
|
||||
const server = locationData
|
||||
path = ["serverVariableValues", server, key]
|
||||
}
|
||||
|
||||
return state.getIn(path) || null
|
||||
}
|
||||
)
|
||||
|
||||
export const serverVariables = onlyOAS3((state, server) => {
|
||||
return state.getIn(["serverVariableValues", server]) || OrderedMap()
|
||||
export const serverVariables = onlyOAS3((state, locationData) => {
|
||||
let path
|
||||
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if(typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
if(namespace) {
|
||||
path = [namespace, "serverVariableValues", server]
|
||||
} else {
|
||||
path = ["serverVariableValues", server]
|
||||
}
|
||||
} else {
|
||||
const server = locationData
|
||||
path = ["serverVariableValues", server]
|
||||
}
|
||||
|
||||
return state.getIn(path) || OrderedMap()
|
||||
}
|
||||
)
|
||||
|
||||
export const serverEffectiveValue = onlyOAS3((state, server) => {
|
||||
let varValues = state.getIn(["serverVariableValues", server]) || OrderedMap()
|
||||
let str = server
|
||||
export const serverEffectiveValue = onlyOAS3((state, locationData) => {
|
||||
var varValues, serverValue
|
||||
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if(typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
serverValue = server
|
||||
if(namespace) {
|
||||
varValues = state.getIn([namespace, "serverVariableValues", serverValue])
|
||||
} else {
|
||||
varValues = state.getIn(["serverVariableValues", serverValue])
|
||||
}
|
||||
} else {
|
||||
serverValue = locationData
|
||||
varValues = state.getIn(["serverVariableValues", serverValue])
|
||||
}
|
||||
|
||||
varValues = varValues || OrderedMap()
|
||||
let str = serverValue
|
||||
|
||||
varValues.map((val, key) => {
|
||||
str = str.replace(new RegExp(`{${key}}`, "g"), val)
|
||||
|
||||
@@ -228,9 +228,18 @@ export const executeRequest = (req) =>
|
||||
}
|
||||
|
||||
if(specSelectors.isOAS3()) {
|
||||
// OAS3 request feature support
|
||||
req.server = oas3Selectors.selectedServer()
|
||||
req.serverVariables = oas3Selectors.serverVariables(req.server).toJS()
|
||||
const namespace = `${pathName}:${method}`
|
||||
|
||||
req.server = oas3Selectors.selectedServer(namespace) || oas3Selectors.selectedServer()
|
||||
|
||||
const namespaceVariables = oas3Selectors.serverVariables({
|
||||
server: req.server,
|
||||
namespace
|
||||
}).toJS()
|
||||
const globalVariables = oas3Selectors.serverVariables({ server: req.server }).toJS()
|
||||
|
||||
req.serverVariables = Object.keys(namespaceVariables).length ? namespaceVariables : globalVariables
|
||||
|
||||
req.requestContentType = oas3Selectors.requestContentType(pathName, method)
|
||||
req.responseContentType = oas3Selectors.responseContentType(pathName, method) || "*/*"
|
||||
const requestBody = oas3Selectors.requestBodyValue(pathName, method)
|
||||
|
||||
+5
-2
@@ -473,6 +473,9 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
|
||||
let required = param.get("required")
|
||||
|
||||
let paramDetails = isOAS3 ? param.get("schema") : param
|
||||
|
||||
if(!paramDetails) return errors
|
||||
|
||||
let maximum = paramDetails.get("maximum")
|
||||
let minimum = paramDetails.get("minimum")
|
||||
let type = paramDetails.get("type")
|
||||
@@ -480,7 +483,7 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
|
||||
let maxLength = paramDetails.get("maxLength")
|
||||
let minLength = paramDetails.get("minLength")
|
||||
let pattern = paramDetails.get("pattern")
|
||||
|
||||
|
||||
|
||||
/*
|
||||
If the parameter is required OR the parameter has a value (meaning optional, but filled in)
|
||||
@@ -506,7 +509,7 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
|
||||
let err = validatePattern(value, pattern)
|
||||
if (err) errors.push(err)
|
||||
}
|
||||
|
||||
|
||||
if (maxLength || maxLength === 0) {
|
||||
let err = validateMaxLength(value, maxLength)
|
||||
if (err) errors.push(err)
|
||||
|
||||
@@ -650,78 +650,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.server-container
|
||||
{
|
||||
margin: 0 0 20px 0;
|
||||
padding: 30px 0;
|
||||
|
||||
background: $server-container-background-color;
|
||||
box-shadow: 0 1px 2px 0 rgba($server-container-box-shadow-color,.15);
|
||||
|
||||
.computed-url {
|
||||
margin: 2em 0;
|
||||
|
||||
code {
|
||||
color: $server-container-computed-url-code-font-color;
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
font-size: 16px;
|
||||
margin: 0 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
.servers
|
||||
{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.servers-title {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
> label
|
||||
{
|
||||
font-size: 12px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
margin: -20px 15px 0 0;
|
||||
|
||||
@include text_headline();
|
||||
|
||||
select
|
||||
{
|
||||
min-width: 130px;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
tr {
|
||||
width: 30em;
|
||||
}
|
||||
td {
|
||||
display: inline-block;
|
||||
max-width: 15em;
|
||||
vertical-align: middle;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
&:first-of-type {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.loading-container
|
||||
{
|
||||
padding: 40px 0 60px;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
.servers
|
||||
{
|
||||
> label
|
||||
{
|
||||
font-size: 12px;
|
||||
|
||||
margin: -20px 15px 0 0;
|
||||
|
||||
@include text_headline();
|
||||
|
||||
select
|
||||
{
|
||||
min-width: 130px;
|
||||
}
|
||||
}
|
||||
|
||||
h4.message {
|
||||
padding-bottom: 2em;
|
||||
}
|
||||
|
||||
table {
|
||||
tr {
|
||||
width: 30em;
|
||||
}
|
||||
td {
|
||||
display: inline-block;
|
||||
max-width: 15em;
|
||||
vertical-align: middle;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
&:first-of-type {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.computed-url {
|
||||
margin: 2em 0;
|
||||
|
||||
code {
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
font-size: 16px;
|
||||
margin: 0 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.global-server-container
|
||||
{
|
||||
margin: 0 0 20px 0;
|
||||
padding: 30px 0;
|
||||
|
||||
background: $server-container-background-color;
|
||||
box-shadow: 0 1px 2px 0 rgba($server-container-box-shadow-color,.15);
|
||||
|
||||
.servers-title {
|
||||
line-height: 2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.operation-servers {
|
||||
h4.message {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
@import 'form';
|
||||
@import 'modal';
|
||||
@import 'models';
|
||||
@import 'servers';
|
||||
@import 'table';
|
||||
@import 'topbar';
|
||||
@import 'information';
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/* eslint-env mocha */
|
||||
import React from "react"
|
||||
import expect, { createSpy } from "expect"
|
||||
import { Select, Input } from "components/layout-utils"
|
||||
import { render } from "enzyme"
|
||||
import * as JsonSchemaComponents from "core/json-schema-components"
|
||||
import { JsonSchemaForm } from "core/json-schema-components"
|
||||
|
||||
const components = {...JsonSchemaComponents, Select, Input}
|
||||
|
||||
const getComponentStub = (name) => {
|
||||
if(components[name]) return components[name]
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
describe("<JsonSchemaForm/>", function(){
|
||||
describe("strings", function() {
|
||||
it("should render the correct options for a string enum parameter", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
schema: {
|
||||
type: "string",
|
||||
enum: ["one", "two"]
|
||||
}
|
||||
}
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("select").length).toEqual(1)
|
||||
expect(wrapper.find("select option").length).toEqual(3)
|
||||
expect(wrapper.find("select option").eq(0).text()).toEqual("--")
|
||||
expect(wrapper.find("select option").eq(1).text()).toEqual("one")
|
||||
expect(wrapper.find("select option").eq(2).text()).toEqual("two")
|
||||
})
|
||||
|
||||
it("should render the correct options for a required string enum parameter", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
required: true,
|
||||
schema: {
|
||||
type: "string",
|
||||
enum: ["one", "two"]
|
||||
}
|
||||
}
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("select").length).toEqual(1)
|
||||
expect(wrapper.find("select option").length).toEqual(2)
|
||||
expect(wrapper.find("select option").eq(0).text()).toEqual("one")
|
||||
expect(wrapper.find("select option").eq(1).text()).toEqual("two")
|
||||
})
|
||||
})
|
||||
describe("booleans", function() {
|
||||
it("should render the correct options for a boolean parameter", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
schema: {
|
||||
type: "boolean"
|
||||
}
|
||||
}
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("select").length).toEqual(1)
|
||||
expect(wrapper.find("select option").length).toEqual(3)
|
||||
expect(wrapper.find("select option").eq(0).text()).toEqual("--")
|
||||
expect(wrapper.find("select option").eq(1).text()).toEqual("true")
|
||||
expect(wrapper.find("select option").eq(2).text()).toEqual("false")
|
||||
})
|
||||
|
||||
it("should render the correct options for a required enum boolean parameter", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
required: true,
|
||||
schema: {
|
||||
type: "boolean",
|
||||
enum: ["true"]
|
||||
}
|
||||
}
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("select").length).toEqual(1)
|
||||
expect(wrapper.find("select option").length).toEqual(1)
|
||||
expect(wrapper.find("select option").first().text()).toEqual("true")
|
||||
})
|
||||
})
|
||||
describe("unknown types", function() {
|
||||
it("should render unknown types as strings", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "yo",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
schema: {
|
||||
type: "NotARealType"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("input").length).toEqual(1)
|
||||
// expect(wrapper.find("select input").length).toEqual(1)
|
||||
// expect(wrapper.find("select option").first().text()).toEqual("true")
|
||||
})
|
||||
|
||||
it("should render unknown types as strings when a format is passed", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "yo",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
schema: {
|
||||
type: "NotARealType",
|
||||
format: "NotARealFormat"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("input").length).toEqual(1)
|
||||
// expect(wrapper.find("select input").length).toEqual(1)
|
||||
// expect(wrapper.find("select option").first().text()).toEqual("true")
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,359 @@
|
||||
import expect from "expect"
|
||||
import { fromJS, OrderedMap } from "immutable"
|
||||
|
||||
import {
|
||||
selectedServer,
|
||||
serverVariableValue,
|
||||
serverVariables,
|
||||
serverEffectiveValue
|
||||
} from "corePlugins/oas3/selectors"
|
||||
|
||||
import reducers from "corePlugins/oas3/reducers"
|
||||
|
||||
import {
|
||||
setSelectedServer,
|
||||
setServerVariableValue,
|
||||
} from "corePlugins/oas3/actions"
|
||||
|
||||
describe("OAS3 plugin - state", function() {
|
||||
describe("action + reducer + selector integration", function() {
|
||||
describe("selectedServer", function() {
|
||||
it("should set and get a global selectedServer", function() {
|
||||
const state = new OrderedMap()
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setSelectedServer("http://google.com")
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_servers"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = selectedServer(newState)(system)
|
||||
|
||||
expect(res).toEqual("http://google.com")
|
||||
})
|
||||
|
||||
it("should set and get a namespaced selectedServer", function() {
|
||||
const state = fromJS({
|
||||
selectedServer: "http://yahoo.com"
|
||||
})
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setSelectedServer("http://google.com", "myOperation")
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_servers"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = selectedServer(newState, "myOperation")(system)
|
||||
|
||||
// Get the global selected server
|
||||
const globalRes = selectedServer(newState)(system)
|
||||
|
||||
expect(res).toEqual("http://google.com")
|
||||
expect(globalRes).toEqual("http://yahoo.com")
|
||||
})
|
||||
})
|
||||
|
||||
describe("serverVariableValue", function() {
|
||||
it("should set and get a global serverVariableValue", function() {
|
||||
const state = new OrderedMap()
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setServerVariableValue({
|
||||
server: "google.com",
|
||||
key: "foo",
|
||||
val: "bar"
|
||||
})
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_server_variable_value"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverVariableValue(newState, "google.com", "foo")(system)
|
||||
|
||||
expect(res).toEqual("bar")
|
||||
})
|
||||
it("should set and get a namespaced serverVariableValue", function() {
|
||||
const state = fromJS({
|
||||
serverVariableValues: {
|
||||
"google.com": {
|
||||
foo: "123"
|
||||
}
|
||||
}
|
||||
})
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setServerVariableValue({
|
||||
namespace: "myOperation",
|
||||
server: "google.com",
|
||||
key: "foo",
|
||||
val: "bar"
|
||||
})
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_server_variable_value"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverVariableValue(newState, {
|
||||
namespace: "myOperation",
|
||||
server: "google.com"
|
||||
}, "foo")(system)
|
||||
|
||||
// Get the global value, to cross-check
|
||||
const globalRes = serverVariableValue(newState, {
|
||||
server: "google.com"
|
||||
}, "foo")(system)
|
||||
|
||||
expect(res).toEqual("bar")
|
||||
expect(globalRes).toEqual("123")
|
||||
})
|
||||
})
|
||||
|
||||
describe("serverVariables", function() {
|
||||
it("should set and get global serverVariables", function() {
|
||||
const state = new OrderedMap()
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setServerVariableValue({
|
||||
server: "google.com",
|
||||
key: "foo",
|
||||
val: "bar"
|
||||
})
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_server_variable_value"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverVariables(newState, "google.com", "foo")(system)
|
||||
|
||||
expect(res.toJS()).toEqual({
|
||||
foo: "bar"
|
||||
})
|
||||
})
|
||||
|
||||
it("should set and get namespaced serverVariables", function() {
|
||||
const state = fromJS({
|
||||
serverVariableValues: {
|
||||
"google.com": {
|
||||
foo: "123"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setServerVariableValue({
|
||||
namespace: "myOperation",
|
||||
server: "google.com",
|
||||
key: "foo",
|
||||
val: "bar"
|
||||
})
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_server_variable_value"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverVariables(newState, {
|
||||
namespace: "myOperation",
|
||||
server: "google.com"
|
||||
}, "foo")(system)
|
||||
|
||||
// Get the global value, to cross-check
|
||||
const globalRes = serverVariables(newState, {
|
||||
server: "google.com"
|
||||
}, "foo")(system)
|
||||
|
||||
expect(res.toJS()).toEqual({
|
||||
foo: "bar"
|
||||
})
|
||||
|
||||
expect(globalRes.toJS()).toEqual({
|
||||
foo: "123"
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("serverEffectiveValue", function() {
|
||||
it("should set variable values and compute a URL for a namespaced server", function() {
|
||||
const state = fromJS({
|
||||
serverVariableValues: {
|
||||
"google.com/{foo}": {
|
||||
foo: "123"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setServerVariableValue({
|
||||
namespace: "myOperation",
|
||||
server: "google.com/{foo}",
|
||||
key: "foo",
|
||||
val: "bar"
|
||||
})
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_server_variable_value"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverEffectiveValue(newState, {
|
||||
namespace: "myOperation",
|
||||
server: "google.com/{foo}"
|
||||
})(system)
|
||||
|
||||
// Get the global value, to cross-check
|
||||
const globalRes = serverEffectiveValue(newState, {
|
||||
server: "google.com/{foo}"
|
||||
})(system)
|
||||
|
||||
expect(res).toEqual("google.com/bar")
|
||||
|
||||
expect(globalRes).toEqual("google.com/123")
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
describe("selectors", function() {
|
||||
describe("serverEffectiveValue", function() {
|
||||
it("should compute global serverEffectiveValues", function() {
|
||||
const state = fromJS({
|
||||
serverVariableValues: {
|
||||
"google.com/{foo}/{bar}": {
|
||||
foo: "123",
|
||||
bar: "456"
|
||||
}
|
||||
}
|
||||
})
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverEffectiveValue(state, "google.com/{foo}/{bar}")(system)
|
||||
|
||||
expect(res).toEqual("google.com/123/456")
|
||||
})
|
||||
|
||||
it("should handle multiple variable instances", function() {
|
||||
const state = fromJS({
|
||||
serverVariableValues: {
|
||||
"google.com/{foo}/{foo}/{bar}": {
|
||||
foo: "123",
|
||||
bar: "456"
|
||||
}
|
||||
}
|
||||
})
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverEffectiveValue(state, "google.com/{foo}/{foo}/{bar}")(system)
|
||||
|
||||
expect(res).toEqual("google.com/123/123/456")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
+2
-5
@@ -321,14 +321,11 @@ describe("utils", function() {
|
||||
}
|
||||
|
||||
it("should check the isOAS3 flag when validating parameters", function() {
|
||||
// This should "skip" validation because there is no `schema.type` property
|
||||
// This should "skip" validation because there is no `schema` property
|
||||
// and we are telling `validateParam` this is an OAS3 spec
|
||||
param = fromJS({
|
||||
value: "",
|
||||
required: true,
|
||||
schema: {
|
||||
notTheTypeProperty: "string"
|
||||
}
|
||||
required: true
|
||||
})
|
||||
result = validateParam( param, false, true )
|
||||
expect( result ).toEqual( [] )
|
||||
|
||||
Reference in New Issue
Block a user