diff --git a/README.md b/README.md
index 2c9e884d..b231ed54 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/src/core/components/model-example.jsx b/src/core/components/model-example.jsx
index 768ee04b..23d7c802 100644
--- a/src/core/components/model-example.jsx
+++ b/src/core/components/model-example.jsx
@@ -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
}
}
@@ -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
@@ -47,7 +53,7 @@ export default class ModelExample extends React.Component {
!isExecute && this.state.activeTab === "model" &&
+ expandDepth={ defaultModelExpandDepth } />
}
diff --git a/src/core/components/models.jsx b/src/core/components/models.jsx
index 1af412ab..e02e5c11 100644
--- a/src/core/components/models.jsx
+++ b/src/core/components/models.jsx
@@ -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")
@@ -33,6 +33,7 @@ export default class Models extends Component {
definitions.entrySeq().map( ( [ name, model ])=>{
return
{!tryItOutEnabled || !allowTryItOut ? null : schemes && schemes.size ?
diff --git a/src/core/components/parameter-row.jsx b/src/core/components/parameter-row.jsx
index 04466a38..82dc064a 100644
--- a/src/core/components/parameter-row.jsx
+++ b/src/core/components/parameter-row.jsx
@@ -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) {
@@ -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
@@ -121,6 +122,7 @@ export default class ParameterRow extends Component {
{
bodyParam && schema ?
(
diff --git a/src/core/components/responses.jsx b/src/core/components/responses.jsx
index e365a44b..e9e29fec 100644
--- a/src/core/components/responses.jsx
+++ b/src/core/components/responses.jsx
@@ -12,12 +12,12 @@ 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,
pathMethod: PropTypes.array.isRequired,
displayRequestDuration: PropTypes.bool.isRequired,
- fn: PropTypes.object.isRequired,
- getConfigs: PropTypes.func.isRequired
+ fn: PropTypes.object.isRequired
}
static defaultProps = {
@@ -89,6 +89,7 @@ export default class Responses extends React.Component {
response={ response }
specSelectors={ specSelectors }
contentType={ producesValue }
+ getConfigs={ getConfigs }
getComponent={ getComponent }/>
)
}).toArray()
diff --git a/src/core/index.js b/src/core/index.js
index ddf162ab..abc0ba36 100644
--- a/src/core/index.js
+++ b/src/core/index.js
@@ -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.
diff --git a/test/components/model-example.js b/test/components/model-example.js
new file mode 100644
index 00000000..f4225c30
--- /dev/null
+++ b/test/components/model-example.js
@@ -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("", 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()
+
+ // 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()
+
+ // 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()
+
+ // 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()
+
+ // Then
+ expect(wrapper.find("div > div").find(ModelComponent).props().expandDepth).toBe(expandDepth)
+ })
+
+})
diff --git a/test/components/models.js b/test/components/models.js
new file mode 100644
index 00000000..750a8cf1
--- /dev/null
+++ b/test/components/models.js
@@ -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("", 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()
+
+ // 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)
+ })
+ })
+
+})