Merge pull request #3552 from shockey/bug/3541-3470-schemes

Fix global state issues with Schemes component
This commit is contained in:
Kyle
2017-08-09 18:07:43 -07:00
committed by GitHub
4 changed files with 46 additions and 12 deletions

View File

@@ -69,7 +69,10 @@ export default class BaseLayout extends React.Component {
<div className="scheme-container"> <div className="scheme-container">
<Col className="schemes wrapper" mobile={12}> <Col className="schemes wrapper" mobile={12}>
{ schemes && schemes.size ? ( { schemes && schemes.size ? (
<Schemes schemes={ schemes } specActions={ specActions } /> <Schemes
currentScheme={specSelectors.operationScheme()}
schemes={ schemes }
specActions={ specActions } />
) : null } ) : null }
{ securityDefinitions ? ( { securityDefinitions ? (

View File

@@ -229,7 +229,7 @@ export default class Operation extends PureComponent {
path={ path } path={ path }
method={ method } method={ method }
specActions={ specActions } specActions={ specActions }
operationScheme={ operationScheme } /> currentScheme={ operationScheme } />
</div> : null </div> : null
} }

View File

@@ -6,9 +6,9 @@ export default class Schemes extends React.Component {
static propTypes = { static propTypes = {
specActions: PropTypes.object.isRequired, specActions: PropTypes.object.isRequired,
schemes: PropTypes.object.isRequired, schemes: PropTypes.object.isRequired,
currentScheme: PropTypes.string.isRequired,
path: PropTypes.string, path: PropTypes.string,
method: PropTypes.string, method: PropTypes.string,
operationScheme: PropTypes.string
} }
componentWillMount() { componentWillMount() {
@@ -19,8 +19,8 @@ export default class Schemes extends React.Component {
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
if ( !this.props.operationScheme || !nextProps.schemes.has(this.props.operationScheme) ) { if ( !this.props.currentScheme || !nextProps.schemes.includes(this.props.currentScheme) ) {
// if we don't have a selected operationScheme or if our selected scheme is no longer an option, // if we don't have a selected currentScheme or if our selected scheme is no longer an option,
// then fire 'change' event and select the first scheme in the list of options // then fire 'change' event and select the first scheme in the list of options
this.setScheme(nextProps.schemes.first()) this.setScheme(nextProps.schemes.first())
} }

View File

@@ -7,35 +7,66 @@ import { fromJS } from "immutable"
import Schemes from "components/schemes" import Schemes from "components/schemes"
describe("<Schemes/>", function(){ describe("<Schemes/>", function(){
it("calls props.specActions.setScheme() when no operationScheme is selected", function(){ it("calls props.specActions.setScheme() when no currentScheme is selected", function(){
let setSchemeSpy = createSpy()
// Given // Given
let props = { let props = {
specActions: { specActions: {
setScheme: createSpy() setScheme: setSchemeSpy
}, },
schemes: fromJS([ schemes: fromJS([
"http", "http",
"https" "https"
]), ]),
operationScheme: undefined, currentScheme: undefined,
path: "/test", path: "/test",
method: "get" method: "get"
} }
// When // When
let wrapper = shallow(<Schemes {...props}/>) let wrapper = shallow(<Schemes {...props}/>)
// Then operationScheme should default to first scheme in options list // Then currentScheme should default to first scheme in options list
expect(props.specActions.setScheme).toHaveBeenCalledWith("http", "/test" , "get") expect(props.specActions.setScheme).toHaveBeenCalledWith("http", "/test" , "get")
// When the operationScheme is no longer in the list of options // When the currentScheme is no longer in the list of options
props.schemes = fromJS([ props.schemes = fromJS([
"https" "https"
]) ])
wrapper.setProps(props) wrapper.setProps(props)
// Then operationScheme should default to first scheme in options list // Then currentScheme should default to first scheme in options list, again
expect(props.specActions.setScheme).toHaveBeenCalledWith("https", "/test", "get") expect(props.specActions.setScheme).toHaveBeenCalledWith("https", "/test", "get")
}) })
it("doesn't call props.specActions.setScheme() when schemes hasn't changed", function(){
let setSchemeSpy = createSpy()
// Given
let props = {
specActions: {
setScheme: setSchemeSpy
},
schemes: fromJS([
"http",
"https"
]),
currentScheme: "https"
}
// When
let wrapper = shallow(<Schemes {...props}/>)
// Should be called initially, to set the global state
expect(setSchemeSpy.calls.length).toEqual(1)
// After an update
wrapper.instance().componentWillReceiveProps(props)
// Should not be called again, since `currentScheme` is in schemes
expect(setSchemeSpy.calls.length).toEqual(1)
})
}) })