Merge branch 'master' into feature/headerfix

This commit is contained in:
Kyle
2017-08-10 21:17:44 -07:00
committed by GitHub
8 changed files with 273 additions and 39 deletions

54
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,54 @@
## Contributing to Swagger-UI
We love contributions from our community of users! This document explains our guidelines and workflows. Please take care to follow them, as it helps us keep things moving smoothly.
#### Environment setup
0. Install Node.js (4 or newer) and npm (3 or newer).
1. Make a fork of Swagger-UI on GitHub, then clone your fork to your machine.
2. Run `npm install` in your Swagger-UI directory.
3. Run `npm run dev`. `localhost:3200` should open automatically.
4. You're ready to go!
#### Branching model
Feature branches should be prefixed with `ft/`.
Bugfix branches should be prefixed with `bug/`.
Version branches should be prefixed with `v/`.
After the forward slash, include a short description of what you're fixing. For example: `bug/fix-everything-that-was-broken`. For versions, add the version that will be released via the branch, for example: `v/1.2.3`.
If there's an issue filed that you're addressing in your branch, include the issue number directly after the forward slash. For example: `bug/1234-fix-all-the-other-things`.
#### Filing issues
- **Do** include the Swagger-UI build you're using - you can find this by opening your console and checking `window.versions.swaggerUi`
- **Do** include a spec that demonstrates the issue you're experiencing.
- **Do** include screenshots, if needed. GIFs are even better!
- **Do** place code inside of a pre-formatted container by surrounding the code with triple backticks.
- **Don't** open tickets discussing issues with the Swagger/OpenAPI specification itself, or for issues with projects that use Swagger-UI.
- **Don't** open an issue without searching the issue tracker for duplicates first.
#### Committing
- Break your commits into logical atomic units. Well-segmented commits make it _much_ easier for others to step through your changes.
- Limit your subject (first) line to 50 characters (GitHub truncates more than 70).
- Provide a body if you'd like to explain your commit in detail.
- Capitalize the beginning of your subject line, and do not end the subject line with a period.
- Your subject line should complete this sentence: `If applied, this commit will [your subject line].`
- Don't use [magic GitHub words](https://help.github.com/articles/closing-issues-using-keywords/) in your commits to close issues - do that in the pull request for your code instead.
_Adapted from [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/#seven-rules)._
#### Making pull requests
- **Do** summarize your changes in the PR body. If in doubt, write a bullet-point list titled `This PR does the following:`.
- **Do** include references to issues that your PR solves, and use [magic GitHub words](https://help.github.com/articles/closing-issues-using-keywords/) to close those issues automatically when your PR is merged.
- **Do** include tests that cover new or changed functionality.
- **Do** be careful to follow our ESLint style rules. We recommend installing an ESLint plugin if you use a graphical code editor.
- **Do** make sure that tests and the linter are passing by running `npm test` locally, otherwise we can't merge your pull request.
- **Don't** include any changes to files in the `dist/` directory - we update those files only during releases.
- **Don't** mention maintainers in your original PR body - we probably would've seen it anyway, so it just increases the noise in our inboxes. Do feel free to ping maintainers if a week has passed and you've heard nothing from us.
- **Don't** open PRs for custom functionality that only serves a small subset of our users - custom functionality should be implemented outside of our codebase, via a plugin.

View File

@@ -69,7 +69,9 @@ export default class ParamBody extends PureComponent {
let { param, fn:{inferSchema} } = this.props let { param, fn:{inferSchema} } = this.props
let schema = inferSchema(param.toJS()) let schema = inferSchema(param.toJS())
return getSampleSchema(schema, xml) return getSampleSchema(schema, xml, {
includeWriteOnly: true
})
} }
onChange = (value, { isEditBox, isXml }) => { onChange = (value, { isEditBox, isXml }) => {

View File

@@ -83,11 +83,16 @@ export default class Response extends React.Component {
if(isOAS3()) { if(isOAS3()) {
let oas3SchemaForContentType = response.getIn(["content", this.state.responseContentType, "schema"]) let oas3SchemaForContentType = response.getIn(["content", this.state.responseContentType, "schema"])
sampleResponse = oas3SchemaForContentType ? getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, { includeReadOnly: true }) : null sampleResponse = oas3SchemaForContentType ? getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, {
includeReadOnly: true
}) : null
schema = oas3SchemaForContentType ? inferSchema(oas3SchemaForContentType.toJS()) : null schema = oas3SchemaForContentType ? inferSchema(oas3SchemaForContentType.toJS()) : null
} else { } else {
schema = inferSchema(response.toJS()) schema = inferSchema(response.toJS())
sampleResponse = schema ? getSampleSchema(schema, contentType, { includeReadOnly: true }) : null sampleResponse = schema ? getSampleSchema(schema, contentType, {
includeReadOnly: true,
includeWriteOnly: true // writeOnly has no filtering effect in swagger 2.0
}) : null
} }
let example = getExampleComponent( sampleResponse, examples, HighlightCode ) let example = getExampleComponent( sampleResponse, examples, HighlightCode )

View File

@@ -20,7 +20,7 @@ export default function curl( request ){
if ( request.get("body") ){ if ( request.get("body") ){
if(type === "multipart/form-data" && request.get("method") === "POST") { if(type === "multipart/form-data" && request.get("method") === "POST") {
for( let [ k,v ] of request.get("body").values()) { for( let [ k,v ] of request.get("body").entrySeq()) {
curlified.push( "-F" ) curlified.push( "-F" )
if (v instanceof win.File) { if (v instanceof win.File) {
curlified.push( `"${k}=@${v.name};type=${v.type}"` ) curlified.push( `"${k}=@${v.name};type=${v.type}"` )

View File

@@ -16,7 +16,9 @@ const RequestBody = ({ requestBody, getComponent, specSelectors, contentType })
const mediaTypeValue = requestBodyContent.get(contentType) const mediaTypeValue = requestBodyContent.get(contentType)
const sampleSchema = getSampleSchema(mediaTypeValue.get("schema").toJS(), contentType) const sampleSchema = getSampleSchema(mediaTypeValue.get("schema").toJS(), contentType, {
includeWriteOnly: true
})
return <div> return <div>
{ requestBodyDescription && { requestBodyDescription &&

View File

@@ -27,7 +27,7 @@ const primitive = (schema) => {
export const sampleFromSchema = (schema, config={}) => { export const sampleFromSchema = (schema, config={}) => {
let { type, example, properties, additionalProperties, items } = objectify(schema) let { type, example, properties, additionalProperties, items } = objectify(schema)
let { includeReadOnly } = config let { includeReadOnly, includeWriteOnly } = config
if(example !== undefined) if(example !== undefined)
return example return example
@@ -46,16 +46,20 @@ export const sampleFromSchema = (schema, config={}) => {
let props = objectify(properties) let props = objectify(properties)
let obj = {} let obj = {}
for (var name in props) { for (var name in props) {
if ( !props[name].readOnly || includeReadOnly ) { if ( props[name].readOnly && !includeReadOnly ) {
obj[name] = sampleFromSchema(props[name], { includeReadOnly: includeReadOnly }) continue
} }
if ( props[name].writeOnly && !includeWriteOnly ) {
continue
}
obj[name] = sampleFromSchema(props[name], config)
} }
if ( additionalProperties === true ) { if ( additionalProperties === true ) {
obj.additionalProp1 = {} obj.additionalProp1 = {}
} else if ( additionalProperties ) { } else if ( additionalProperties ) {
let additionalProps = objectify(additionalProperties) let additionalProps = objectify(additionalProperties)
let additionalPropVal = sampleFromSchema(additionalProps, { includeReadOnly: includeReadOnly }) let additionalPropVal = sampleFromSchema(additionalProps, config)
for (let i = 1; i < 4; i++) { for (let i = 1; i < 4; i++) {
obj["additionalProp" + i] = additionalPropVal obj["additionalProp" + i] = additionalPropVal
@@ -65,7 +69,7 @@ export const sampleFromSchema = (schema, config={}) => {
} }
if(type === "array") { if(type === "array") {
return [ sampleFromSchema(items, { includeReadOnly: includeReadOnly }) ] return [ sampleFromSchema(items, config) ]
} }
if(schema["enum"]) { if(schema["enum"]) {
@@ -96,7 +100,7 @@ export const inferSchema = (thing) => {
export const sampleXmlFromSchema = (schema, config={}) => { export const sampleXmlFromSchema = (schema, config={}) => {
let objectifySchema = objectify(schema) let objectifySchema = objectify(schema)
let { type, properties, additionalProperties, items, example } = objectifySchema let { type, properties, additionalProperties, items, example } = objectifySchema
let { includeReadOnly } = config let { includeReadOnly, includeWriteOnly } = config
let defaultValue = objectifySchema.default let defaultValue = objectifySchema.default
let res = {} let res = {}
let _attr = {} let _attr = {}
@@ -177,27 +181,32 @@ export const sampleXmlFromSchema = (schema, config={}) => {
example = example || {} example = example || {}
for (let propName in props) { for (let propName in props) {
if ( !props[propName].readOnly || includeReadOnly ) { if ( props[propName].readOnly && !includeReadOnly ) {
props[propName].xml = props[propName].xml || {} continue
}
if ( props[propName].writeOnly && !includeWriteOnly ) {
continue
}
if (props[propName].xml.attribute) { props[propName].xml = props[propName].xml || {}
let enumAttrVal = Array.isArray(props[propName].enum) && props[propName].enum[0]
let attrExample = props[propName].example if (props[propName].xml.attribute) {
let attrDefault = props[propName].default let enumAttrVal = Array.isArray(props[propName].enum) && props[propName].enum[0]
_attr[props[propName].xml.name || propName] = attrExample!== undefined && attrExample let attrExample = props[propName].example
|| example[propName] !== undefined && example[propName] || attrDefault !== undefined && attrDefault let attrDefault = props[propName].default
|| enumAttrVal || primitive(props[propName]) _attr[props[propName].xml.name || propName] = attrExample!== undefined && attrExample
|| example[propName] !== undefined && example[propName] || attrDefault !== undefined && attrDefault
|| enumAttrVal || primitive(props[propName])
} else {
props[propName].xml.name = props[propName].xml.name || propName
props[propName].example = props[propName].example !== undefined ? props[propName].example : example[propName]
let t = sampleXmlFromSchema(props[propName])
if (Array.isArray(t)) {
res[displayName] = res[displayName].concat(t)
} else { } else {
props[propName].xml.name = props[propName].xml.name || propName res[displayName].push(t)
props[propName].example = props[propName].example !== undefined ? props[propName].example : example[propName]
let t = sampleXmlFromSchema(props[propName])
if (Array.isArray(t)) {
res[displayName] = res[displayName].concat(t)
} else {
res[displayName].push(t)
}
} }
} }
} }

View File

@@ -132,10 +132,10 @@ describe("curlify", function() {
url: "http://example.com", url: "http://example.com",
method: "POST", method: "POST",
headers: { "content-type": "multipart/form-data" }, headers: { "content-type": "multipart/form-data" },
body: [ body: {
["id", "123"], id: "123",
["name", "Sahar"] name: "Sahar"
] }
} }
let curlified = curl(Im.fromJS(req)) let curlified = curl(Im.fromJS(req))
@@ -152,10 +152,10 @@ describe("curlify", function() {
url: "http://example.com", url: "http://example.com",
method: "POST", method: "POST",
headers: { "content-type": "multipart/form-data" }, headers: { "content-type": "multipart/form-data" },
body: [ body: {
["id", "123"], id: "123",
["file", file] file
] }
} }
let curlified = curl(Im.fromJS(req)) let curlified = curl(Im.fromJS(req))

View File

@@ -1,6 +1,105 @@
import { createXMLExample } from "corePlugins/samples/fn" import { createXMLExample, sampleFromSchema } from "corePlugins/samples/fn"
import expect from "expect" import expect from "expect"
describe("sampleFromSchema", function() {
it("returns object with no readonly fields for parameter", function () {
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
readOnlyDog: {
readOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
var expected = {
id: 0
}
expect(sampleFromSchema(definition, { includeReadOnly: false })).toEqual(expected)
})
it("returns object with readonly fields for parameter, with includeReadOnly", function () {
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
readOnlyDog: {
readOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
var expected = {
id: 0,
readOnlyDog: "string"
}
expect(sampleFromSchema(definition, { includeReadOnly: true })).toEqual(expected)
})
it("returns object without writeonly fields for parameter", function () {
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
writeOnlyDog: {
writeOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
var expected = {
id: 0
}
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns object with writeonly fields for parameter, with includeWriteOnly", function () {
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
writeOnlyDog: {
writeOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
var expected = {
id: 0,
writeOnlyDog: "string"
}
expect(sampleFromSchema(definition, { includeWriteOnly: true })).toEqual(expected)
})
})
describe("createXMLExample", function () { describe("createXMLExample", function () {
var sut = createXMLExample var sut = createXMLExample
@@ -554,6 +653,69 @@ describe("createXMLExample", function () {
expect(sut(definition, { includeReadOnly: false })).toEqual(expected) expect(sut(definition, { includeReadOnly: false })).toEqual(expected)
}) })
it("returns object with readonly fields for parameter, with includeReadOnly", function () {
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<id>0</id>\n\t<dog>string</dog>\n</animals>"
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
dog: {
readOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
expect(sut(definition, { includeReadOnly: true })).toEqual(expected)
})
it("returns object without writeonly fields for parameter", function () {
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<id>0</id>\n</animals>"
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
dog: {
writeOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
expect(sut(definition)).toEqual(expected)
})
it("returns object with writeonly fields for parameter, with includeWriteOnly", function () {
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<id>0</id>\n\t<dog>string</dog>\n</animals>"
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
dog: {
writeOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
expect(sut(definition, { includeWriteOnly: true })).toEqual(expected)
})
it("returns object with passed property as attribute", function () { it("returns object with passed property as attribute", function () {
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals id=\"0\">\n\t<dog>string</dog>\n</animals>" var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals id=\"0\">\n\t<dog>string</dog>\n</animals>"
var definition = { var definition = {