diff --git a/src/core/components/content-type.jsx b/src/core/components/content-type.jsx index 6f81f671..19d22188 100644 --- a/src/core/components/content-type.jsx +++ b/src/core/components/content-type.jsx @@ -27,6 +27,16 @@ export default class ContentType extends React.Component { } } + componentWillReceiveProps(nextProps) { + if(!nextProps.contentTypes || !nextProps.contentTypes.size) { + return + } + + if(!nextProps.contentTypes.includes(nextProps.value)) { + nextProps.onChange(nextProps.contentTypes.first()) + } + } + onChangeWrapper = e => this.props.onChange(e.target.value) render() { diff --git a/src/core/containers/OperationContainer.jsx b/src/core/containers/OperationContainer.jsx index 510f52e4..4f224855 100644 --- a/src/core/containers/OperationContainer.jsx +++ b/src/core/containers/OperationContainer.jsx @@ -57,6 +57,8 @@ export default class OperationContainer extends PureComponent { const operationId = op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), props.path, props.method) || op.get("id") const isShownKey = ["operations", props.tag, operationId] const isDeepLinkingEnabled = deepLinking && deepLinking !== "false" + const allowTryItOut = typeof props.allowTryItOut === "undefined" ? + props.specSelectors.allowTryItOutFor(props.path, props.method) : props.allowTryItOut return { operationId, @@ -64,9 +66,9 @@ export default class OperationContainer extends PureComponent { showSummary, displayOperationId, displayRequestDuration, + allowTryItOut, isShown: layoutSelectors.isShown(isShownKey, docExpansion === "full" ), jumpToKey: `paths.${props.path}.${props.method}`, - allowTryItOut: props.specSelectors.allowTryItOutFor(props.path, props.method), response: props.specSelectors.responseFor(props.path, props.method), request: props.specSelectors.requestFor(props.path, props.method) } diff --git a/src/core/plugins/oas3/components/callbacks.jsx b/src/core/plugins/oas3/components/callbacks.jsx index 9290c6fe..43437375 100644 --- a/src/core/plugins/oas3/components/callbacks.jsx +++ b/src/core/plugins/oas3/components/callbacks.jsx @@ -1,10 +1,12 @@ import React from "react" import PropTypes from "prop-types" +import ImPropTypes from "react-immutable-proptypes" +import { fromJS } from "immutable" const Callbacks = (props) => { let { callbacks, getComponent } = props // const Markdown = getComponent("Markdown") - const Operation = getComponent("operation", true) + const OperationContainer = getComponent("OperationContainer", true) if(!callbacks) { return No callbacks @@ -16,24 +18,22 @@ const Callbacks = (props) => { { callback.map((pathItem, pathItemName) => { return
{ pathItem.map((operation, method) => { - return - // return
{JSON.stringify(operation)}
+ /> }) }
}) } - // return
- //

{name}

- // {callback.description && } - //
{JSON.stringify(callback)}
- //
}) return
{callbackElements} @@ -42,7 +42,7 @@ const Callbacks = (props) => { Callbacks.propTypes = { getComponent: PropTypes.func.isRequired, - callbacks: PropTypes.array.isRequired + callbacks: ImPropTypes.iterable.isRequired } diff --git a/src/core/plugins/oas3/components/request-body-editor.jsx b/src/core/plugins/oas3/components/request-body-editor.jsx index 62f91a52..ff4c4dae 100644 --- a/src/core/plugins/oas3/components/request-body-editor.jsx +++ b/src/core/plugins/oas3/components/request-body-editor.jsx @@ -48,6 +48,13 @@ export default class RequestBodyEditor extends PureComponent { } } + componentDidUpdate(prevProps) { + if(this.props.requestBody !== prevProps.requestBody) { + // force recalc of value if the request body definition has changed + this.setValueToSample(this.props.mediaType) + } + } + setValueToSample = (explicitMediaType) => { this.onChange(this.sample(explicitMediaType)) } diff --git a/src/core/plugins/oas3/components/request-body.jsx b/src/core/plugins/oas3/components/request-body.jsx index 5b20a50c..4c13f1d6 100644 --- a/src/core/plugins/oas3/components/request-body.jsx +++ b/src/core/plugins/oas3/components/request-body.jsx @@ -22,6 +22,10 @@ const RequestBody = ({ const mediaTypeValue = requestBodyContent.get(contentType) + if(!mediaTypeValue) { + return null + } + return
{ requestBodyDescription && diff --git a/src/core/plugins/view/root-injects.js b/src/core/plugins/view/root-injects.js index 04d0131a..d977400d 100644 --- a/src/core/plugins/view/root-injects.js +++ b/src/core/plugins/view/root-injects.js @@ -120,5 +120,5 @@ export const getComponent = (getSystem, getStore, getComponents, componentName, return makeContainer(getSystem, component, getStore()) // container == truthy - return makeContainer(getSystem, component) + return makeContainer(getSystem, wrapRender(component)) } diff --git a/test/core/system/system.js b/test/core/system/system.js index 3abd02d9..073390fa 100644 --- a/test/core/system/system.js +++ b/test/core/system/system.js @@ -571,6 +571,116 @@ describe("bound system", function(){ // Then expect(renderedComponent.text()).toEqual("This came from mapStateToProps and this came from the system and this came from my own props") }) + + it("should catch errors thrown inside of React Component Class render methods", function() { + // Given + // eslint-disable-next-line react/require-render-return + class BrokenComponent extends React.Component { + render() { + throw new Error("This component is broken") + } + } + const system = new System({ + plugins: [ + ViewPlugin, + { + components: { + BrokenComponent + } + } + ] + }) + + // When + var Component = system.getSystem().getComponent("BrokenComponent") + const renderedComponent = render() + + // Then + expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.") + }) + + it("should catch errors thrown inside of pure component render methods", function() { + // Given + // eslint-disable-next-line react/require-render-return + class BrokenComponent extends PureComponent { + render() { + throw new Error("This component is broken") + } + } + + const system = new System({ + plugins: [ + ViewPlugin, + { + components: { + BrokenComponent + } + } + ] + }) + + // When + var Component = system.getSystem().getComponent("BrokenComponent") + const renderedComponent = render() + + // Then + expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.") + }) + + it("should catch errors thrown inside of stateless component functions", function() { + // Given + // eslint-disable-next-line react/require-render-return + let BrokenComponent = function BrokenComponent() { throw new Error("This component is broken") } + const system = new System({ + plugins: [ + ViewPlugin, + { + components: { + BrokenComponent + } + } + ] + }) + + // When + var Component = system.getSystem().getComponent("BrokenComponent") + const renderedComponent = render() + + // Then + expect(renderedComponent.text().startsWith("😱 Could not render")).toEqual(true) + }) + + it("should catch errors thrown inside of container components", function() { + // Given + // eslint-disable-next-line react/require-render-return + class BrokenComponent extends React.Component { + render() { + throw new Error("This component is broken") + } + } + + const system = new System({ + plugins: [ + ViewPlugin, + { + components: { + BrokenComponent + } + } + ] + }) + + // When + var Component = system.getSystem().getComponent("BrokenComponent", true) + const renderedComponent = render( + + + + ) + + // Then + expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.") + }) }) })