feat(rendering): gate rendering based on valid version identifiers (#4614)
* create VersionPragmaFilter component * use VersionPragmaFilter in BaseLayout * tighten version idenitifier constraints * handle case where user specifies a valid `swagger` and `openapi` field * add traceable class names for each message * add tests * linter fixes! * UNRELATED CHANGE: remove travis short-circuit * add bypass switch to VersionPragmaFilter
This commit is contained in:
@@ -11,15 +11,6 @@ branches:
|
||||
- master
|
||||
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||
install: "npm i && npm update"
|
||||
before_install:
|
||||
- | # quickly pass if only documentation is being updated
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
||||
TRAVIS_COMMIT_RANGE="FETCH_HEAD...$TRAVIS_BRANCH"
|
||||
git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.md$)|(^(docs|examples))/' || {
|
||||
echo "Only docs were updated, stopping build process."
|
||||
exit
|
||||
}
|
||||
fi
|
||||
before_deploy:
|
||||
- npm run build
|
||||
env:
|
||||
|
||||
@@ -40,6 +40,7 @@ export default class BaseLayout extends React.Component {
|
||||
let servers = specSelectors.servers()
|
||||
|
||||
let SvgAssets = getComponent("SvgAssets")
|
||||
let VersionPragmaFilter = getComponent("VersionPragmaFilter")
|
||||
let Info = getComponent("info")
|
||||
let Operations = getComponent("operations", true)
|
||||
let Models = getComponent("Models", true)
|
||||
@@ -49,6 +50,9 @@ export default class BaseLayout extends React.Component {
|
||||
let Servers = getComponent("Servers")
|
||||
let Errors = getComponent("errors", true)
|
||||
|
||||
let isSwagger2 = specSelectors.isSwagger2()
|
||||
let isOAS3 = specSelectors.isOAS3()
|
||||
|
||||
let isLoading = specSelectors.loadingStatus() === "loading"
|
||||
let isFailed = specSelectors.loadingStatus() === "failed"
|
||||
let filter = layoutSelectors.currentFilter()
|
||||
@@ -80,7 +84,7 @@ export default class BaseLayout extends React.Component {
|
||||
|
||||
<div className='swagger-ui'>
|
||||
<SvgAssets />
|
||||
<div>
|
||||
<VersionPragmaFilter isSwagger2={isSwagger2} isOAS3={isOAS3} alsoShow={<Errors/>}>
|
||||
<Errors/>
|
||||
<Row className="information-container">
|
||||
<Col mobile={12}>
|
||||
@@ -142,7 +146,7 @@ export default class BaseLayout extends React.Component {
|
||||
<Models/>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</VersionPragmaFilter>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
54
src/core/components/version-pragma-filter.jsx
Normal file
54
src/core/components/version-pragma-filter.jsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export default class VersionPragmaFilter extends React.PureComponent {
|
||||
static propTypes = {
|
||||
isSwagger2: PropTypes.bool.isRequired,
|
||||
isOAS3: PropTypes.bool.isRequired,
|
||||
bypass: PropTypes.bool,
|
||||
alsoShow: PropTypes.element,
|
||||
children: PropTypes.any,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
alsoShow: null,
|
||||
children: null,
|
||||
bypass: false,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { bypass, isSwagger2, isOAS3, alsoShow } = this.props
|
||||
|
||||
if(bypass) {
|
||||
return <div>{ this.props.children }</div>
|
||||
}
|
||||
|
||||
if(isSwagger2 && isOAS3) {
|
||||
return <div className="version-pragma">
|
||||
{alsoShow}
|
||||
<div className="version-pragma__message version-pragma__message--ambiguous">
|
||||
<div>
|
||||
<h3>Unable to render this definition</h3>
|
||||
<p><code>swagger</code> and <code>openapi</code> fields cannot be present in the same Swagger or OpenAPI definition. Please remove one of the fields.</p>
|
||||
<p>Supported version fields are <code>swagger: {"\"2.0\""}</code> and those that match <code>openapi: 3.0.n</code> (for example, <code>openapi: 3.0.0</code>).</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
if(!isSwagger2 && !isOAS3) {
|
||||
return <div className="version-pragma">
|
||||
{alsoShow}
|
||||
<div className="version-pragma__message version-pragma__message--missing">
|
||||
<div>
|
||||
<h3>Unable to render this definition</h3>
|
||||
<p>The provided definition does not specify a valid version field.</p>
|
||||
<p>Please indicate a valid Swagger or OpenAPI version field. Supported version fields are <code>swagger: {"\"2.0\""}</code> and those that match <code>openapi: 3.0.n</code> (for example, <code>openapi: 3.0.0</code>).</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
return <div>{ this.props.children }</div>
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ export function isOAS3(jsSpec) {
|
||||
return false
|
||||
}
|
||||
|
||||
return oasVersion.startsWith("3")
|
||||
return oasVersion.startsWith("3.0.")
|
||||
}
|
||||
|
||||
export function isSwagger2(jsSpec) {
|
||||
@@ -15,7 +15,7 @@ export function isSwagger2(jsSpec) {
|
||||
return false
|
||||
}
|
||||
|
||||
return swaggerVersion.startsWith("2")
|
||||
return swaggerVersion.startsWith("2.0")
|
||||
}
|
||||
|
||||
export function OAS3ComponentWrapFactory(Component) {
|
||||
|
||||
@@ -66,6 +66,7 @@ import ArrayModel from "core/components/array-model"
|
||||
import PrimitiveModel from "core/components/primitive-model"
|
||||
import Property from "core/components/property"
|
||||
import TryItOutButton from "core/components/try-it-out-button"
|
||||
import VersionPragmaFilter from "core/components/version-pragma-filter"
|
||||
import VersionStamp from "core/components/version-stamp"
|
||||
import DeepLink from "core/components/deep-link"
|
||||
import SvgAssets from "core/components/svg-assets"
|
||||
@@ -125,6 +126,7 @@ export default function() {
|
||||
TryItOutButton,
|
||||
Markdown,
|
||||
BaseLayout,
|
||||
VersionPragmaFilter,
|
||||
VersionStamp,
|
||||
OperationExt,
|
||||
OperationExtRow,
|
||||
|
||||
@@ -796,3 +796,30 @@ a.nostyle {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.version-pragma {
|
||||
height: 100%;
|
||||
padding: 5em 0px;
|
||||
|
||||
&__message {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
line-height: 1.5em;
|
||||
|
||||
padding: 0px .6em;
|
||||
|
||||
> div {
|
||||
max-width: 55ch;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #dedede;
|
||||
padding: 4px 4px 2px;
|
||||
white-space: pre;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
70
test/components/version-pragma-filter.js
Normal file
70
test/components/version-pragma-filter.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/* eslint-env mocha */
|
||||
import React from "react"
|
||||
import expect, { createSpy } from "expect"
|
||||
import { shallow } from "enzyme"
|
||||
import { fromJS, Map } from "immutable"
|
||||
import VersionPragmaFilter from "components/version-pragma-filter"
|
||||
|
||||
describe("<VersionPragmaFilter/>", function(){
|
||||
it("renders children for a Swagger 2 definition", function(){
|
||||
// When
|
||||
let wrapper = shallow(
|
||||
<VersionPragmaFilter isSwagger2={true} isOAS3={false}>
|
||||
hello!
|
||||
</VersionPragmaFilter>
|
||||
)
|
||||
|
||||
// Then
|
||||
expect(wrapper.find("div").length).toEqual(1)
|
||||
expect(wrapper.find("div").text()).toEqual("hello!")
|
||||
})
|
||||
it("renders children for an OpenAPI 3 definition", function(){
|
||||
// When
|
||||
let wrapper = shallow(
|
||||
<VersionPragmaFilter isSwagger2={false} isOAS3={true}>
|
||||
hello!
|
||||
</VersionPragmaFilter>
|
||||
)
|
||||
|
||||
// Then
|
||||
expect(wrapper.find("div").length).toEqual(1)
|
||||
expect(wrapper.find("div").text()).toEqual("hello!")
|
||||
})
|
||||
it("renders children when a bypass prop is set", function(){
|
||||
// When
|
||||
let wrapper = shallow(
|
||||
<VersionPragmaFilter bypass>
|
||||
hello!
|
||||
</VersionPragmaFilter>
|
||||
)
|
||||
|
||||
// Then
|
||||
expect(wrapper.find("div").length).toEqual(1)
|
||||
expect(wrapper.find("div").text()).toEqual("hello!")
|
||||
})
|
||||
it("renders the correct message for an ambiguous-version definition", function(){
|
||||
// When
|
||||
let wrapper = shallow(
|
||||
<VersionPragmaFilter isSwagger2={true} isOAS3={true}>
|
||||
hello!
|
||||
</VersionPragmaFilter>
|
||||
)
|
||||
|
||||
// Then
|
||||
expect(wrapper.find("div.version-pragma__message--ambiguous").length).toEqual(1)
|
||||
expect(wrapper.find("div.version-pragma__message--missing").length).toEqual(0)
|
||||
})
|
||||
it("renders the correct message for a missing-version definition", function(){
|
||||
// When
|
||||
let wrapper = shallow(
|
||||
<VersionPragmaFilter isSwagger2={false} isOAS3={false}>
|
||||
hello!
|
||||
</VersionPragmaFilter>
|
||||
)
|
||||
|
||||
// Then
|
||||
expect(wrapper.find("div.version-pragma__message--missing").length).toEqual(1)
|
||||
expect(wrapper.find("div.version-pragma__message--ambiguous").length).toEqual(0)
|
||||
})
|
||||
|
||||
})
|
||||
Reference in New Issue
Block a user