Skip to content

Commit a03c127

Browse files
authored
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
1 parent a51bf1e commit a03c127

File tree

7 files changed

+161
-13
lines changed

7 files changed

+161
-13
lines changed

.travis.yml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@ branches:
1111
- master
1212
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
1313
install: "npm i && npm update"
14-
before_install:
15-
- | # quickly pass if only documentation is being updated
16-
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
17-
TRAVIS_COMMIT_RANGE="FETCH_HEAD...$TRAVIS_BRANCH"
18-
git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.md$)|(^(docs|examples))/' || {
19-
echo "Only docs were updated, stopping build process."
20-
exit
21-
}
22-
fi
2314
before_deploy:
2415
- npm run build
2516
env:

src/core/components/layouts/base.jsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export default class BaseLayout extends React.Component {
4040
let servers = specSelectors.servers()
4141

4242
let SvgAssets = getComponent("SvgAssets")
43+
let VersionPragmaFilter = getComponent("VersionPragmaFilter")
4344
let Info = getComponent("info")
4445
let Operations = getComponent("operations", true)
4546
let Models = getComponent("Models", true)
@@ -49,6 +50,9 @@ export default class BaseLayout extends React.Component {
4950
let Servers = getComponent("Servers")
5051
let Errors = getComponent("errors", true)
5152

53+
let isSwagger2 = specSelectors.isSwagger2()
54+
let isOAS3 = specSelectors.isOAS3()
55+
5256
let isLoading = specSelectors.loadingStatus() === "loading"
5357
let isFailed = specSelectors.loadingStatus() === "failed"
5458
let filter = layoutSelectors.currentFilter()
@@ -80,7 +84,7 @@ export default class BaseLayout extends React.Component {
8084

8185
<div className='swagger-ui'>
8286
<SvgAssets />
83-
<div>
87+
<VersionPragmaFilter isSwagger2={isSwagger2} isOAS3={isOAS3} alsoShow={<Errors/>}>
8488
<Errors/>
8589
<Row className="information-container">
8690
<Col mobile={12}>
@@ -142,7 +146,7 @@ export default class BaseLayout extends React.Component {
142146
<Models/>
143147
</Col>
144148
</Row>
145-
</div>
149+
</VersionPragmaFilter>
146150
</div>
147151
)
148152
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React from "react"
2+
import PropTypes from "prop-types"
3+
4+
export default class VersionPragmaFilter extends React.PureComponent {
5+
static propTypes = {
6+
isSwagger2: PropTypes.bool.isRequired,
7+
isOAS3: PropTypes.bool.isRequired,
8+
bypass: PropTypes.bool,
9+
alsoShow: PropTypes.element,
10+
children: PropTypes.any,
11+
}
12+
13+
static defaultProps = {
14+
alsoShow: null,
15+
children: null,
16+
bypass: false,
17+
}
18+
19+
render() {
20+
const { bypass, isSwagger2, isOAS3, alsoShow } = this.props
21+
22+
if(bypass) {
23+
return <div>{ this.props.children }</div>
24+
}
25+
26+
if(isSwagger2 && isOAS3) {
27+
return <div className="version-pragma">
28+
{alsoShow}
29+
<div className="version-pragma__message version-pragma__message--ambiguous">
30+
<div>
31+
<h3>Unable to render this definition</h3>
32+
<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>
33+
<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>
34+
</div>
35+
</div>
36+
</div>
37+
}
38+
39+
if(!isSwagger2 && !isOAS3) {
40+
return <div className="version-pragma">
41+
{alsoShow}
42+
<div className="version-pragma__message version-pragma__message--missing">
43+
<div>
44+
<h3>Unable to render this definition</h3>
45+
<p>The provided definition does not specify a valid version field.</p>
46+
<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>
47+
</div>
48+
</div>
49+
</div>
50+
}
51+
52+
return <div>{ this.props.children }</div>
53+
}
54+
}

src/core/plugins/oas3/helpers.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export function isOAS3(jsSpec) {
66
return false
77
}
88

9-
return oasVersion.startsWith("3")
9+
return oasVersion.startsWith("3.0.")
1010
}
1111

1212
export function isSwagger2(jsSpec) {
@@ -15,7 +15,7 @@ export function isSwagger2(jsSpec) {
1515
return false
1616
}
1717

18-
return swaggerVersion.startsWith("2")
18+
return swaggerVersion.startsWith("2.0")
1919
}
2020

2121
export function OAS3ComponentWrapFactory(Component) {

src/core/presets/base.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import ArrayModel from "core/components/array-model"
6666
import PrimitiveModel from "core/components/primitive-model"
6767
import Property from "core/components/property"
6868
import TryItOutButton from "core/components/try-it-out-button"
69+
import VersionPragmaFilter from "core/components/version-pragma-filter"
6970
import VersionStamp from "core/components/version-stamp"
7071
import DeepLink from "core/components/deep-link"
7172
import SvgAssets from "core/components/svg-assets"
@@ -125,6 +126,7 @@ export default function() {
125126
TryItOutButton,
126127
Markdown,
127128
BaseLayout,
129+
VersionPragmaFilter,
128130
VersionStamp,
129131
OperationExt,
130132
OperationExtRow,

src/style/_layout.scss

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,3 +796,30 @@ a.nostyle {
796796
cursor: pointer;
797797
}
798798
}
799+
800+
.version-pragma {
801+
height: 100%;
802+
padding: 5em 0px;
803+
804+
&__message {
805+
display: flex;
806+
justify-content: center;
807+
height: 100%;
808+
font-size: 1.2em;
809+
text-align: center;
810+
line-height: 1.5em;
811+
812+
padding: 0px .6em;
813+
814+
> div {
815+
max-width: 55ch;
816+
flex: 1;
817+
}
818+
819+
code {
820+
background-color: #dedede;
821+
padding: 4px 4px 2px;
822+
white-space: pre;
823+
}
824+
}
825+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* eslint-env mocha */
2+
import React from "react"
3+
import expect, { createSpy } from "expect"
4+
import { shallow } from "enzyme"
5+
import { fromJS, Map } from "immutable"
6+
import VersionPragmaFilter from "components/version-pragma-filter"
7+
8+
describe("<VersionPragmaFilter/>", function(){
9+
it("renders children for a Swagger 2 definition", function(){
10+
// When
11+
let wrapper = shallow(
12+
<VersionPragmaFilter isSwagger2={true} isOAS3={false}>
13+
hello!
14+
</VersionPragmaFilter>
15+
)
16+
17+
// Then
18+
expect(wrapper.find("div").length).toEqual(1)
19+
expect(wrapper.find("div").text()).toEqual("hello!")
20+
})
21+
it("renders children for an OpenAPI 3 definition", function(){
22+
// When
23+
let wrapper = shallow(
24+
<VersionPragmaFilter isSwagger2={false} isOAS3={true}>
25+
hello!
26+
</VersionPragmaFilter>
27+
)
28+
29+
// Then
30+
expect(wrapper.find("div").length).toEqual(1)
31+
expect(wrapper.find("div").text()).toEqual("hello!")
32+
})
33+
it("renders children when a bypass prop is set", function(){
34+
// When
35+
let wrapper = shallow(
36+
<VersionPragmaFilter bypass>
37+
hello!
38+
</VersionPragmaFilter>
39+
)
40+
41+
// Then
42+
expect(wrapper.find("div").length).toEqual(1)
43+
expect(wrapper.find("div").text()).toEqual("hello!")
44+
})
45+
it("renders the correct message for an ambiguous-version definition", function(){
46+
// When
47+
let wrapper = shallow(
48+
<VersionPragmaFilter isSwagger2={true} isOAS3={true}>
49+
hello!
50+
</VersionPragmaFilter>
51+
)
52+
53+
// Then
54+
expect(wrapper.find("div.version-pragma__message--ambiguous").length).toEqual(1)
55+
expect(wrapper.find("div.version-pragma__message--missing").length).toEqual(0)
56+
})
57+
it("renders the correct message for a missing-version definition", function(){
58+
// When
59+
let wrapper = shallow(
60+
<VersionPragmaFilter isSwagger2={false} isOAS3={false}>
61+
hello!
62+
</VersionPragmaFilter>
63+
)
64+
65+
// Then
66+
expect(wrapper.find("div.version-pragma__message--missing").length).toEqual(1)
67+
expect(wrapper.find("div.version-pragma__message--ambiguous").length).toEqual(0)
68+
})
69+
70+
})

0 commit comments

Comments
 (0)