* implement a selector for consumes options * fix incorrect comment, test names * add `consumesOptionsFor` selector * use `consumesOptionsFor` and drop `operationConsumes`bubble
@@ -83,7 +83,6 @@ export default class Operation extends PureComponent { | |||
let operation = operationProps.getIn(["op"]) | |||
let responses = operation.get("responses") | |||
let produces = operation.get("produces") | |||
let parameters = getList(operation, ["parameters"]) | |||
let operationScheme = specSelectors.operationScheme(path, method) | |||
let isShownKey = ["operations", tag, operationId] | |||
@@ -216,7 +215,7 @@ export default class Operation extends PureComponent { | |||
specSelectors={ specSelectors } | |||
oas3Actions={oas3Actions} | |||
specActions={ specActions } | |||
produces={ produces } | |||
produces={specSelectors.producesOptionsFor([path, method]) } | |||
producesValue={ specSelectors.currentProducesFor([path, method]) } | |||
specPath={specPath.push("responses")} | |||
path={ path } | |||
@@ -129,7 +129,7 @@ export default class ParameterRow extends Component { | |||
: <ParamBody getComponent={getComponent} | |||
fn={fn} | |||
param={param} | |||
consumes={ specSelectors.operationConsumes(pathMethod) } | |||
consumes={ specSelectors.consumesOptionsFor(pathMethod) } | |||
consumesValue={ specSelectors.contentTypeValues(pathMethod).get("requestContentType") } | |||
onChange={this.onChangeWrapper} | |||
onChangeConsumes={onChangeConsumes} | |||
@@ -401,12 +401,6 @@ export function contentTypeValues(state, pathMethod) { | |||
}) | |||
} | |||
// Get the consumes/produces by path | |||
export function operationConsumes(state, pathMethod) { | |||
pathMethod = pathMethod || [] | |||
return specJsonWithResolvedSubtrees(state).getIn(["paths", ...pathMethod, "consumes"], fromJS({})) | |||
} | |||
// Get the currently selected produces value for an operation | |||
export function currentProducesFor(state, pathMethod) { | |||
pathMethod = pathMethod || [] | |||
@@ -425,6 +419,48 @@ export function currentProducesFor(state, pathMethod) { | |||
} | |||
// Get the produces options for an operation | |||
export function producesOptionsFor(state, pathMethod) { | |||
pathMethod = pathMethod || [] | |||
const spec = specJsonWithResolvedSubtrees(state) | |||
const operation = spec.getIn([ "paths", ...pathMethod], null) | |||
if(operation === null) { | |||
// return nothing if the operation does not exist | |||
return | |||
} | |||
const [path] = pathMethod | |||
const operationProduces = operation.get("produces", null) | |||
const pathItemProduces = spec.getIn(["paths", path, "produces"], null) | |||
const globalProduces = spec.getIn(["produces"], null) | |||
return operationProduces || pathItemProduces || globalProduces | |||
} | |||
// Get the consumes options for an operation | |||
export function consumesOptionsFor(state, pathMethod) { | |||
pathMethod = pathMethod || [] | |||
const spec = specJsonWithResolvedSubtrees(state) | |||
const operation = spec.getIn(["paths", ...pathMethod], null) | |||
if (operation === null) { | |||
// return nothing if the operation does not exist | |||
return | |||
} | |||
const [path] = pathMethod | |||
const operationConsumes = operation.get("consumes", null) | |||
const pathItemConsumes = spec.getIn(["paths", path, "consumes"], null) | |||
const globalConsumes = spec.getIn(["consumes"], null) | |||
return operationConsumes || pathItemConsumes || globalConsumes | |||
} | |||
export const operationScheme = ( state, path, method ) => { | |||
let url = state.get("url") | |||
let matchResult = url.match(/^([a-z][a-z0-9+\-.]*):/) | |||
@@ -7,7 +7,7 @@ import { | |||
contentTypeValues, | |||
operationScheme, | |||
specJsonWithResolvedSubtrees, | |||
operationConsumes | |||
producesOptionsFor, | |||
} from "corePlugins/spec/selectors" | |||
import Petstore from "./assets/petstore.json" | |||
@@ -15,7 +15,8 @@ import { | |||
operationWithMeta, | |||
parameterWithMeta, | |||
parameterWithMetaByIdentity, | |||
parameterInclusionSettingFor | |||
parameterInclusionSettingFor, | |||
consumesOptionsFor | |||
} from "../../../../src/core/plugins/spec/selectors" | |||
describe("spec plugin - selectors", function(){ | |||
@@ -253,34 +254,6 @@ describe("spec plugin - selectors", function(){ | |||
}) | |||
describe("operationConsumes", function(){ | |||
it("should return the operationConsumes for an operation", function(){ | |||
// Given | |||
let state = fromJS({ | |||
json: { | |||
paths: { | |||
"/one": { | |||
get: { | |||
consumes: [ | |||
"application/xml", | |||
"application/something-else" | |||
] | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
// When | |||
let contentTypes = operationConsumes(state, [ "/one", "get" ]) | |||
// Then | |||
expect(contentTypes.toJS()).toEqual([ | |||
"application/xml", | |||
"application/something-else" | |||
]) | |||
}) | |||
}) | |||
describe("operationScheme", function(){ | |||
it("should return the correct scheme for a remote spec that doesn't specify a scheme", function(){ | |||
@@ -751,4 +724,264 @@ describe("spec plugin - selectors", function(){ | |||
expect(result).toEqual(true) | |||
}) | |||
}) | |||
describe("producesOptionsFor", function() { | |||
it("should return an operation produces value", function () { | |||
const state = fromJS({ | |||
json: { | |||
paths: { | |||
"/": { | |||
"get": { | |||
description: "my operation", | |||
produces: [ | |||
"operation/one", | |||
"operation/two", | |||
] | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
const result = producesOptionsFor(state, ["/", "get"]) | |||
expect(result.toJS()).toEqual([ | |||
"operation/one", | |||
"operation/two", | |||
]) | |||
}) | |||
it("should return a path item produces value", function () { | |||
const state = fromJS({ | |||
json: { | |||
paths: { | |||
"/": { | |||
"get": { | |||
description: "my operation", | |||
produces: [ | |||
"path-item/one", | |||
"path-item/two", | |||
] | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
const result = producesOptionsFor(state, ["/", "get"]) | |||
expect(result.toJS()).toEqual([ | |||
"path-item/one", | |||
"path-item/two", | |||
]) | |||
}) | |||
it("should return a global produces value", function () { | |||
const state = fromJS({ | |||
json: { | |||
produces: [ | |||
"global/one", | |||
"global/two", | |||
], | |||
paths: { | |||
"/": { | |||
"get": { | |||
description: "my operation" | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
const result = producesOptionsFor(state, ["/", "get"]) | |||
expect(result.toJS()).toEqual([ | |||
"global/one", | |||
"global/two", | |||
]) | |||
}) | |||
it("should favor an operation produces value over a path-item value", function () { | |||
const state = fromJS({ | |||
json: { | |||
paths: { | |||
"/": { | |||
produces: [ | |||
"path-item/one", | |||
"path-item/two", | |||
], | |||
"get": { | |||
description: "my operation", | |||
produces: [ | |||
"operation/one", | |||
"operation/two", | |||
] | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
const result = producesOptionsFor(state, ["/", "get"]) | |||
expect(result.toJS()).toEqual([ | |||
"operation/one", | |||
"operation/two", | |||
]) | |||
}) | |||
it("should favor a path-item produces value over a global value", function () { | |||
const state = fromJS({ | |||
json: { | |||
produces: [ | |||
"global/one", | |||
"global/two", | |||
], | |||
paths: { | |||
"/": { | |||
produces: [ | |||
"path-item/one", | |||
"path-item/two", | |||
], | |||
"get": { | |||
description: "my operation" | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
const result = producesOptionsFor(state, ["/", "get"]) | |||
expect(result.toJS()).toEqual([ | |||
"path-item/one", | |||
"path-item/two", | |||
]) | |||
}) | |||
}) | |||
describe("consumesOptionsFor", function() { | |||
it("should return an operation consumes value", function () { | |||
const state = fromJS({ | |||
json: { | |||
paths: { | |||
"/": { | |||
"get": { | |||
description: "my operation", | |||
consumes: [ | |||
"operation/one", | |||
"operation/two", | |||
] | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
const result = consumesOptionsFor(state, ["/", "get"]) | |||
expect(result.toJS()).toEqual([ | |||
"operation/one", | |||
"operation/two", | |||
]) | |||
}) | |||
it("should return a path item consumes value", function () { | |||
const state = fromJS({ | |||
json: { | |||
paths: { | |||
"/": { | |||
"get": { | |||
description: "my operation", | |||
consumes: [ | |||
"path-item/one", | |||
"path-item/two", | |||
] | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
const result = consumesOptionsFor(state, ["/", "get"]) | |||
expect(result.toJS()).toEqual([ | |||
"path-item/one", | |||
"path-item/two", | |||
]) | |||
}) | |||
it("should return a global consumes value", function () { | |||
const state = fromJS({ | |||
json: { | |||
consumes: [ | |||
"global/one", | |||
"global/two", | |||
], | |||
paths: { | |||
"/": { | |||
"get": { | |||
description: "my operation" | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
const result = consumesOptionsFor(state, ["/", "get"]) | |||
expect(result.toJS()).toEqual([ | |||
"global/one", | |||
"global/two", | |||
]) | |||
}) | |||
it("should favor an operation consumes value over a path-item value", function () { | |||
const state = fromJS({ | |||
json: { | |||
paths: { | |||
"/": { | |||
consumes: [ | |||
"path-item/one", | |||
"path-item/two", | |||
], | |||
"get": { | |||
description: "my operation", | |||
consumes: [ | |||
"operation/one", | |||
"operation/two", | |||
] | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
const result = consumesOptionsFor(state, ["/", "get"]) | |||
expect(result.toJS()).toEqual([ | |||
"operation/one", | |||
"operation/two", | |||
]) | |||
}) | |||
it("should favor a path-item consumes value over a global value", function () { | |||
const state = fromJS({ | |||
json: { | |||
consumes: [ | |||
"global/one", | |||
"global/two", | |||
], | |||
paths: { | |||
"/": { | |||
consumes: [ | |||
"path-item/one", | |||
"path-item/two", | |||
], | |||
"get": { | |||
description: "my operation" | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
const result = consumesOptionsFor(state, ["/", "get"]) | |||
expect(result.toJS()).toEqual([ | |||
"path-item/one", | |||
"path-item/two", | |||
]) | |||
}) | |||
}) | |||
}) |
@@ -0,0 +1,17 @@ | |||
--- | |||
paths: | |||
findByStatus: | |||
get: | |||
tags: | |||
- "pet" | |||
summary: "Finds Pets by status" | |||
description: "Multiple status values can be provided with comma separated strings" | |||
operationId: "findPetsByStatus" | |||
parameters: | |||
- name: "status" | |||
in: "body" | |||
schema: | |||
type: string | |||
responses: | |||
200: | |||
description: ok |
@@ -0,0 +1,44 @@ | |||
swagger: "2.0" | |||
info: | |||
description: "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters." | |||
version: "1.0.0" | |||
title: "Swagger Petstore" | |||
termsOfService: "http://swagger.io/terms/" | |||
contact: | |||
email: "apiteam@swagger.io" | |||
license: | |||
name: "Apache 2.0" | |||
url: "http://www.apache.org/licenses/LICENSE-2.0.html" | |||
host: "petstore.swagger.io" | |||
basePath: "/v2" | |||
produces: | |||
- application/json | |||
- application/xml | |||
- text/csv | |||
consumes: | |||
- application/json | |||
- application/xml | |||
- text/csv | |||
schemes: | |||
- "https" | |||
- "http" | |||
paths: | |||
/pet: | |||
post: | |||
tags: | |||
- "pet" | |||
summary: "Add a new pet to the store" | |||
description: "" | |||
operationId: "addPet" | |||
parameters: | |||
- in: "body" | |||
name: "body" | |||
description: "Pet object that needs to be added to the store" | |||
required: true | |||
schema: | |||
$ref: "#/definitions/Pet" | |||
responses: | |||
405: | |||
description: "Invalid input" | |||
/pet/findByStatus: | |||
$ref: "status.yaml#/paths/findByStatus" |
@@ -0,0 +1,32 @@ | |||
import repeat from "lodash/repeat" | |||
describe("#5043: path-level $ref path items should inherit global consumes/produces", () => { | |||
it("should render consumes options correctly", () => { | |||
cy | |||
.visit("/?url=/documents/bugs/5043/swagger.yaml") | |||
.get("#operations-pet-findPetsByStatus") | |||
.click() | |||
.get(".try-out__btn") | |||
.click() | |||
.get(".content-type") | |||
.contains("application/json") | |||
.get(".content-type") | |||
.contains("application/xml") | |||
.get(".content-type") | |||
.contains("text/csv") | |||
}) | |||
it("should render produces options correctly", () => { | |||
cy | |||
.visit("/?url=/documents/bugs/5043/swagger.yaml") | |||
.get("#operations-pet-findPetsByStatus") | |||
.click() | |||
.get(".try-out__btn") | |||
.click() | |||
.get(".body-param-content-type select") | |||
.contains("application/json") | |||
.get(".body-param-content-type select") | |||
.contains("application/xml") | |||
.get(".body-param-content-type select") | |||
.contains("text/csv") | |||
}) | |||
}) |