Skip to content

Commit

Permalink
Merge pull request #3628 from gilbode/ft/default_model_rendering
Browse files Browse the repository at this point in the history
Add defaultModelRendering parameter.
  • Loading branch information
shockey authored Sep 29, 2017
2 parents 356dc81 + 263f6fe commit cecc3b3
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 11 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ domNode | The HTML DOM element inside which SwaggerUi will put the user interfac
oauth2RedirectUrl | OAuth redirect URL
tagsSorter | 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.
operationsSorter | 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.
defaultModelRendering | Controls how models are shown when the API is first rendered. (The user can always switch the rendering for a given model by clicking the 'Model' and 'Example Value' links.) It can be set to 'model' or 'example', and the default is 'example'.
defaultModelExpandDepth | The default expansion depth for models. The default value is 1.
configUrl | Configs URL
parameterMacro | MUST be a function. Function to set default value to parameters. Accepts two arguments parameterMacro(operation, parameter). Operation and parameter are objects passed for context, both remain immutable
modelPropertyMacro | MUST be a function. Function to set default values to each property in model. Accepts one argument modelPropertyMacro(property), property is immutable
Expand Down
16 changes: 11 additions & 5 deletions src/core/components/model-example.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ export default class ModelExample extends React.Component {
specSelectors: PropTypes.object.isRequired,
schema: PropTypes.object.isRequired,
example: PropTypes.any.isRequired,
isExecute: PropTypes.bool
isExecute: PropTypes.bool,
getConfigs: PropTypes.func.isRequired
}

constructor(props, context) {
super(props, context)

let { getConfigs } = this.props
let { defaultModelRendering } = getConfigs()
if (defaultModelRendering !== "example" && defaultModelRendering !== "model") {
defaultModelRendering = "example"
}
this.state = {
activeTab: "example"
activeTab: defaultModelRendering
}
}

Expand All @@ -27,7 +32,8 @@ export default class ModelExample extends React.Component {
}

render() {
let { getComponent, specSelectors, schema, example, isExecute } = this.props
let { getComponent, specSelectors, schema, example, isExecute, getConfigs } = this.props
let { defaultModelExpandDepth } = getConfigs()
const ModelWrapper = getComponent("ModelWrapper")

return <div>
Expand All @@ -47,7 +53,7 @@ export default class ModelExample extends React.Component {
!isExecute && this.state.activeTab === "model" && <ModelWrapper schema={ schema }
getComponent={ getComponent }
specSelectors={ specSelectors }
expandDepth={ 1 } />
expandDepth={ defaultModelExpandDepth } />


}
Expand Down
3 changes: 2 additions & 1 deletion src/core/components/models.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class Models extends Component {
render(){
let { specSelectors, getComponent, layoutSelectors, layoutActions, getConfigs } = this.props
let definitions = specSelectors.definitions()
let { docExpansion } = getConfigs()
let { docExpansion, defaultModelExpandDepth } = getConfigs()
let showModels = layoutSelectors.isShown("models", docExpansion === "full" || docExpansion === "list" )

const ModelWrapper = getComponent("ModelWrapper")
Expand All @@ -33,6 +33,7 @@ export default class Models extends Component {
definitions.entrySeq().map( ( [ name, model ])=>{
return <div className="model-container" key={ `models-section-${name}` }>
<ModelWrapper name={ name }
expandDepth={ defaultModelExpandDepth }
schema={ model }
getComponent={ getComponent }
specSelectors={ specSelectors }/>
Expand Down
1 change: 1 addition & 0 deletions src/core/components/operation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ export default class Operation extends PureComponent {
specActions={ specActions }
specSelectors={ specSelectors }
pathMethod={ [path, method] }
getConfigs={ getConfigs }
/>

{!tryItOutEnabled || !allowTryItOut ? null : schemes && schemes.size ? <div className="opblock-schemes">
Expand Down
6 changes: 4 additions & 2 deletions src/core/components/parameter-row.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export default class ParameterRow extends Component {
isExecute: PropTypes.bool,
onChangeConsumes: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
pathMethod: PropTypes.array.isRequired
pathMethod: PropTypes.array.isRequired,
getConfigs: PropTypes.func.isRequired
}

constructor(props, context) {
Expand Down Expand Up @@ -56,7 +57,7 @@ export default class ParameterRow extends Component {
}

render() {
let {param, onChange, getComponent, isExecute, fn, onChangeConsumes, specSelectors, pathMethod} = this.props
let {param, onChange, getComponent, getConfigs, isExecute, fn, onChangeConsumes, specSelectors, pathMethod} = this.props

let { isOAS3 } = specSelectors

Expand Down Expand Up @@ -120,6 +121,7 @@ export default class ParameterRow extends Component {

{
bodyParam && schema ? <ModelExample getComponent={ getComponent }
getConfigs={ getConfigs }
isExecute={ isExecute }
specSelectors={ specSelectors }
schema={ schema }
Expand Down
5 changes: 4 additions & 1 deletion src/core/components/parameters.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export default class Parameters extends Component {
onTryoutClick: PropTypes.func,
onCancelClick: PropTypes.func,
onChangeKey: PropTypes.array,
pathMethod: PropTypes.array.isRequired
pathMethod: PropTypes.array.isRequired,
getConfigs: PropTypes.func.isRequired
}


Expand Down Expand Up @@ -60,6 +61,7 @@ export default class Parameters extends Component {

fn,
getComponent,
getConfigs,
specSelectors,
pathMethod
} = this.props
Expand Down Expand Up @@ -93,6 +95,7 @@ export default class Parameters extends Component {
eachMap(parameters, (parameter) => (
<ParameterRow fn={ fn }
getComponent={ getComponent }
getConfigs={ getConfigs }
param={ parameter }
key={ `${parameter.get( "in" )}.${parameter.get("name")}` }
onChange={ this.onChange }
Expand Down
3 changes: 3 additions & 0 deletions src/core/components/response.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export default class Response extends React.Component {
response: PropTypes.object,
className: PropTypes.string,
getComponent: PropTypes.func.isRequired,
getConfigs: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
fn: PropTypes.object.isRequired,
contentType: PropTypes.string,
Expand Down Expand Up @@ -73,6 +74,7 @@ export default class Response extends React.Component {
className,
fn,
getComponent,
getConfigs,
specSelectors,
contentType,
controlsAcceptHeader
Expand Down Expand Up @@ -144,6 +146,7 @@ export default class Response extends React.Component {
{ example ? (
<ModelExample
getComponent={ getComponent }
getConfigs={ getConfigs }
specSelectors={ specSelectors }
schema={ fromJSOrdered(schema) }
example={ example }/>
Expand Down
5 changes: 3 additions & 2 deletions src/core/components/responses.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ export default class Responses extends React.Component {
produces: PropTypes.object,
producesValue: PropTypes.any,
getComponent: PropTypes.func.isRequired,
getConfigs: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
specActions: PropTypes.object.isRequired,
oas3Actions: PropTypes.object.isRequired,
pathMethod: PropTypes.array.isRequired,
displayRequestDuration: PropTypes.bool.isRequired,
fn: PropTypes.object.isRequired,
getConfigs: PropTypes.func.isRequired
fn: PropTypes.object.isRequired
}

static defaultProps = {
Expand Down Expand Up @@ -116,6 +116,7 @@ export default class Responses extends React.Component {
controlsAcceptHeader={response === acceptControllingResponse}
onContentTypeChange={this.onResponseContentTypeChange}
contentType={ producesValue }
getConfigs={ getConfigs }
getComponent={ getComponent }/>
)
}).toArray()
Expand Down
2 changes: 2 additions & 0 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ module.exports = function SwaggerUI(opts) {
requestInterceptor: (a => a),
responseInterceptor: (a => a),
showMutatedRequest: true,
defaultModelRendering: "example",
defaultModelExpandDepth: 1,

// Initial set of plugins ( TODO rename this, or refactor - we don't need presets _and_ plugins. Its just there for performance.
// Instead, we can compile the first plugin ( it can be a collection of plugins ), then batch the rest.
Expand Down
116 changes: 116 additions & 0 deletions test/components/model-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/* eslint-env mocha */
import React from "react"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import ModelExample from "components/model-example"
import ModelComponent from "components/model-wrapper"

describe("<ModelExample/>", function(){
// Given
let components = {
ModelWrapper: ModelComponent
}
let props = {
getComponent: (c) => {
return components[c]
},
specSelectors: {},
schema: {},
example: "{\"example\": \"value\"}",
isExecute: false,
getConfigs: () => ({
defaultModelRendering: "model",
defaultModelExpandDepth: 1
})
}
let exampleSelectedTestInputs = [
{ defaultModelRendering: "model", isExecute: true },
{ defaultModelRendering: "example", isExecute: true },
{ defaultModelRendering: "example", isExecute: false },
{ defaultModelRendering: "othervalue", isExecute: true },
{ defaultModelRendering: "othervalue", isExecute: false }
]
let modelSelectedTestInputs = [
{ defaultModelRendering: "model", isExecute: false }
]


it("renders model and example tabs", function(){
// When
let wrapper = shallow(<ModelExample {...props}/>)

// Then should render tabs
expect(wrapper.find("div > ul.tab").length).toEqual(1)

let tabs = wrapper.find("div > ul.tab").children()
expect(tabs.length).toEqual(2)
tabs.forEach((node) => {
expect(node.length).toEqual(1)
expect(node.name()).toEqual("li")
expect(node.hasClass("tabitem")).toEqual(true)
})
expect(tabs.at(0).text()).toEqual("Example Value")
expect(tabs.at(1).text()).toEqual("Model")
})

exampleSelectedTestInputs.forEach(function(testInputs) {
it("example tab is selected if isExecute = " + testInputs.isExecute + " and defaultModelRendering = " + testInputs.defaultModelRendering, function(){
// When
props.isExecute = testInputs.isExecute
props.getConfigs = () => ({
defaultModelRendering: testInputs.defaultModelRendering,
defaultModelExpandDepth: 1
})
let wrapper = shallow(<ModelExample {...props}/>)

// Then
let tabs = wrapper.find("div > ul.tab").children()

let exampleTab = tabs.at(0)
expect(exampleTab.hasClass("active")).toEqual(true)
let modelTab = tabs.at(1)
expect(modelTab.hasClass("active")).toEqual(false)

expect(wrapper.find("div > div").length).toEqual(1)
expect(wrapper.find("div > div").text()).toEqual(props.example)
})
})

modelSelectedTestInputs.forEach(function(testInputs) {
it("model tab is selected if isExecute = " + testInputs.isExecute + " and defaultModelRendering = " + testInputs.defaultModelRendering, function(){
// When
props.isExecute = testInputs.isExecute
props.getConfigs = () => ({
defaultModelRendering: testInputs.defaultModelRendering,
defaultModelExpandDepth: 1
})
let wrapper = shallow(<ModelExample {...props}/>)

// Then
let tabs = wrapper.find("div > ul.tab").children()

let exampleTab = tabs.at(0)
expect(exampleTab.hasClass("active")).toEqual(false)
let modelTab = tabs.at(1)
expect(modelTab.hasClass("active")).toEqual(true)

expect(wrapper.find("div > div").length).toEqual(1)
expect(wrapper.find("div > div").find(ModelComponent).props().expandDepth).toBe(1)
})
})

it("passes defaultModelExpandDepth to ModelComponent", function(){
// When
let expandDepth = 0
props.isExecute = false
props.getConfigs = () => ({
defaultModelRendering: "model",
defaultModelExpandDepth: expandDepth
})
let wrapper = shallow(<ModelExample {...props}/>)

// Then
expect(wrapper.find("div > div").find(ModelComponent).props().expandDepth).toBe(expandDepth)
})

})
51 changes: 51 additions & 0 deletions test/components/models.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* eslint-env mocha */
import React from "react"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import { fromJS } from "immutable"
import Models from "components/models"
import ModelCollpase from "components/model-collapse"
import ModelComponent from "components/model-wrapper"

describe("<Models/>", function(){
// Given
let components = {
Collapse: ModelCollpase,
ModelWrapper: ModelComponent
}
let props = {
getComponent: (c) => {
return components[c]
},
specSelectors: {
definitions: function() {
return fromJS({
def1: {},
def2: {}
})
}
},
layoutSelectors: {
isShown: createSpy()
},
layoutActions: {},
getConfigs: () => ({
docExpansion: "list",
defaultModelExpandDepth: 0
})
}


it("passes defaultModelExpandDepth to ModelWrapper", function(){
// When
let wrapper = shallow(<Models {...props}/>)

// Then should render tabs
expect(wrapper.find("ModelCollapse").length).toEqual(1)
expect(wrapper.find("ModelComponent").length).toBeGreaterThan(0)
wrapper.find("ModelComponent").forEach((modelWrapper) => {
expect(modelWrapper.props().expandDepth).toBe(0)
})
})

})

0 comments on commit cecc3b3

Please sign in to comment.