Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f784472857 | ||
|
|
c888daf9b4 | ||
|
|
cbff0251ae | ||
|
|
62354568a9 | ||
|
|
d981f0f26e | ||
|
|
44c3f09abe | ||
|
|
0c50c7e99f | ||
|
|
62ed4db110 | ||
|
|
553acee07d | ||
|
|
932cc9838c | ||
|
|
d3c9ceceef | ||
|
|
5f855e56bb | ||
|
|
3f6e21e3b1 | ||
|
|
26d0ad7684 | ||
|
|
9a121ea445 | ||
|
|
c55f22575a | ||
|
|
2795518340 | ||
|
|
2bf2167a18 | ||
|
|
dc7d7054bf | ||
|
|
14473dd51d | ||
|
|
a0b659a96e | ||
|
|
3efdf1223e | ||
|
|
911a140e38 | ||
|
|
e2d8a4e396 | ||
|
|
39d34523b9 | ||
|
|
d90353228a | ||
|
|
4480db0390 |
@@ -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.13.2 | 2018-03-23 | 2.0, 3.0 | [tag v3.13.2](https://github.com/swagger-api/swagger-ui/tree/v3.13.2)
|
||||
3.13.5 | 2018-04-20 | 2.0, 3.0 | [tag v3.13.5](https://github.com/swagger-api/swagger-ui/tree/v3.13.5)
|
||||
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)
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: Brentertainment OAuth2 Test Server
|
||||
description: >
|
||||
The server does not support CORS (yet?), so you need to take the strange step of disabling Same-Origin Policy in your browser.
|
||||
[Here](https://www.thepolyglotdeveloper.com/2014/08/bypass-cors-errors-testing-apis-locally/) are some instructions.
|
||||
license:
|
||||
name: MIT
|
||||
servers:
|
||||
- url: http://brentertainment.com/oauth2/lockdin/
|
||||
paths:
|
||||
/resource:
|
||||
get:
|
||||
description: Protected resource
|
||||
security:
|
||||
- oauth2AuthorizationCode: ["resource"]
|
||||
- oauth2Implicit: ["resource"]
|
||||
- oauth2Password: ["resource"]
|
||||
- oauth2ClientCredentials: ["resource"]
|
||||
- oauth2Multiflow: ["resource"]
|
||||
responses:
|
||||
200:
|
||||
description: the only response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
components:
|
||||
securitySchemes:
|
||||
oauth2AuthorizationCode:
|
||||
type: oauth2
|
||||
flows:
|
||||
authorizationCode:
|
||||
authorizationUrl: "http://brentertainment.com/oauth2/lockdin/authorize"
|
||||
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
|
||||
scopes:
|
||||
resource: our only scope
|
||||
oauth2Implicit:
|
||||
type: oauth2
|
||||
flows:
|
||||
implicit:
|
||||
authorizationUrl: "http://brentertainment.com/oauth2/lockdin/authorize"
|
||||
scopes:
|
||||
resource: our only scope
|
||||
oauth2Password:
|
||||
type: oauth2
|
||||
flows:
|
||||
password:
|
||||
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
|
||||
scopes:
|
||||
resource: our only scope
|
||||
oauth2ClientCredentials:
|
||||
type: oauth2
|
||||
flows:
|
||||
clientCredentials:
|
||||
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
|
||||
scopes:
|
||||
resource: our only scope
|
||||
oauth2Multiflow:
|
||||
type: oauth2
|
||||
flows:
|
||||
clientCredentials:
|
||||
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
|
||||
scopes:
|
||||
resource: our only scope
|
||||
password:
|
||||
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
|
||||
scopes:
|
||||
resource: our only scope
|
||||
implicit:
|
||||
authorizationUrl: "http://brentertainment.com/oauth2/lockdin/authorize"
|
||||
scopes:
|
||||
resource: our only scope
|
||||
authorizationCode:
|
||||
authorizationUrl: "http://brentertainment.com/oauth2/lockdin/authorize"
|
||||
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
|
||||
scopes:
|
||||
resource: our only scope
|
||||
+35
-67
@@ -16,13 +16,16 @@
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
body {
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
@@ -30,75 +33,40 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
|
||||
<defs>
|
||||
<symbol viewBox="0 0 20 20" id="unlocked">
|
||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
|
||||
</symbol>
|
||||
<script src="./swagger-ui-bundle.js"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
window["SwaggerUIBundle"] = window["swagger-ui-bundle"]
|
||||
window["SwaggerUIStandalonePreset"] = window["swagger-ui-standalone-preset"]
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "http://petstore.swagger.io/v2/swagger.json",
|
||||
dom_id: '#swagger-ui',
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="locked">
|
||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
|
||||
</symbol>
|
||||
window.ui = ui
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="close">
|
||||
<path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow">
|
||||
<path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow-down">
|
||||
<path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
|
||||
</symbol>
|
||||
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="jump-to">
|
||||
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="expand">
|
||||
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
|
||||
</symbol>
|
||||
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
window["SwaggerUIBundle"] = window["swagger-ui-bundle"]
|
||||
window["SwaggerUIStandalonePreset"] = window["swagger-ui-standalone-preset"]
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "http://petstore.swagger.io/v2/swagger.json",
|
||||
dom_id: '#swagger-ui',
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
|
||||
window.ui = ui
|
||||
|
||||
ui.initOAuth({
|
||||
clientId: "your-client-id",
|
||||
clientSecret: "your-client-secret-if-required",
|
||||
realm: "your-realms",
|
||||
appName: "your-app-name",
|
||||
scopeSeparator: " ",
|
||||
additionalQueryStringParams: {}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
ui.initOAuth({
|
||||
clientId: "your-client-id",
|
||||
clientSecret: "your-client-secret-if-required",
|
||||
realm: "your-realms",
|
||||
appName: "your-app-name",
|
||||
scopeSeparator: " ",
|
||||
additionalQueryStringParams: {}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
Vendored
+56
-90
@@ -1,95 +1,61 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "http://petstore.swagger.io/v2/swagger.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
|
||||
<defs>
|
||||
<symbol viewBox="0 0 20 20" id="unlocked">
|
||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="locked">
|
||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="close">
|
||||
<path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow">
|
||||
<path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow-down">
|
||||
<path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
|
||||
</symbol>
|
||||
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="jump-to">
|
||||
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="expand">
|
||||
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
|
||||
</symbol>
|
||||
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "http://petstore.swagger.io/v2/swagger.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Vendored
+18
-18
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
+3
-3
File diff suppressed because one or more lines are too long
+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
@@ -18,7 +18,7 @@ class OperationsLayout extends React.Component {
|
||||
getComponent
|
||||
} = this.props
|
||||
|
||||
const Operations = getComponent("Operations", true)
|
||||
const Operations = getComponent("operations", true)
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -68,7 +68,7 @@ There is no dependency management built into the plugin system, so if you create
|
||||
|
||||
### Interfaces
|
||||
|
||||
##### Actions
|
||||
#### Actions
|
||||
|
||||
```javascript
|
||||
const MyActionPlugin = () => {
|
||||
@@ -102,7 +102,7 @@ This action creator function will be exposed to container components as `example
|
||||
|
||||
For more information about the concept of actions in Redux, see the [Redux Actions documentation](http://redux.js.org/docs/basics/Actions.html).
|
||||
|
||||
##### Reducers
|
||||
#### Reducers
|
||||
|
||||
Reducers take a state (which is an [Immutable.js map](https://facebook.github.io/immutable-js/docs/#/Map)) and an action, and return a new state.
|
||||
|
||||
@@ -126,7 +126,7 @@ const MyReducerPlugin = function(system) {
|
||||
}
|
||||
```
|
||||
|
||||
##### Selectors
|
||||
#### Selectors
|
||||
|
||||
Selectors reach into their namespace's state to retrieve or derive data from the state.
|
||||
|
||||
@@ -172,7 +172,7 @@ Once a selector has been defined, you can use it anywhere that you can get a sys
|
||||
system.exampleSelectors.myFavoriteColor() // gets `favColor` in state for you
|
||||
```
|
||||
|
||||
##### Components
|
||||
#### Components
|
||||
|
||||
You can provide a map of components to be integrated into the system.
|
||||
|
||||
@@ -214,7 +214,7 @@ const NeverShowInfoPlugin = function(system) {
|
||||
}
|
||||
```
|
||||
|
||||
##### Wrap-Actions
|
||||
#### Wrap-Actions
|
||||
|
||||
Wrap Actions allow you to override the behavior of an action in the system.
|
||||
|
||||
@@ -262,7 +262,7 @@ const MyWrapActionPlugin = function(system) {
|
||||
}
|
||||
```
|
||||
|
||||
##### Wrap-Selectors
|
||||
#### Wrap-Selectors
|
||||
|
||||
Wrap Selectors allow you to override the behavior of a selector in the system.
|
||||
|
||||
@@ -307,7 +307,7 @@ const MyWrapSelectorsPlugin = function(system) {
|
||||
}
|
||||
```
|
||||
|
||||
##### Wrap-Components
|
||||
#### Wrap-Components
|
||||
|
||||
Wrap Components allow you to override a component registered within the system.
|
||||
|
||||
@@ -381,7 +381,7 @@ const MyWrapComponentPlugin = function(system) {
|
||||
}
|
||||
```
|
||||
|
||||
##### `rootInjects`
|
||||
#### `rootInjects`
|
||||
|
||||
The `rootInjects` interface allows you to inject values at the top level of the system.
|
||||
|
||||
@@ -398,7 +398,7 @@ const MyRootInjectsPlugin = function(system) {
|
||||
}
|
||||
```
|
||||
|
||||
##### `afterLoad`
|
||||
#### `afterLoad`
|
||||
|
||||
The `afterLoad` plugin method allows you to get a reference to the system after your plugin has been registered.
|
||||
|
||||
@@ -431,7 +431,7 @@ const MyMethodProvidingPlugin = function() {
|
||||
}
|
||||
```
|
||||
|
||||
##### fn
|
||||
#### fn
|
||||
|
||||
The fn interface allows you to add helper functions to the system for use elsewhere.
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ Parameter Name | Description
|
||||
`maxDisplayedTags` | `Number`. If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.
|
||||
`operationsSorter` | `Function=(a => a)`. Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.
|
||||
`showExtensions` | `Boolean=false`. Controls the display of vendor extension (`x-`) fields and values for Operations, Parameters, and Schema.
|
||||
`showCommonExtensions` | `Boolean=false`. Controls the display of extensions (`pattern`, `maxLength`, `minLength`, `maximum`, `minimum`) fields and values for Parameters.
|
||||
`tagsSorter` | `Function=(a => a)`. Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function (see [Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger-UI.
|
||||
`onComplete` | `Function=NOOP`. Provides a mechanism to be notified when Swagger-UI has finished rendering a newly provided definition.
|
||||
|
||||
@@ -66,8 +67,8 @@ Parameter Name | Description
|
||||
Parameter Name | Description
|
||||
--- | ---
|
||||
`oauth2RedirectUrl` | `String`. OAuth redirect URL.
|
||||
`requestInterceptor` | `Function=(a => a)`. 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` |`Function=(a => a)`. 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.
|
||||
`requestInterceptor` | `Function=(a => a)`. MUST be a function. Function to intercept remote definition, Try-It-Out, and OAuth2 requests. Accepts one argument requestInterceptor(request) and must return the modified request, or a Promise that resolves to the modified request.
|
||||
`responseInterceptor` |`Function=(a => a)`. MUST be a function. Function to intercept remote definition, Try-It-Out, and OAuth2 responses. Accepts one argument responseInterceptor(response) and must return the modified response, or a Promise that resolves to the modified response.
|
||||
`showMutatedRequest` | `Boolean=true`. If set to `true`, uses the mutated request returned from a requestInterceptor to produce the curl command in the UI, otherwise the request before the requestInterceptor was applied is used.
|
||||
`supportedSubmitMethods` | `Array=["get", "put", "post", "delete", "options", "head", "patch", "trace"]`. List of HTTP methods that have the Try it out feature enabled. An empty array disables Try it out for all operations. This does not filter the operations from the display.
|
||||
`validatorUrl` | `String="https://online.swagger.io/validator" OR null`. By default, Swagger-UI attempts to validate specs against swagger.io's online validator. You can use this parameter to set a different validator URL, for example for locally deployed validators ([Validator Badge](https://github.com/swagger-api/validator-badge)). Setting it to `null` will disable validation.
|
||||
|
||||
+4
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "swagger-ui",
|
||||
"version": "3.13.2",
|
||||
"version": "3.13.6",
|
||||
"main": "dist/swagger-ui.js",
|
||||
"repository": "git@github.com:swagger-api/swagger-ui.git",
|
||||
"contributors": [
|
||||
@@ -36,7 +36,7 @@
|
||||
"test-e2e": "sleep 3 && nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json",
|
||||
"e2e-initial-render": "nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json --group initial-render",
|
||||
"mock-api": "json-server --watch test/e2e/db.json --port 3204",
|
||||
"hot-e2e-server": "webpack-dev-server --content-base test/e2e/helpers --host 0.0.0.0 --config webpack-hot-dev-server.config.js --inline --hot --progress",
|
||||
"hot-e2e-server": "webpack-dev-server --port 3230 --content-base test/e2e/helpers --host 0.0.0.0 --config webpack-hot-dev-server.config.js --inline --hot --progress",
|
||||
"e2e": "npm-run-all --parallel -r hot-e2e-server mock-api test-e2e"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -52,6 +52,7 @@
|
||||
"getbase": "^2.8.2",
|
||||
"ieee754": "^1.1.8",
|
||||
"immutable": "^3.x.x",
|
||||
"js-file-download": "^0.4.1",
|
||||
"js-yaml": "^3.5.5",
|
||||
"lodash": "4.17.5",
|
||||
"matcher": "^0.1.2",
|
||||
@@ -83,7 +84,7 @@
|
||||
"scroll-to-element": "^2.0.0",
|
||||
"serialize-error": "2.0.0",
|
||||
"shallowequal": "0.2.2",
|
||||
"swagger-client": "^3.5.2",
|
||||
"swagger-client": "^3.7.2",
|
||||
"url-parse": "^1.1.8",
|
||||
"whatwg-fetch": "0.11.1",
|
||||
"worker-loader": "^0.7.1",
|
||||
|
||||
@@ -99,10 +99,13 @@ export default class Auths extends React.Component {
|
||||
{
|
||||
definitions.filter( schema => schema.get("type") === "oauth2")
|
||||
.map( (schema, name) =>{
|
||||
return (<div key={ name }>
|
||||
const { flow } = schema
|
||||
const key = [name, flow].join("__").slice(0, -2)
|
||||
return (<div key={ key }>
|
||||
<Oauth2 authorized={ authorized }
|
||||
schema={ schema }
|
||||
name={ name } />
|
||||
authId={ key }
|
||||
name={ key || schema.get("name") || name } />
|
||||
</div>)
|
||||
}
|
||||
).toArray()
|
||||
|
||||
@@ -47,11 +47,11 @@ export default class Oauth2 extends React.Component {
|
||||
}
|
||||
|
||||
authorize =() => {
|
||||
let { authActions, errActions, getConfigs, authSelectors } = this.props
|
||||
let { authActions, errActions, getConfigs, authSelectors, authId } = this.props
|
||||
let configs = getConfigs()
|
||||
let authConfigs = authSelectors.getConfigs()
|
||||
|
||||
errActions.clear({authId: name,type: "auth", source: "auth"})
|
||||
errActions.clear({authId: authId ,type: "auth", source: "auth"})
|
||||
oauth2Authorize({auth: this.state, authActions, errActions, configs, authConfigs })
|
||||
}
|
||||
|
||||
@@ -79,15 +79,15 @@ export default class Oauth2 extends React.Component {
|
||||
|
||||
logout =(e) => {
|
||||
e.preventDefault()
|
||||
let { authActions, errActions, name } = this.props
|
||||
let { authActions, errActions, authId } = this.props
|
||||
|
||||
errActions.clear({authId: name, type: "auth", source: "auth"})
|
||||
authActions.logout([ name ])
|
||||
errActions.clear({authId: authId, type: "auth", source: "auth"})
|
||||
authActions.logout([ authId ])
|
||||
}
|
||||
|
||||
render() {
|
||||
let {
|
||||
schema, getComponent, authSelectors, errSelectors, name, specSelectors
|
||||
schema, getComponent, authSelectors, errSelectors, name, authId, specSelectors
|
||||
} = this.props
|
||||
const Input = getComponent("Input")
|
||||
const Row = getComponent("Row")
|
||||
@@ -107,9 +107,9 @@ export default class Oauth2 extends React.Component {
|
||||
|
||||
let flow = schema.get("flow")
|
||||
let scopes = schema.get("allowedScopes") || schema.get("scopes")
|
||||
let authorizedAuth = authSelectors.authorized().get(name)
|
||||
let authorizedAuth = authSelectors.authorized().get(authId)
|
||||
let isAuthorized = !!authorizedAuth
|
||||
let errors = errSelectors.allErrors().filter( err => err.get("authId") === name)
|
||||
let errors = errSelectors.allErrors().filter( err => err.get("authId") === authId)
|
||||
let isValid = !errors.filter( err => err.get("source") === "validation").size
|
||||
let description = schema.get("description")
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import React, { Component } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { highlight } from "core/utils"
|
||||
import saveAs from "js-file-download"
|
||||
|
||||
export default class HighlightCode extends Component {
|
||||
static propTypes = {
|
||||
value: PropTypes.string.isRequired,
|
||||
className: PropTypes.string
|
||||
className: PropTypes.string,
|
||||
downloadable: PropTypes.bool
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -20,10 +22,47 @@ export default class HighlightCode extends Component {
|
||||
this.el = c
|
||||
}
|
||||
|
||||
downloadText = () => {
|
||||
saveAs(this.props.value, "response.txt")
|
||||
}
|
||||
|
||||
preventYScrollingBeyondElement = (e) => {
|
||||
const target = e.target
|
||||
|
||||
var deltaY = e.nativeEvent.deltaY
|
||||
var contentHeight = target.scrollHeight
|
||||
var visibleHeight = target.offsetHeight
|
||||
var scrollTop = target.scrollTop
|
||||
|
||||
const scrollOffset = visibleHeight + scrollTop
|
||||
|
||||
const isElementScrollable = contentHeight > visibleHeight
|
||||
const isScrollingPastTop = scrollTop === 0 && deltaY < 0
|
||||
const isScrollingPastBottom = scrollOffset >= contentHeight && deltaY > 0
|
||||
|
||||
if (isElementScrollable && (isScrollingPastTop || isScrollingPastBottom)) {
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
let { value, className } = this.props
|
||||
let { value, className, downloadable } = this.props
|
||||
className = className || ""
|
||||
|
||||
return <pre ref={this.initializeComponent} className={className + " microlight"}>{ value }</pre>
|
||||
return (
|
||||
<div className="highlight-code">
|
||||
{ !downloadable ? null :
|
||||
<div className="download-contents" onClick={this.downloadText}>
|
||||
Download
|
||||
</div>
|
||||
}
|
||||
<pre
|
||||
ref={this.initializeComponent}
|
||||
onWheel={this.preventYScrollingBeyondElement}
|
||||
className={className + " microlight"}>
|
||||
{value}
|
||||
</pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ export default class BaseLayout extends React.Component {
|
||||
let schemes = specSelectors.schemes()
|
||||
let servers = specSelectors.servers()
|
||||
|
||||
let SvgAssets = getComponent("SvgAssets")
|
||||
let Info = getComponent("info")
|
||||
let Operations = getComponent("operations", true)
|
||||
let Models = getComponent("Models", true)
|
||||
@@ -78,6 +79,7 @@ export default class BaseLayout extends React.Component {
|
||||
return (
|
||||
|
||||
<div className='swagger-ui'>
|
||||
<SvgAssets />
|
||||
<div>
|
||||
<Errors/>
|
||||
<Row className="information-container">
|
||||
|
||||
@@ -72,6 +72,7 @@ export default class Operation extends PureComponent {
|
||||
tag,
|
||||
showSummary,
|
||||
operationId,
|
||||
originalOperationId,
|
||||
allowTryItOut,
|
||||
displayOperationId,
|
||||
displayRequestDuration,
|
||||
@@ -140,7 +141,7 @@ export default class Operation extends PureComponent {
|
||||
</div>
|
||||
}
|
||||
|
||||
{ displayOperationId && operationId ? <span className="opblock-summary-operation-id">{operationId}</span> : null }
|
||||
{ displayOperationId && (originalOperationId || operationId) ? <span className="opblock-summary-operation-id">{originalOperationId || operationId}</span> : null }
|
||||
|
||||
{
|
||||
(!security || !security.count()) ? null :
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Map } from "immutable"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import win from "core/window"
|
||||
import { getExtensions } from "core/utils"
|
||||
import { getExtensions, getCommonExtensions } from "core/utils"
|
||||
|
||||
export default class ParameterRow extends Component {
|
||||
static propTypes = {
|
||||
@@ -82,7 +82,7 @@ export default class ParameterRow extends Component {
|
||||
|
||||
let { isOAS3 } = specSelectors
|
||||
|
||||
const { showExtensions } = getConfigs()
|
||||
const { showExtensions, showCommonExtensions } = getConfigs()
|
||||
|
||||
// const onChangeWrapper = (value) => onChange(param, value)
|
||||
const JsonSchemaForm = getComponent("JsonSchemaForm")
|
||||
@@ -106,41 +106,46 @@ export default class ParameterRow extends Component {
|
||||
const ParameterExt = getComponent("ParameterExt")
|
||||
|
||||
let paramWithMeta = specSelectors.parameterWithMeta(pathMethod, param.get("name"), param.get("in"))
|
||||
|
||||
let schema = param.get("schema")
|
||||
let type = isOAS3 && isOAS3() ? param.getIn(["schema", "type"]) : param.get("type")
|
||||
let format = param.get("format")
|
||||
let schema = isOAS3 && isOAS3() ? param.get("schema") : param
|
||||
let type = schema.get("type")
|
||||
let isFormData = inType === "formData"
|
||||
let isFormDataSupported = "FormData" in win
|
||||
let required = param.get("required")
|
||||
let itemType = param.getIn(isOAS3 && isOAS3() ? ["schema", "items", "type"] : ["items", "type"])
|
||||
let itemType = schema.getIn(["items", "type"])
|
||||
|
||||
let value = paramWithMeta ? paramWithMeta.get("value") : ""
|
||||
let extensions = getExtensions(param)
|
||||
let commonExt = showCommonExtensions ? getCommonExtensions(param) : null
|
||||
let extensions = showExtensions ? getExtensions(param) : null
|
||||
|
||||
let paramItems // undefined
|
||||
let paramItemsEnum // undefined
|
||||
let isDisplayParamItemsEnum = false
|
||||
let paramEnum // undefined
|
||||
let paramDefaultValue // undefined
|
||||
let paramExample // undefined
|
||||
let isDisplayParamEnum = false
|
||||
|
||||
if ( param !== undefined ) {
|
||||
paramItems = param.get("items")
|
||||
paramItems = schema.get("items")
|
||||
}
|
||||
if ( paramItems !== undefined ) {
|
||||
paramItemsEnum = param.get("items").get("enum")
|
||||
|
||||
if (paramItems !== undefined) {
|
||||
paramEnum = paramItems.get("enum")
|
||||
paramDefaultValue = paramItems.get("default")
|
||||
} else {
|
||||
paramEnum = schema.get("enum")
|
||||
}
|
||||
if ( paramItemsEnum !== undefined ) {
|
||||
if (paramItemsEnum.size > 0) {
|
||||
isDisplayParamItemsEnum = true
|
||||
}
|
||||
|
||||
if ( paramEnum !== undefined && paramEnum.size > 0) {
|
||||
isDisplayParamEnum = true
|
||||
}
|
||||
|
||||
// Default and Example Value for readonly doc
|
||||
let paramDefaultValue // undefined
|
||||
let paramExample // undefined
|
||||
if ( param !== undefined ) {
|
||||
paramDefaultValue = param.get("default")
|
||||
paramDefaultValue = schema.get("default")
|
||||
paramExample = param.get("example")
|
||||
}
|
||||
|
||||
if (isDisplayParamItemsEnum) { // if we have an array, default value is in "items"
|
||||
paramDefaultValue = paramItems.get("default")
|
||||
if (paramExample === undefined) {
|
||||
paramExample = param.get("x-example")
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -150,32 +155,32 @@ export default class ParameterRow extends Component {
|
||||
{ param.get("name") }
|
||||
{ !required ? null : <span style={{color: "red"}}> *</span> }
|
||||
</div>
|
||||
<div className="parameter__type">{ type } { itemType && `[${itemType}]` }</div>
|
||||
<div className="parameter__type">
|
||||
{ type }
|
||||
{ itemType && `[${itemType}]` }
|
||||
{ format && <span className="prop-format">(${format})</span>}
|
||||
</div>
|
||||
<div className="parameter__deprecated">
|
||||
{ isOAS3 && isOAS3() && param.get("deprecated") ? "deprecated": null }
|
||||
</div>
|
||||
<div className="parameter__in">({ param.get("in") })</div>
|
||||
{ !showCommonExtensions || !commonExt.size ? null : commonExt.map((v, key) => <ParameterExt key={`${key}-${v}`} xKey={key} xVal={v} /> )}
|
||||
{ !showExtensions || !extensions.size ? null : extensions.map((v, key) => <ParameterExt key={`${key}-${v}`} xKey={key} xVal={v} /> )}
|
||||
</td>
|
||||
|
||||
<td className="col parameters-col_description">
|
||||
<Markdown source={ param.get("description") }/>
|
||||
{ param.get("description") ? <Markdown source={ param.get("description") }/> : null }
|
||||
|
||||
{ (bodyParam || !isExecute) && isDisplayParamItemsEnum ?
|
||||
<Markdown source={
|
||||
"<i>Available values</i>: " + paramItemsEnum.map(function(item) {
|
||||
{ (bodyParam || !isExecute) && isDisplayParamEnum ?
|
||||
<Markdown className="parameter__enum" source={
|
||||
"<i>Available values</i> : " + paramEnum.map(function(item) {
|
||||
return item
|
||||
}).toArray().join(", ")}/>
|
||||
: null
|
||||
}
|
||||
|
||||
{ (bodyParam || !isExecute) && paramDefaultValue !== undefined ?
|
||||
<Markdown source={"<i>Default value</i>: " + paramDefaultValue}/>
|
||||
: null
|
||||
}
|
||||
|
||||
{ (bodyParam || !isExecute) && paramExample !== undefined ?
|
||||
<Markdown source={"<i>Example</i>: " + paramExample}/>
|
||||
<Markdown className="parameter__default" source={"<i>Default value</i> : " + paramDefaultValue}/>
|
||||
: null
|
||||
}
|
||||
|
||||
@@ -188,8 +193,8 @@ export default class ParameterRow extends Component {
|
||||
required={ required }
|
||||
description={param.get("description") ? `${param.get("name")} - ${param.get("description")}` : `${param.get("name")}`}
|
||||
onChange={ this.onChangeWrapper }
|
||||
errors={ param.get("errors") }
|
||||
schema={ isOAS3 && isOAS3() ? param.get("schema") : param }/>
|
||||
errors={ paramWithMeta.get("errors") }
|
||||
schema={ schema }/>
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +204,7 @@ export default class ParameterRow extends Component {
|
||||
getConfigs={ getConfigs }
|
||||
isExecute={ isExecute }
|
||||
specSelectors={ specSelectors }
|
||||
schema={ schema }
|
||||
schema={ param.get("schema") }
|
||||
example={ bodyParam }/>
|
||||
: null
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@ import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import Remarkable from "remarkable"
|
||||
import sanitize from "sanitize-html"
|
||||
import cx from "classnames"
|
||||
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
const isPlainText = (str) => /^[A-Z\s0-9!?\.]+$/gi.test(str)
|
||||
|
||||
function Markdown({ source }) {
|
||||
function Markdown({ source, className = "" }) {
|
||||
if(isPlainText(source)) {
|
||||
// If the source text is not Markdown,
|
||||
// let's save some time and just render it.
|
||||
@@ -28,12 +29,13 @@ function Markdown({ source }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="markdown" dangerouslySetInnerHTML={{ __html: sanitized }}></div>
|
||||
<div className={cx(className, "markdown")} dangerouslySetInnerHTML={{ __html: sanitized }}></div>
|
||||
)
|
||||
}
|
||||
|
||||
Markdown.propTypes = {
|
||||
source: PropTypes.string.isRequired
|
||||
source: PropTypes.string.isRequired,
|
||||
className: PropTypes.string
|
||||
}
|
||||
|
||||
export default Markdown
|
||||
|
||||
@@ -5,7 +5,10 @@ import lowerCase from "lodash/lowerCase"
|
||||
import { extractFileNameFromContentDispositionHeader } from "core/utils"
|
||||
import win from "core/window"
|
||||
|
||||
export default class ResponseBody extends React.Component {
|
||||
export default class ResponseBody extends React.PureComponent {
|
||||
state = {
|
||||
parsedContent: null
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
content: PropTypes.any.isRequired,
|
||||
@@ -15,8 +18,39 @@ export default class ResponseBody extends React.Component {
|
||||
url: PropTypes.string
|
||||
}
|
||||
|
||||
updateParsedContent = (prevContent) => {
|
||||
const { content } = this.props
|
||||
|
||||
if(prevContent === content) {
|
||||
return
|
||||
}
|
||||
|
||||
if(content && content instanceof Blob) {
|
||||
var reader = new FileReader()
|
||||
reader.onload = () => {
|
||||
this.setState({
|
||||
parsedContent: reader.result
|
||||
})
|
||||
}
|
||||
reader.readAsText(content)
|
||||
} else {
|
||||
this.setState({
|
||||
parsedContent: content.toString()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.updateParsedContent(null)
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
this.updateParsedContent(prevProps.content)
|
||||
}
|
||||
|
||||
render() {
|
||||
let { content, contentType, url, headers={}, getComponent } = this.props
|
||||
const { parsedContent } = this.state
|
||||
const HighlightCode = getComponent("highlightCode")
|
||||
let body, bodyEl
|
||||
url = url || ""
|
||||
@@ -66,7 +100,7 @@ export default class ResponseBody extends React.Component {
|
||||
body = "can't parse JSON. Raw result:\n\n" + content
|
||||
}
|
||||
|
||||
bodyEl = <HighlightCode value={ body } />
|
||||
bodyEl = <HighlightCode downloadable value={ body } />
|
||||
|
||||
// XML
|
||||
} else if (/xml/i.test(contentType)) {
|
||||
@@ -74,11 +108,11 @@ export default class ResponseBody extends React.Component {
|
||||
textNodesOnSameLine: true,
|
||||
indentor: " "
|
||||
})
|
||||
bodyEl = <HighlightCode value={ body } />
|
||||
bodyEl = <HighlightCode downloadable value={ body } />
|
||||
|
||||
// HTML or Plain Text
|
||||
} else if (lowerCase(contentType) === "text/html" || /text\/plain/.test(contentType)) {
|
||||
bodyEl = <HighlightCode value={ content } />
|
||||
bodyEl = <HighlightCode downloadable value={ content } />
|
||||
|
||||
// Image
|
||||
} else if (/^image\//i.test(contentType)) {
|
||||
@@ -92,10 +126,25 @@ export default class ResponseBody extends React.Component {
|
||||
} else if (/^audio\//i.test(contentType)) {
|
||||
bodyEl = <pre><audio controls><source src={ url } type={ contentType } /></audio></pre>
|
||||
} else if (typeof content === "string") {
|
||||
bodyEl = <HighlightCode value={ content } />
|
||||
bodyEl = <HighlightCode downloadable value={ content } />
|
||||
} else if ( content.size > 0 ) {
|
||||
// We don't know the contentType, but there was some content returned
|
||||
bodyEl = <div>Unknown response type</div>
|
||||
if(parsedContent) {
|
||||
// We were able to squeeze something out of content
|
||||
// in `updateParsedContent`, so let's display it
|
||||
bodyEl = <div>
|
||||
<p className="i">
|
||||
Unrecognized response type; displaying content as text.
|
||||
</p>
|
||||
<HighlightCode downloadable value={ parsedContent } />
|
||||
</div>
|
||||
|
||||
} else {
|
||||
// Give up
|
||||
bodyEl = <p className="i">
|
||||
Unrecognized response type; unable to display.
|
||||
</p>
|
||||
}
|
||||
} else {
|
||||
// We don't know the contentType and there was no content returned
|
||||
bodyEl = null
|
||||
|
||||
@@ -37,12 +37,12 @@ export default class Schemes extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let { schemes } = this.props
|
||||
let { schemes, currentScheme } = this.props
|
||||
|
||||
return (
|
||||
<label htmlFor="schemes">
|
||||
<span className="schemes-title">Schemes</span>
|
||||
<select onChange={ this.onChange }>
|
||||
<select onChange={ this.onChange } value={currentScheme}>
|
||||
{ schemes.valueSeq().map(
|
||||
( scheme ) => <option value={ scheme } key={ scheme }>{ scheme }</option>
|
||||
).toArray()}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import React from "react"
|
||||
const SvgAssets = () =>
|
||||
<div>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" style={{
|
||||
position: "absolute",
|
||||
width: 0,
|
||||
height: 0
|
||||
}}>
|
||||
<defs>
|
||||
<symbol viewBox="0 0 20 20" id="unlocked">
|
||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="locked">
|
||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="close">
|
||||
<path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow">
|
||||
<path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow-down">
|
||||
<path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
|
||||
</symbol>
|
||||
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="jump-to">
|
||||
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="expand">
|
||||
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
|
||||
</symbol>
|
||||
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
export default SvgAssets
|
||||
@@ -58,7 +58,7 @@ export default class OperationContainer extends PureComponent {
|
||||
const { op, layoutSelectors, getConfigs } = props
|
||||
const { docExpansion, deepLinking, displayOperationId, displayRequestDuration, supportedSubmitMethods } = getConfigs()
|
||||
const showSummary = layoutSelectors.showSummary()
|
||||
const operationId = op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || 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 isDeepLinkingEnabled = deepLinking && deepLinking !== "false"
|
||||
const allowTryItOut = supportedSubmitMethods.indexOf(props.method) >= 0 && (typeof props.allowTryItOut === "undefined" ?
|
||||
@@ -204,6 +204,7 @@ export default class OperationContainer extends PureComponent {
|
||||
security,
|
||||
isAuthorized,
|
||||
operationId,
|
||||
originalOperationId: resolvedSubtree.getIn(["operation", "__originalOperationId"]),
|
||||
showSummary,
|
||||
isShown,
|
||||
jumpToKey,
|
||||
|
||||
@@ -49,6 +49,7 @@ module.exports = function SwaggerUI(opts) {
|
||||
defaultModelExpandDepth: 1,
|
||||
defaultModelsExpandDepth: 1,
|
||||
showExtensions: false,
|
||||
showCommonExtensions: false,
|
||||
supportedSubmitMethods: [
|
||||
"get",
|
||||
"put",
|
||||
|
||||
@@ -81,8 +81,8 @@ export function getLineNumberForPath(yaml, path) {
|
||||
* YAML or JSON string
|
||||
* @param {array} path
|
||||
* an array of stings that constructs a
|
||||
* JSON Path similiar to JSON Pointers(RFC 6901). The difference is, each
|
||||
* component of path is an item of the array intead of beinf seperated with
|
||||
* JSON Path similar to JSON Pointers(RFC 6901). The difference is, each
|
||||
* component of path is an item of the array instead of being separated with
|
||||
* slash(/) in a string
|
||||
*/
|
||||
export function positionRangeForPath(yaml, path) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react"
|
||||
|
||||
// Nothing by default- component can be overriden by another plugin.
|
||||
// Nothing by default- component can be overridden by another plugin.
|
||||
|
||||
export default class JumpToPath extends React.Component {
|
||||
render() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import parseUrl from "url-parse"
|
||||
import win from "core/window"
|
||||
import { btoa, buildFormData } from "core/utils"
|
||||
|
||||
@@ -139,15 +140,25 @@ export const authorizeAccessCodeWithBasicAuthentication = ( { auth, redirectUrl
|
||||
return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get("tokenUrl"), auth, headers})
|
||||
}
|
||||
|
||||
export const authorizeRequest = ( data ) => ( { fn, getConfigs, authActions, errActions, authSelectors } ) => {
|
||||
export const authorizeRequest = ( data ) => ( { fn, getConfigs, authActions, errActions, oas3Selectors, specSelectors, authSelectors } ) => {
|
||||
let { body, query={}, headers={}, name, url, auth } = data
|
||||
let { additionalQueryStringParams } = authSelectors.getConfigs() || {}
|
||||
let fetchUrl = url
|
||||
|
||||
for (let key in additionalQueryStringParams) {
|
||||
url += "&" + key + "=" + encodeURIComponent(additionalQueryStringParams[key])
|
||||
let { additionalQueryStringParams } = authSelectors.getConfigs() || {}
|
||||
|
||||
let parsedUrl
|
||||
|
||||
if (specSelectors.isOAS3()) {
|
||||
parsedUrl = parseUrl(url, oas3Selectors.selectedServer(), true)
|
||||
} else {
|
||||
parsedUrl = parseUrl(url, specSelectors.url(), true)
|
||||
}
|
||||
|
||||
if(typeof additionalQueryStringParams === "object") {
|
||||
parsedUrl.query = Object.assign({}, parsedUrl.query, additionalQueryStringParams)
|
||||
}
|
||||
|
||||
const fetchUrl = parsedUrl.toString()
|
||||
|
||||
let _headers = Object.assign({
|
||||
"Accept":"application/json, text/plain, */*",
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import YAML from "js-yaml"
|
||||
|
||||
export const parseYamlConfig = (yaml, system) => {
|
||||
try {
|
||||
return YAML.safeLoad(yaml)
|
||||
} catch(e) {
|
||||
if (system) {
|
||||
system.errActions.newThrownErr( new Error(e) )
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +1,10 @@
|
||||
import YAML from "js-yaml"
|
||||
import yamlConfig from "root/swagger-config.yaml"
|
||||
import { parseYamlConfig } from "./helpers"
|
||||
import * as actions from "./actions"
|
||||
import * as specActions from "./spec-actions"
|
||||
import * as selectors from "./selectors"
|
||||
import reducers from "./reducers"
|
||||
|
||||
const parseYamlConfig = (yaml, system) => {
|
||||
try {
|
||||
return YAML.safeLoad(yaml)
|
||||
} catch(e) {
|
||||
if (system) {
|
||||
system.errActions.newThrownErr( new Error(e) )
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const specActions = {
|
||||
downloadConfig: (url) => ({fn}) => {
|
||||
let {fetch} = fn
|
||||
return fetch(url)
|
||||
},
|
||||
|
||||
getConfigByUrl: (configUrl, cb)=> ({ specActions }) => {
|
||||
if (configUrl) {
|
||||
return specActions.downloadConfig(configUrl).then(next, next)
|
||||
}
|
||||
|
||||
function next(res) {
|
||||
if (res instanceof Error || res.status >= 400) {
|
||||
specActions.updateLoadingStatus("failedConfig")
|
||||
specActions.updateLoadingStatus("failedConfig")
|
||||
specActions.updateUrl("")
|
||||
console.error(res.statusText + " " + configUrl)
|
||||
cb(null)
|
||||
} else {
|
||||
cb(parseYamlConfig(res.text))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const specSelectors = {
|
||||
getLocalConfig: () => {
|
||||
return parseYamlConfig(yamlConfig)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { parseYamlConfig } from "./helpers"
|
||||
|
||||
export const downloadConfig = (url) => ({fn: { fetch }, getConfigs}) => {
|
||||
const { requestInterceptor, responseInterceptor } = getConfigs()
|
||||
let req = { url }
|
||||
if(requestInterceptor) {
|
||||
req = requestInterceptor(req)
|
||||
}
|
||||
return fetch(req)
|
||||
.then(res => {
|
||||
if(res) {
|
||||
return responseInterceptor(res)
|
||||
}
|
||||
return res
|
||||
})
|
||||
}
|
||||
|
||||
export const getConfigByUrl = (configUrl, cb)=> ({ specActions }) => {
|
||||
if (configUrl) {
|
||||
return specActions.downloadConfig(configUrl).then(next, next)
|
||||
}
|
||||
|
||||
function next(res) {
|
||||
if (res instanceof Error || res.status >= 400) {
|
||||
specActions.updateLoadingStatus("failedConfig")
|
||||
specActions.updateLoadingStatus("failedConfig")
|
||||
specActions.updateUrl("")
|
||||
console.error(res.statusText + " " + configUrl)
|
||||
cb(null)
|
||||
} else {
|
||||
cb(parseYamlConfig(res.text))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ export const definitionsToAuthorize = onlyOAS3(createSelector(
|
||||
definition.get("flows").entrySeq().forEach(([flowKey, flowVal]) => {
|
||||
let translatedDef = fromJS({
|
||||
flow: flowKey,
|
||||
name: defName,
|
||||
authorizationUrl: flowVal.get("authorizationUrl"),
|
||||
tokenUrl: flowVal.get("tokenUrl"),
|
||||
scopes: flowVal.get("scopes"),
|
||||
@@ -40,7 +41,7 @@ export const definitionsToAuthorize = onlyOAS3(createSelector(
|
||||
})
|
||||
|
||||
list = list.push(new Map({
|
||||
[defName]: translatedDef.filter((v) => {
|
||||
[`${defName}__${flowKey}`]: translatedDef.filter((v) => {
|
||||
// filter out unset values, sometimes `authorizationUrl`
|
||||
// and `tokenUrl` come out as `undefined` in the data
|
||||
return v !== undefined
|
||||
|
||||
@@ -16,8 +16,14 @@ const Callbacks = (props) => {
|
||||
return <div key={callbackName}>
|
||||
<h2>{callbackName}</h2>
|
||||
{ callback.map((pathItem, pathItemName) => {
|
||||
if(pathItemName === "$$ref") {
|
||||
return null
|
||||
}
|
||||
return <div key={pathItemName}>
|
||||
{ pathItem.map((operation, method) => {
|
||||
if(method === "$$ref") {
|
||||
return null
|
||||
}
|
||||
let op = fromJS({
|
||||
operation
|
||||
})
|
||||
|
||||
@@ -33,7 +33,8 @@ export default class HttpAuth extends React.Component {
|
||||
let { onChange } = this.props
|
||||
let { value, name } = e.target
|
||||
|
||||
let newValue = this.state.value || {}
|
||||
let newValue = Object.assign({}, this.state.value)
|
||||
|
||||
if(name) {
|
||||
newValue[name] = value
|
||||
} else {
|
||||
@@ -53,7 +54,7 @@ export default class HttpAuth extends React.Component {
|
||||
const Markdown = getComponent( "Markdown" )
|
||||
const JumpToPath = getComponent("JumpToPath", true)
|
||||
|
||||
const scheme = schema.get("scheme")
|
||||
const scheme = (schema.get("scheme") || "").toLowerCase()
|
||||
let value = this.getValue()
|
||||
let errors = errSelectors.allErrors().filter( err => err.get("authId") === name)
|
||||
|
||||
@@ -125,7 +126,7 @@ export default class HttpAuth extends React.Component {
|
||||
)
|
||||
}
|
||||
return <div>
|
||||
<em><b>{name}</b> HTTP authentication: unsupported or missing scheme</em>
|
||||
<em><b>{name}</b> HTTP authentication: unsupported scheme {`'${scheme}'`}</em>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import ReactMarkdown from "react-markdown"
|
||||
import cx from "classnames"
|
||||
import { Parser, HtmlRenderer } from "commonmark"
|
||||
import { OAS3ComponentWrapFactory } from "../helpers"
|
||||
import { sanitizer } from "core/components/providers/markdown"
|
||||
|
||||
export const Markdown = ({ source }) => {
|
||||
export const Markdown = ({ source, className = "" }) => {
|
||||
if ( source ) {
|
||||
const parser = new Parser()
|
||||
const writer = new HtmlRenderer()
|
||||
@@ -19,14 +20,15 @@ export const Markdown = ({ source }) => {
|
||||
return (
|
||||
<ReactMarkdown
|
||||
source={sanitized}
|
||||
className={"renderedMarkdown"}
|
||||
className={cx(className, "renderedMarkdown")}
|
||||
/>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
Markdown.propTypes = {
|
||||
source: PropTypes.string
|
||||
source: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
}
|
||||
|
||||
export default OAS3ComponentWrapFactory(Markdown)
|
||||
export default OAS3ComponentWrapFactory(Markdown)
|
||||
|
||||
@@ -118,7 +118,11 @@ export default {
|
||||
let operationPath = ["paths", ...path]
|
||||
let metaPath = ["meta", "paths", ...path]
|
||||
|
||||
if(!state.getIn(["json", ...operationPath]) && !state.getIn(["resolved", ...operationPath])) {
|
||||
if(
|
||||
!state.getIn(["json", ...operationPath])
|
||||
&& !state.getIn(["resolved", ...operationPath])
|
||||
&& !state.getIn(["resolvedSubtrees", ...operationPath])
|
||||
) {
|
||||
// do nothing if the operation does not exist
|
||||
return state
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ import Property from "core/components/property"
|
||||
import TryItOutButton from "core/components/try-it-out-button"
|
||||
import VersionStamp from "core/components/version-stamp"
|
||||
import DeepLink from "core/components/deep-link"
|
||||
import SvgAssets from "core/components/svg-assets"
|
||||
|
||||
import Markdown from "core/components/providers/markdown"
|
||||
|
||||
@@ -130,7 +131,8 @@ export default function() {
|
||||
OperationContainer,
|
||||
DeepLink,
|
||||
InfoUrl,
|
||||
InfoBasePath
|
||||
InfoBasePath,
|
||||
SvgAssets
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -10,7 +10,7 @@ import { memoizedSampleFromSchema, memoizedCreateXMLExample } from "core/plugins
|
||||
import win from "./window"
|
||||
import cssEscape from "css.escape"
|
||||
|
||||
const DEFAULT_REPONSE_KEY = "default"
|
||||
const DEFAULT_RESPONSE_KEY = "default"
|
||||
|
||||
export const isImmutable = (maybe) => Im.Iterable.isIterable(maybe)
|
||||
|
||||
@@ -128,7 +128,7 @@ export function systemThunkMiddleware(getSystem) {
|
||||
|
||||
export function defaultStatusCode ( responses ) {
|
||||
let codes = responses.keySeq()
|
||||
return codes.contains(DEFAULT_REPONSE_KEY) ? DEFAULT_REPONSE_KEY : codes.filter( key => (key+"")[0] === "2").sort().first()
|
||||
return codes.contains(DEFAULT_RESPONSE_KEY) ? DEFAULT_RESPONSE_KEY : codes.filter( key => (key+"")[0] === "2").sort().first()
|
||||
}
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ export function highlight (el) {
|
||||
// running through characters and highlighting
|
||||
while (prev2 = prev1,
|
||||
// escaping if needed (with except for comments)
|
||||
// pervious character will not be therefore
|
||||
// previous character will not be therefore
|
||||
// recognized as a token finalize condition
|
||||
prev1 = tokenType < 7 && prev1 == "\\" ? 1 : chr
|
||||
) {
|
||||
@@ -712,6 +712,7 @@ export const createDeepLinkPath = (str) => typeof str == "string" || str instanc
|
||||
export const escapeDeepLinkPath = (str) => cssEscape( createDeepLinkPath(str) )
|
||||
|
||||
export const getExtensions = (defObj) => defObj.filter((v, k) => /^x-/.test(k))
|
||||
export const getCommonExtensions = (defObj) => defObj.filter((v, k) => /^pattern|maxLength|minLength|maximum|minimum/.test(k))
|
||||
|
||||
// Deeply strips a specific key from an object.
|
||||
//
|
||||
|
||||
@@ -6,7 +6,7 @@ Plugins allow you to add
|
||||
- `statePlugins`
|
||||
- `selectors` - query the state
|
||||
- `reducers` - modify the state
|
||||
- `actions` - fire and forget, that will eventually be handled by a reducer. You *can* rely on the result of async actions. But in general its not recommended
|
||||
- `actions` - fire and forget, that will eventually be handled by a reducer. You *can* rely on the result of async actions. But in general it's not recommended
|
||||
- `wrapActions` - replace an action with a wrapped action (useful for hooking into existing `actions`)
|
||||
- `components` - React components
|
||||
- `fn` - commons functions
|
||||
|
||||
@@ -626,6 +626,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
.highlight-code {
|
||||
position: relative;
|
||||
|
||||
> .microlight {
|
||||
overflow-y: auto;
|
||||
max-height: 400px;
|
||||
min-height: 6em;
|
||||
}
|
||||
}
|
||||
|
||||
.download-contents {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
cursor: pointer;
|
||||
background: #7d8293;
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
border-radius: 4px;
|
||||
font-family: 'Titillium Web', sans-serif;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
height: 30px;
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
.scheme-container
|
||||
{
|
||||
margin: 0 0 20px 0;
|
||||
|
||||
@@ -28,7 +28,7 @@ describe("oauth2", function () {
|
||||
expect(win.open.calls[0].arguments[0]).toMatch("https://testAuthorizationUrl?response_type=code&redirect_uri=&state=")
|
||||
})
|
||||
|
||||
it("should append query paramters to authorizeUrl with query parameters", function() {
|
||||
it("should append query parameters to authorizeUrl with query parameters", function() {
|
||||
win.open = createSpy()
|
||||
mockSchema.authorizationUrl = "https://testAuthorizationUrl?param=1"
|
||||
oauth2Authorize(authConfig)
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/* eslint-env mocha */
|
||||
import expect, { createSpy } from "expect"
|
||||
import { authorizeRequest } from "corePlugins/auth/actions"
|
||||
|
||||
describe("auth plugin - actions", () => {
|
||||
|
||||
describe("authorizeRequest", () => {
|
||||
|
||||
[
|
||||
[
|
||||
{
|
||||
oas3: true,
|
||||
server: "https://host/resource",
|
||||
scheme: "http",
|
||||
host: null,
|
||||
url: "http://specs/file",
|
||||
},
|
||||
"https://host/authorize"
|
||||
],
|
||||
[
|
||||
{
|
||||
oas3: false,
|
||||
server: null,
|
||||
scheme: "https",
|
||||
host: undefined,
|
||||
url: "https://specs/file",
|
||||
},
|
||||
"https://specs/authorize"
|
||||
],
|
||||
[
|
||||
{
|
||||
oas3: false,
|
||||
server: null,
|
||||
scheme: "https",
|
||||
host: "host",
|
||||
url: "http://specs/file",
|
||||
},
|
||||
"http://specs/authorize"
|
||||
],
|
||||
].forEach(([{oas3, server, scheme, host, url}, expectedFetchUrl]) => {
|
||||
it("should resolve authorization endpoint against the server URL", () => {
|
||||
|
||||
// Given
|
||||
const data = {
|
||||
url: "/authorize"
|
||||
}
|
||||
const system = {
|
||||
fn: {
|
||||
fetch: createSpy().andReturn(Promise.resolve())
|
||||
},
|
||||
getConfigs: () => ({}),
|
||||
authSelectors: {
|
||||
getConfigs: () => ({})
|
||||
},
|
||||
oas3Selectors: {
|
||||
selectedServer: () => server
|
||||
},
|
||||
specSelectors: {
|
||||
isOAS3: () => oas3,
|
||||
operationScheme: () => scheme,
|
||||
host: () => host,
|
||||
url: () => url
|
||||
}
|
||||
}
|
||||
|
||||
// When
|
||||
authorizeRequest(data)(system)
|
||||
|
||||
// Then
|
||||
expect(system.fn.fetch.calls.length).toEqual(1)
|
||||
expect(system.fn.fetch.calls[0].arguments[0]).toInclude({url: expectedFetchUrl})
|
||||
})
|
||||
})
|
||||
|
||||
it("should add additionalQueryStringParams to Swagger 2.0 authorization and token URLs", () => {
|
||||
|
||||
// Given
|
||||
const data = {
|
||||
url: "/authorize?q=1"
|
||||
}
|
||||
const system = {
|
||||
fn: {
|
||||
fetch: createSpy().andReturn(Promise.resolve())
|
||||
},
|
||||
getConfigs: () => ({}),
|
||||
authSelectors: {
|
||||
getConfigs: () => ({
|
||||
additionalQueryStringParams: {
|
||||
myCustomParam: "abc123"
|
||||
}
|
||||
})
|
||||
},
|
||||
specSelectors: {
|
||||
isOAS3: () => false,
|
||||
operationScheme: () => "https",
|
||||
host: () => "http://google.com",
|
||||
url: () => "http://google.com/swagger.json"
|
||||
}
|
||||
}
|
||||
|
||||
// When
|
||||
authorizeRequest(data)(system)
|
||||
|
||||
// Then
|
||||
expect(system.fn.fetch.calls.length).toEqual(1)
|
||||
|
||||
expect(system.fn.fetch.calls[0].arguments[0].url)
|
||||
.toEqual("http://google.com/authorize?q=1&myCustomParam=abc123")
|
||||
})
|
||||
|
||||
it("should add additionalQueryStringParams to OpenAPI 3.0 authorization and token URLs", () => {
|
||||
|
||||
// Given
|
||||
const data = {
|
||||
url: "/authorize?q=1"
|
||||
}
|
||||
const system = {
|
||||
fn: {
|
||||
fetch: createSpy().andReturn(Promise.resolve())
|
||||
},
|
||||
getConfigs: () => ({}),
|
||||
authSelectors: {
|
||||
getConfigs: () => ({
|
||||
additionalQueryStringParams: {
|
||||
myCustomParam: "abc123"
|
||||
}
|
||||
})
|
||||
},
|
||||
oas3Selectors: {
|
||||
selectedServer: () => "http://google.com"
|
||||
},
|
||||
specSelectors: {
|
||||
isOAS3: () => true,
|
||||
}
|
||||
}
|
||||
|
||||
// When
|
||||
authorizeRequest(data)(system)
|
||||
|
||||
// Then
|
||||
expect(system.fn.fetch.calls.length).toEqual(1)
|
||||
|
||||
expect(system.fn.fetch.calls[0].arguments[0].url)
|
||||
.toEqual("http://google.com/authorize?q=1&myCustomParam=abc123")
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,84 @@
|
||||
/* eslint-env mocha */
|
||||
import expect, { createSpy } from "expect"
|
||||
import { downloadConfig } from "corePlugins/configs/spec-actions"
|
||||
|
||||
describe("configs plugin - actions", () => {
|
||||
|
||||
describe("downloadConfig", () => {
|
||||
it("should call the system fetch helper with a provided url", () => {
|
||||
const fetchSpy = createSpy(async () => {}).andCallThrough()
|
||||
const system = {
|
||||
fn: {
|
||||
fetch: fetchSpy
|
||||
},
|
||||
getConfigs() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
const url = "http://swagger.io/one"
|
||||
|
||||
downloadConfig(url)(system)
|
||||
|
||||
expect(fetchSpy).toHaveBeenCalledWith({
|
||||
url: url
|
||||
})
|
||||
})
|
||||
it("should allow the globally configured requestInterceptor to modify the request", () => {
|
||||
const fetchSpy = createSpy(async () => {}).andCallThrough()
|
||||
const requestInterceptorSpy = createSpy((req) => {
|
||||
req.url = "http://swagger.io/two"
|
||||
return req
|
||||
}).andCallThrough()
|
||||
const system = {
|
||||
fn: {
|
||||
fetch: fetchSpy
|
||||
},
|
||||
getConfigs() {
|
||||
return {
|
||||
requestInterceptor: requestInterceptorSpy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const url = "http://swagger.io/one"
|
||||
|
||||
downloadConfig(url)(system)
|
||||
|
||||
expect(fetchSpy).toHaveBeenCalledWith({
|
||||
url: "http://swagger.io/two"
|
||||
})
|
||||
})
|
||||
it("should allow the globally configured responseInterceptor to modify the response", async () => {
|
||||
const fetchSpy = createSpy(async (req) => {
|
||||
return {
|
||||
url: req.url,
|
||||
ok: true
|
||||
}
|
||||
}).andCallThrough()
|
||||
const responseInterceptorSpy = createSpy((res) => {
|
||||
res.url = "http://swagger.io/two"
|
||||
return res
|
||||
}).andCallThrough()
|
||||
const system = {
|
||||
fn: {
|
||||
fetch: fetchSpy
|
||||
},
|
||||
getConfigs() {
|
||||
return {
|
||||
responseInterceptor: responseInterceptorSpy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const url = "http://swagger.io/one"
|
||||
|
||||
const res = await downloadConfig(url)(system)
|
||||
|
||||
expect(res).toEqual({
|
||||
url: "http://swagger.io/two",
|
||||
ok: true
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
+21
-1
@@ -1,6 +1,6 @@
|
||||
/* eslint-env mocha */
|
||||
import expect from "expect"
|
||||
import { fromJS, OrderedMap } from "immutable"
|
||||
import { Map, fromJS, OrderedMap } from "immutable"
|
||||
import {
|
||||
mapToList,
|
||||
parseSearch,
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
getAcceptControllingResponse,
|
||||
createDeepLinkPath,
|
||||
escapeDeepLinkPath,
|
||||
getExtensions,
|
||||
getCommonExtensions,
|
||||
sanitizeUrl,
|
||||
extractFileNameFromContentDispositionHeader,
|
||||
deeplyStripKey
|
||||
@@ -943,6 +945,24 @@ describe("utils", function() {
|
||||
})
|
||||
})
|
||||
|
||||
describe("getExtensions", function() {
|
||||
const objTest = Map([[ "x-test", "a"], ["minimum", "b"]])
|
||||
it("does not error on empty array", function() {
|
||||
const result1 = getExtensions([])
|
||||
expect(result1).toEqual([])
|
||||
const result2 = getCommonExtensions([])
|
||||
expect(result2).toEqual([])
|
||||
})
|
||||
it("gets only the x- keys", function() {
|
||||
const result = getExtensions(objTest)
|
||||
expect(result).toEqual(Map([[ "x-test", "a"]]))
|
||||
})
|
||||
it("gets the common keys", function() {
|
||||
const result = getCommonExtensions(objTest, true)
|
||||
expect(result).toEqual(Map([[ "minimum", "b"]]))
|
||||
})
|
||||
})
|
||||
|
||||
describe("deeplyStripKey", function() {
|
||||
it("should filter out a specified key", function() {
|
||||
const input = {
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
describe("bug #4196: HTTP basic auth credential retention", function () {
|
||||
let mainPage
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(80)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/bugs/4196.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
done()
|
||||
})
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
it("should display the most recent auth data across modal close/opens", function (client) {
|
||||
client.waitForElementVisible(".opblock-tag-section", 10000)
|
||||
.click("button.btn.authorize") // Open modal
|
||||
.waitForElementVisible("section>input", 5000)
|
||||
.setValue("section>input", "aaa") // Set user
|
||||
.waitForElementVisible(`section>input[type="password"]`, 5000)
|
||||
.setValue(`section>input[type="password"]`, "aaa") // Set password
|
||||
.click(".auth-btn-wrapper button:nth-child(1)") // Click Authorize
|
||||
.assert.containsText("div.wrapper:nth-child(4)>code", "aaa")
|
||||
.click(".auth-btn-wrapper button:nth-child(2)") // Close modal
|
||||
.pause(50)
|
||||
.click("button.btn.authorize") // Open modal
|
||||
.pause(50)
|
||||
.click(".auth-btn-wrapper button:nth-child(1)") // Logout
|
||||
.waitForElementVisible("section>input", 5000)
|
||||
.setValue("section>input", "bbb") // Set user
|
||||
.waitForElementVisible(`section>input[type="password"]`, 5000)
|
||||
.setValue(`section>input[type="password"]`, "bbb") // Set password
|
||||
.click(".auth-btn-wrapper button:nth-child(1)") // Click Authorize
|
||||
.pause(5000)
|
||||
.assert.containsText("div.wrapper:nth-child(4)>code", "bbb")
|
||||
|
||||
client.end()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
describe("bug #4374: OAS3 parameters should be visibly validated in Try-It-Out", function () {
|
||||
let mainPage
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 10000)
|
||||
.pause(1000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/bugs/4374.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
done()
|
||||
})
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
it("indicates an error when a required parameter is not selected", function (client) {
|
||||
client.waitForElementVisible(".opblock-tag-section", 10000)
|
||||
.assert.containsText(".opblock-summary-path span", "/pet/findByStatus")
|
||||
.click(".opblock")
|
||||
.waitForElementVisible(".opblock.is-open", 5000)
|
||||
.click(".try-out__btn")
|
||||
.click(".btn.execute")
|
||||
.pause(100)
|
||||
.assert.cssClassPresent(".parameters-col_description select", "invalid")
|
||||
|
||||
client.end()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,29 @@
|
||||
describe("bug #4409: operationId normalization and layout tracking", function () {
|
||||
let mainPage
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/bugs/4409.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
done()
|
||||
})
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
it("expands an operation that has a normalizable operationId", function (client) {
|
||||
client.waitForElementVisible(".opblock-tag-section", 10000)
|
||||
.assert.containsText(".opblock-summary-path span", "/myApi")
|
||||
.click(".opblock")
|
||||
.waitForElementVisible(".opblock-body", 5000)
|
||||
.assert.cssClassPresent(".opblock", "is-open")
|
||||
|
||||
client.end()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
describe("bug #4445: callback-via-$ref rendering", function () {
|
||||
let mainPage
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/bugs/4445.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
done()
|
||||
})
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
it("expands an operation that has a visible callback", function (client) {
|
||||
client.waitForElementVisible(".opblock-tag-section", 10000)
|
||||
.click(".opblock")
|
||||
.waitForElementVisible(".opblock-body", 5000)
|
||||
.click(".opblock-section-header > .tab-header > div.tab-item:nth-of-type(2)")
|
||||
.waitForElementVisible(".callbacks-container .opblock", 5000)
|
||||
.click(".callbacks-container .opblock")
|
||||
.waitForElementVisible(".callbacks-container .opblock-body", 5000)
|
||||
.assert.containsText(".callbacks-container .opblock-description-wrapper:nth-of-type(2) p", "subscription payload")
|
||||
|
||||
client.end()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,31 @@
|
||||
describe("bug #4485: operation metadata storage when referenced via path item $ref", function () {
|
||||
let mainPage
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(2000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/bugs/4485/main.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
done()
|
||||
})
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
it("sets a consumes value for a body parameter correctly", function (client) {
|
||||
client.waitForElementVisible(".opblock-tag-section", 10000)
|
||||
.click(".opblock")
|
||||
.waitForElementVisible(".opblock-body", 5000)
|
||||
.click("button.btn.try-out__btn")
|
||||
.click("select.content-type [value=\"application/xml\"]")
|
||||
.pause(500)
|
||||
.assert.value("select.content-type", "application/xml")
|
||||
|
||||
client.end()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,58 @@
|
||||
describe("parameter enum rendering", function () {
|
||||
describe("swagger 2.0", () => {
|
||||
beforeEach(function (client, done) {
|
||||
client
|
||||
.url("localhost:3230")
|
||||
.waitForElementVisible(".download-url-input", 10000)
|
||||
.pause(1000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/features/parameter-enum-rendering.swagger.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
done()
|
||||
})
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
it("reveals a string parameter's enums and defaults when viewing that parameter", function (client) {
|
||||
client.waitForElementVisible(".opblock-tag-section", 10000)
|
||||
.assert.containsText(".opblock-summary-path span", "/report")
|
||||
.click(".opblock")
|
||||
.waitForElementVisible(".opblock.is-open", 5000)
|
||||
.pause(500)
|
||||
.assert.containsText("div.parameter__enum", "today, yesterday, lastweek")
|
||||
.assert.containsText("div.parameter__default", "today")
|
||||
|
||||
client.end()
|
||||
})
|
||||
})
|
||||
describe("openapi 3.0", () => {
|
||||
beforeEach(function (client, done) {
|
||||
client
|
||||
.url("localhost:3230")
|
||||
.waitForElementVisible(".download-url-input", 10000)
|
||||
.pause(1000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/features/parameter-enum-rendering.openapi.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
done()
|
||||
})
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
it("reveals a string parameter's enums and defaults when viewing that parameter", function (client) {
|
||||
client.waitForElementVisible(".opblock-tag-section", 10000)
|
||||
.assert.containsText(".opblock-summary-path span", "/report")
|
||||
.click(".opblock")
|
||||
.waitForElementVisible(".opblock.is-open", 5000)
|
||||
.pause(500)
|
||||
.assert.containsText("div.parameter__enum", "today, yesterday, lastweek")
|
||||
.assert.containsText("div.parameter__default", "today")
|
||||
|
||||
client.end()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -4,12 +4,12 @@ describe("render informationContainer", function () {
|
||||
beforeEach(function (client, done) {
|
||||
|
||||
mainPage = client
|
||||
.url("localhost:3200")
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/petstore.json")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
@@ -29,8 +29,8 @@ describe("render informationContainer", function () {
|
||||
.assert.containsText("@title", "Swagger Petstore")
|
||||
.assert.containsText("@version", "1.0.0")
|
||||
.assert.containsText("@baseUrl", "[ Base URL: localhost:3204/ ]")
|
||||
.assert.attributeEquals("@mainUrl", "href", "http://localhost:3200/test-specs/petstore.json")
|
||||
.assert.containsText("@mainUrlContent", "http://localhost:3200/test-specs/petstore.json")
|
||||
.assert.attributeEquals("@mainUrl", "href", "http://localhost:3230/test-specs/petstore.json")
|
||||
.assert.containsText("@mainUrlContent", "http://localhost:3230/test-specs/petstore.json")
|
||||
.assert.containsText("@description", "This is a sample server Petstore server. You can find out more about Swagger at http://swagger.io or on irc.freenode.net, #swagger. For this sample, you can use the api key special-key to test the authorization filters.")
|
||||
.assert.attributeEquals("@swaggerUrl", "href", "http://swagger.io/")
|
||||
.assert.attributeEquals("@swaggerircUrl", "href", "http://swagger.io/irc/")
|
||||
|
||||
@@ -3,12 +3,12 @@ describe("Render Model Wrapper", function () {
|
||||
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3200")
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/petstore.json")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ describe("render pet api container", function () {
|
||||
let apiWrapper
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3200")
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3200/test-specs/callbacks.openapi.yaml")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/callbacks.openapi.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ describe("render pet api container", function () {
|
||||
let apiWrapper
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3200")
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.openapi.yaml")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/petstore.openapi.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ describe("onComplete option", function () {
|
||||
let mainPage
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3200")
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".opblock-tag-section", 5000)
|
||||
|
||||
@@ -3,13 +3,13 @@ describe("render pet api container", function () {
|
||||
let apiWrapper
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3200")
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/petstore.json")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
@@ -71,6 +71,16 @@ describe("render pet api container", function () {
|
||||
client.end()
|
||||
})
|
||||
|
||||
it("Testing post /pet api model values", function (client) {
|
||||
apiWrapper.waitForElementVisible("@petOperationPostContainer", 5000)
|
||||
.click("@petOperationPostCollpase")
|
||||
.waitForElementVisible("@petOperationPostCollapseContainer", 5000)
|
||||
.click("a.tablinks[data-name=model]")
|
||||
.assert.containsText("span.model-title > .model-title__text", `Pet`)
|
||||
|
||||
client.end()
|
||||
})
|
||||
|
||||
it("render put /pet api container", function (client) {
|
||||
apiWrapper.waitForElementVisible("@petOperationPutContainer", 5000)
|
||||
.assert.containsText("@petOperationPutTitle", "/pet")
|
||||
@@ -81,10 +91,10 @@ describe("render pet api container", function () {
|
||||
.waitForElementVisible("@petOperationPutExecuteBtn", 1000)
|
||||
.click("@petOperationPutTryBtn")
|
||||
.assert.cssClassNotPresent("@petOperationPutTryBtn", "cancel")
|
||||
|
||||
|
||||
client.end()
|
||||
})
|
||||
|
||||
|
||||
it("Testing put /pet api Mock data", function (client) {
|
||||
apiWrapper.waitForElementVisible("@petOperationPutContainer", 5000)
|
||||
.click("@petOperationPutCollpase")
|
||||
@@ -115,7 +125,7 @@ describe("render pet api container", function () {
|
||||
.waitForElementVisible("@petOperationGetByTagExecuteBtn", 1000)
|
||||
.click("@petOperationGetByTagTryBtn")
|
||||
.assert.cssClassNotPresent("@petOperationGetByTagTryBtn", "cancel")
|
||||
|
||||
|
||||
client.end()
|
||||
})
|
||||
|
||||
@@ -138,7 +148,7 @@ describe("render pet api container", function () {
|
||||
|
||||
client.end()
|
||||
})
|
||||
|
||||
|
||||
it("render get by ID /pet/{petId} api container", function (client) {
|
||||
apiWrapper.waitForElementVisible("@petOperationGetByIdContainer", 5000)
|
||||
.assert.containsText("@petOperationGetByIdTitle", "/pet/{petId}")
|
||||
@@ -148,7 +158,7 @@ describe("render pet api container", function () {
|
||||
.waitForElementVisible("@petOperationGetByTagExecuteBtn", 1000)
|
||||
.click("@petOperationGetByTagTryBtn")
|
||||
.assert.cssClassNotPresent("@petOperationGetByTagTryBtn", "cancel")
|
||||
|
||||
|
||||
client.end()
|
||||
})
|
||||
|
||||
@@ -167,7 +177,7 @@ describe("render pet api container", function () {
|
||||
.assert.attributeEquals("@petOperationGetByIdParameter", "title", "Value must be an integer")
|
||||
.click("@petOperationGetByTagTryBtn")
|
||||
.assert.cssClassNotPresent("@petOperationGetByTagTryBtn", "cancel")
|
||||
|
||||
|
||||
client.end()
|
||||
})
|
||||
|
||||
@@ -180,10 +190,10 @@ describe("render pet api container", function () {
|
||||
.waitForElementVisible("@petOperationDeleteExecuteBtn", 1000)
|
||||
.click("@petOperationDeleteTryBtn")
|
||||
.assert.cssClassNotPresent("@petOperationDeleteTryBtn", "cancel")
|
||||
|
||||
|
||||
client.end()
|
||||
})
|
||||
|
||||
|
||||
it("Testing delete /pet api Mock data", function (client) {
|
||||
apiWrapper.waitForElementVisible("@petOperationDeleteContainer", 3000)
|
||||
.click("@petOperationDeleteCollpase")
|
||||
@@ -203,4 +213,4 @@ describe("render pet api container", function () {
|
||||
|
||||
client.end()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,13 +3,13 @@ describe("render store api container", function(){
|
||||
let apiWrapper
|
||||
beforeEach( function(client, done){
|
||||
mainPage = client
|
||||
.url("localhost:3200")
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(3000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/petstore.json")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ describe("render user api container", function(){
|
||||
let apiWrapper
|
||||
beforeEach( function(client, done){
|
||||
mainPage = client
|
||||
.url("localhost:3200")
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/petstore.json")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@ describe("Remote $ref rendering", function () {
|
||||
|
||||
mainPage = client
|
||||
// expand the models so we don't have to manually do it
|
||||
.url("localhost:3200?defaultModelsExpandDepth=5")
|
||||
.url("localhost:3230?defaultModelsExpandDepth=5")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(2000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3200/test-specs/refs/api1.yaml")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/refs/api1.yaml")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
@@ -19,7 +19,7 @@ describe("Remote $ref rendering", function () {
|
||||
})
|
||||
|
||||
it("renders a remote $ref correctly", function (client) {
|
||||
mainPage.expect.element("#model-TestResponse > span > div > span > span > span.inner-object > table > tbody > tr:nth-child(2) > td:nth-child(2) > span > span > div > div > p").text.to.equal("this is a api2prop")
|
||||
mainPage.expect.element("#model-TestResponse > span > div > span > span > span.inner-object > table > tbody > tr:nth-child(2) > td:nth-child(2) > span > span > div > div > p").text.to.equal("this is an api2prop")
|
||||
|
||||
client.end()
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ describe("Render scheme", function () {
|
||||
beforeEach(function (client, done) {
|
||||
|
||||
mainPage = client
|
||||
.url("localhost:3200")
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
schemeContainer = mainPage.section.schemeContainer
|
||||
@@ -12,7 +12,7 @@ describe("Render scheme", function () {
|
||||
client.waitForElementVisible(".download-url-input", 5000)
|
||||
.pause(5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/petstore.json")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ describe("initial render", function () {
|
||||
|
||||
beforeEach(function (client, done) {
|
||||
mainPage = client
|
||||
.url("localhost:3200")
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
topbar = mainPage.section.topbar
|
||||
@@ -26,7 +26,7 @@ describe("initial render", function () {
|
||||
client.waitForElementVisible(".download-url-input", 10000)
|
||||
.pause(5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
|
||||
.setValue(".download-url-input", "http://localhost:3230/test-specs/petstore.json")
|
||||
.click("button.download-url-button")
|
||||
.pause(1000)
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: Demo API
|
||||
description: First test
|
||||
termsOfService: 'http://demo.io/terms-of-service/'
|
||||
contact:
|
||||
name: Demo Support
|
||||
email: support@demo.io
|
||||
version: 1.0.0
|
||||
servers:
|
||||
- url: '{server}/v1'
|
||||
variables:
|
||||
server:
|
||||
default: https://api.demo.io
|
||||
description: the API endpoint
|
||||
|
||||
paths:
|
||||
/session:
|
||||
put:
|
||||
summary: Returns a new authentication token
|
||||
tags:
|
||||
- session
|
||||
security:
|
||||
- basicAuth: []
|
||||
responses:
|
||||
'201':
|
||||
description: A session object
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- type: object
|
||||
properties:
|
||||
user_id:
|
||||
type: string
|
||||
format: uuid
|
||||
readOnly: true
|
||||
example: 110e8400-e29b-11d4-a716-446655440000
|
||||
- $ref: '#/components/schemas/Session'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
basicAuth:
|
||||
type: http
|
||||
scheme: basic
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
schemas:
|
||||
Session:
|
||||
required:
|
||||
- token
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
readOnly: true
|
||||
example: >-
|
||||
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.EkN-DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8jO19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuhtF39yxJPAjUESwxk2J5k_4zM3O-vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE
|
||||
|
||||
Error:
|
||||
required:
|
||||
- message
|
||||
properties:
|
||||
message:
|
||||
description: a human readable message explaining the error
|
||||
type: string
|
||||
reason:
|
||||
description: a functionnal key about the error
|
||||
type: string
|
||||
responses:
|
||||
Unauthorized:
|
||||
description: Not authenticated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
Default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
@@ -0,0 +1,228 @@
|
||||
---
|
||||
openapi: 3.0.0
|
||||
servers:
|
||||
- url: http://localhost:3204/
|
||||
info:
|
||||
description: 'This is a sample server Petstore server. You can find out more about
|
||||
Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For
|
||||
this sample, you can use the api key `special-key` to test the authorization filters.'
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
termsOfService: http://swagger.io/terms/
|
||||
contact:
|
||||
email: apiteam@swagger.io
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
tags:
|
||||
- name: pet
|
||||
description: Everything about your Pets
|
||||
externalDocs:
|
||||
description: Find out more
|
||||
url: http://swagger.io
|
||||
- name: store
|
||||
description: Access to Petstore orders
|
||||
- name: user
|
||||
description: Operations about user
|
||||
externalDocs:
|
||||
description: Find out more about our store
|
||||
url: http://swagger.io
|
||||
paths:
|
||||
"/pet/findByStatus":
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by status
|
||||
description: Multiple status values can be provided with comma separated strings
|
||||
operationId: findPetsByStatus
|
||||
parameters:
|
||||
- name: status
|
||||
in: query
|
||||
description: Status values that need to be considered for filter
|
||||
required: true
|
||||
explode: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- available
|
||||
- pending
|
||||
- sold
|
||||
default: available
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
"$ref": "#/components/schemas/Pet"
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
"$ref": "#/components/schemas/Pet"
|
||||
'400':
|
||||
description: Invalid status value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write:pets
|
||||
- read:pets
|
||||
externalDocs:
|
||||
description: Find out more about Swagger
|
||||
url: http://swagger.io
|
||||
components:
|
||||
schemas:
|
||||
Order:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
petId:
|
||||
type: integer
|
||||
format: int64
|
||||
quantity:
|
||||
type: integer
|
||||
format: int32
|
||||
shipDate:
|
||||
type: string
|
||||
format: date-time
|
||||
status:
|
||||
type: string
|
||||
description: Order Status
|
||||
enum:
|
||||
- placed
|
||||
- approved
|
||||
- delivered
|
||||
complete:
|
||||
type: boolean
|
||||
default: false
|
||||
xml:
|
||||
name: Order
|
||||
Category:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
xml:
|
||||
name: Category
|
||||
User:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
username:
|
||||
type: string
|
||||
firstName:
|
||||
type: string
|
||||
lastName:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
phone:
|
||||
type: string
|
||||
userStatus:
|
||||
type: integer
|
||||
format: int32
|
||||
description: User Status
|
||||
xml:
|
||||
name: User
|
||||
Tag:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
xml:
|
||||
name: Tag
|
||||
Pet:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- photoUrls
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
category:
|
||||
"$ref": "#/components/schemas/Category"
|
||||
name:
|
||||
type: string
|
||||
example: doggie
|
||||
photoUrls:
|
||||
type: array
|
||||
xml:
|
||||
name: photoUrl
|
||||
wrapped: true
|
||||
items:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
xml:
|
||||
name: tag
|
||||
wrapped: true
|
||||
items:
|
||||
"$ref": "#/components/schemas/Tag"
|
||||
status:
|
||||
type: string
|
||||
description: pet status in the store
|
||||
enum:
|
||||
- available
|
||||
- pending
|
||||
- sold
|
||||
xml:
|
||||
name: Pet
|
||||
ApiResponse:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
type:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
requestBodies:
|
||||
Pet:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
"$ref": "#/components/schemas/Pet"
|
||||
application/xml:
|
||||
schema:
|
||||
"$ref": "#/components/schemas/Pet"
|
||||
description: Pet object that needs to be added to the store
|
||||
required: true
|
||||
UserArray:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
"$ref": "#/components/schemas/User"
|
||||
description: List of user object
|
||||
required: true
|
||||
securitySchemes:
|
||||
petstore_auth:
|
||||
type: oauth2
|
||||
flows:
|
||||
implicit:
|
||||
authorizationUrl: http://petstore.swagger.io/oauth/dialog
|
||||
scopes:
|
||||
write:pets: modify pets in your account
|
||||
read:pets: read your pets
|
||||
api_key:
|
||||
type: apiKey
|
||||
name: api_key
|
||||
in: header
|
||||
@@ -0,0 +1,24 @@
|
||||
openapi: 3.0.0
|
||||
servers:
|
||||
- url: 'https://__host__/'
|
||||
info:
|
||||
description: Test API
|
||||
version: '1.0'
|
||||
title: Test API
|
||||
contact:
|
||||
name: Sample Person
|
||||
email: Sample.Person@adp.com
|
||||
tags:
|
||||
- name: Test API with Schema
|
||||
description: Test API with Schema
|
||||
paths:
|
||||
/myApi:
|
||||
get:
|
||||
operationId: some guid
|
||||
responses:
|
||||
'200':
|
||||
description: Returns documents
|
||||
description: Returns documents
|
||||
tags:
|
||||
- Test API with Schema
|
||||
summary: Test API with Schema
|
||||
@@ -0,0 +1,64 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: Callback Example
|
||||
version: 1.0.0
|
||||
paths:
|
||||
/streams:
|
||||
post:
|
||||
description: subscribes a client to receive out-of-band data
|
||||
parameters:
|
||||
- name: callbackUrl
|
||||
in: query
|
||||
required: true
|
||||
description: |
|
||||
the location where data will be sent. Must be network accessible
|
||||
by the source server
|
||||
schema:
|
||||
type: string
|
||||
format: uri
|
||||
example: https://tonys-server.com
|
||||
responses:
|
||||
'201':
|
||||
description: subscription successfully created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
description: subscription information
|
||||
required:
|
||||
- subscriptionId
|
||||
properties:
|
||||
subscriptionId:
|
||||
description: this unique identifier allows management of the subscription
|
||||
type: string
|
||||
example: 2531329f-fb09-4ef7-887e-84e648214436
|
||||
callbacks:
|
||||
# the name `onData` is a convenience locator
|
||||
onData:
|
||||
$ref: '#/components/callbacks/onData'
|
||||
components:
|
||||
callbacks:
|
||||
onData:
|
||||
# when data is sent, it will be sent to the `callbackUrl` provided
|
||||
# when making the subscription PLUS the suffix `/data`
|
||||
'{$request.query.callbackUrl}/data':
|
||||
post:
|
||||
requestBody:
|
||||
description: subscription payload
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
userData:
|
||||
type: string
|
||||
responses:
|
||||
'202':
|
||||
description: |
|
||||
Your server implementation should return this HTTP status code
|
||||
if the data was received successfully
|
||||
'204':
|
||||
description: |
|
||||
Your server should return this HTTP status code if no longer interested
|
||||
in further updates
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
post:
|
||||
description: Book
|
||||
operationId: buy
|
||||
summary: Buy a book
|
||||
tags:
|
||||
- Book
|
||||
consumes:
|
||||
- application/json
|
||||
- application/xml
|
||||
parameters:
|
||||
- name: requestBody
|
||||
in: body
|
||||
description: Buy a Book
|
||||
required: true
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
swagger: '2.0'
|
||||
paths:
|
||||
"/v1/book":
|
||||
"$ref": "./book.yaml"
|
||||
@@ -0,0 +1,21 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: test
|
||||
version: 0.0.0
|
||||
paths:
|
||||
/report:
|
||||
get:
|
||||
parameters:
|
||||
- in: query
|
||||
name: rel_date
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
default: today
|
||||
enum:
|
||||
- today
|
||||
- yesterday
|
||||
- lastweek
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
@@ -0,0 +1,20 @@
|
||||
swagger: '2.0'
|
||||
info:
|
||||
title: test
|
||||
version: 0.0.0
|
||||
paths:
|
||||
/report:
|
||||
get:
|
||||
parameters:
|
||||
- in: query
|
||||
name: rel_date
|
||||
required: true
|
||||
type: string
|
||||
default: today
|
||||
enum:
|
||||
- today
|
||||
- yesterday
|
||||
- lastweek
|
||||
responses:
|
||||
200:
|
||||
description: OK
|
||||
@@ -21,7 +21,7 @@ components:
|
||||
schemas:
|
||||
Api2Prop:
|
||||
type: string
|
||||
description: this is a api2prop
|
||||
description: this is an api2prop
|
||||
example: 'api1prop-value'
|
||||
|
||||
TestResponse2:
|
||||
|
||||
Reference in New Issue
Block a user