fix: streamline management of user-selected produces and consumes values (#4137)
* Remove produces/consumes setter from OperationContainer * Store consumes/produces information in `meta` key * Migrate produces value state usage to `meta` key * use meta consumes data for isXml check * Fix failing tests * normalize action name casing * restore correct produces fallback value logic
This commit is contained in:
@@ -248,7 +248,7 @@ export default class Operation extends PureComponent {
|
|||||||
oas3Actions={oas3Actions}
|
oas3Actions={oas3Actions}
|
||||||
specActions={ specActions }
|
specActions={ specActions }
|
||||||
produces={ produces }
|
produces={ produces }
|
||||||
producesValue={ operation.get("produces_value") }
|
producesValue={ specSelectors.currentProducesFor([path, method]) }
|
||||||
specPath={specPath.push("responses")}
|
specPath={specPath.push("responses")}
|
||||||
path={ path }
|
path={ path }
|
||||||
method={ method }
|
method={ method }
|
||||||
|
|||||||
@@ -82,27 +82,9 @@ export default class OperationContainer extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
const defaultContentType = "application/json"
|
|
||||||
let { specActions, path, method, op } = nextProps
|
|
||||||
let operation = op.get("operation")
|
|
||||||
let producesValue = operation.get("produces_value")
|
|
||||||
let produces = operation.get("produces")
|
|
||||||
let consumes = operation.get("consumes")
|
|
||||||
let consumesValue = operation.get("consumes_value")
|
|
||||||
|
|
||||||
if(nextProps.response !== this.props.response) {
|
if(nextProps.response !== this.props.response) {
|
||||||
this.setState({ executeInProgress: false })
|
this.setState({ executeInProgress: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (producesValue === undefined) {
|
|
||||||
producesValue = produces && produces.size ? produces.first() : defaultContentType
|
|
||||||
specActions.changeProducesValue([path, method], producesValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumesValue === undefined) {
|
|
||||||
consumesValue = consumes && consumes.size ? consumes.first() : defaultContentType
|
|
||||||
specActions.changeConsumesValue([path, method], consumesValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleShown =() => {
|
toggleShown =() => {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const LOG_REQUEST = "spec_log_request"
|
|||||||
export const CLEAR_RESPONSE = "spec_clear_response"
|
export const CLEAR_RESPONSE = "spec_clear_response"
|
||||||
export const CLEAR_REQUEST = "spec_clear_request"
|
export const CLEAR_REQUEST = "spec_clear_request"
|
||||||
export const CLEAR_VALIDATE_PARAMS = "spec_clear_validate_param"
|
export const CLEAR_VALIDATE_PARAMS = "spec_clear_validate_param"
|
||||||
export const UPDATE_OPERATION_VALUE = "spec_update_operation_value"
|
export const UPDATE_OPERATION_META_VALUE = "spec_update_operation_meta_value"
|
||||||
export const UPDATE_RESOLVED = "spec_update_resolved"
|
export const UPDATE_RESOLVED = "spec_update_resolved"
|
||||||
export const SET_SCHEME = "set_scheme"
|
export const SET_SCHEME = "set_scheme"
|
||||||
|
|
||||||
@@ -150,14 +150,14 @@ export function clearValidateParams( payload ){
|
|||||||
|
|
||||||
export function changeConsumesValue(path, value) {
|
export function changeConsumesValue(path, value) {
|
||||||
return {
|
return {
|
||||||
type: UPDATE_OPERATION_VALUE,
|
type: UPDATE_OPERATION_META_VALUE,
|
||||||
payload:{ path, value, key: "consumes_value" }
|
payload:{ path, value, key: "consumes_value" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function changeProducesValue(path, value) {
|
export function changeProducesValue(path, value) {
|
||||||
return {
|
return {
|
||||||
type: UPDATE_OPERATION_VALUE,
|
type: UPDATE_OPERATION_META_VALUE,
|
||||||
payload:{ path, value, key: "produces_value" }
|
payload:{ path, value, key: "produces_value" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
SET_REQUEST,
|
SET_REQUEST,
|
||||||
SET_MUTATED_REQUEST,
|
SET_MUTATED_REQUEST,
|
||||||
UPDATE_RESOLVED,
|
UPDATE_RESOLVED,
|
||||||
UPDATE_OPERATION_VALUE,
|
UPDATE_OPERATION_META_VALUE,
|
||||||
CLEAR_RESPONSE,
|
CLEAR_RESPONSE,
|
||||||
CLEAR_REQUEST,
|
CLEAR_REQUEST,
|
||||||
CLEAR_VALIDATE_PARAMS,
|
CLEAR_VALIDATE_PARAMS,
|
||||||
@@ -52,8 +52,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
[VALIDATE_PARAMS]: ( state, { payload: { pathMethod, isOAS3 } } ) => {
|
[VALIDATE_PARAMS]: ( state, { payload: { pathMethod, isOAS3 } } ) => {
|
||||||
let operation = state.getIn( [ "resolved", "paths", ...pathMethod ] )
|
let meta = state.getIn( [ "meta", "paths", ...pathMethod ] )
|
||||||
let isXml = /xml/i.test(operation.get("consumes_value"))
|
let isXml = /xml/i.test(meta.get("consumes_value"))
|
||||||
|
|
||||||
return state.updateIn( [ "resolved", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => {
|
return state.updateIn( [ "resolved", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => {
|
||||||
return parameters.withMutations( parameters => {
|
return parameters.withMutations( parameters => {
|
||||||
@@ -107,12 +107,17 @@ export default {
|
|||||||
return state.setIn( [ "mutatedRequests", path, method ], fromJSOrdered(req))
|
return state.setIn( [ "mutatedRequests", path, method ], fromJSOrdered(req))
|
||||||
},
|
},
|
||||||
|
|
||||||
[UPDATE_OPERATION_VALUE]: (state, { payload: { path, value, key } }) => {
|
[UPDATE_OPERATION_META_VALUE]: (state, { payload: { path, value, key } }) => {
|
||||||
|
// path is a pathMethod tuple... can't change the name now.
|
||||||
let operationPath = ["resolved", "paths", ...path]
|
let operationPath = ["resolved", "paths", ...path]
|
||||||
|
let metaPath = ["meta", "paths", ...path]
|
||||||
|
|
||||||
if(!state.getIn(operationPath)) {
|
if(!state.getIn(operationPath)) {
|
||||||
|
// do nothing if the operation does not exist
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
return state.setIn([...operationPath, key], fromJS(value))
|
|
||||||
|
return state.setIn([...metaPath, key], fromJS(value))
|
||||||
},
|
},
|
||||||
|
|
||||||
[CLEAR_RESPONSE]: (state, { payload: { path, method } } ) =>{
|
[CLEAR_RESPONSE]: (state, { payload: { path, method } } ) =>{
|
||||||
|
|||||||
@@ -306,10 +306,13 @@ export function parametersIncludeType(parameters, typeValue="") {
|
|||||||
export function contentTypeValues(state, pathMethod) {
|
export function contentTypeValues(state, pathMethod) {
|
||||||
pathMethod = pathMethod || []
|
pathMethod = pathMethod || []
|
||||||
let op = spec(state).getIn(["paths", ...pathMethod], fromJS({}))
|
let op = spec(state).getIn(["paths", ...pathMethod], fromJS({}))
|
||||||
|
let meta = state.getIn(["meta", "paths", ...pathMethod], fromJS({}))
|
||||||
|
let producesValue = currentProducesFor(state, pathMethod)
|
||||||
|
|
||||||
const parameters = op.get("parameters") || new List()
|
const parameters = op.get("parameters") || new List()
|
||||||
|
|
||||||
const requestContentType = (
|
const requestContentType = (
|
||||||
op.get("consumes_value") ? op.get("consumes_value")
|
meta.get("consumes_value") ? meta.get("consumes_value")
|
||||||
: parametersIncludeType(parameters, "file") ? "multipart/form-data"
|
: parametersIncludeType(parameters, "file") ? "multipart/form-data"
|
||||||
: parametersIncludeType(parameters, "formData") ? "application/x-www-form-urlencoded"
|
: parametersIncludeType(parameters, "formData") ? "application/x-www-form-urlencoded"
|
||||||
: undefined
|
: undefined
|
||||||
@@ -317,7 +320,7 @@ export function contentTypeValues(state, pathMethod) {
|
|||||||
|
|
||||||
return fromJS({
|
return fromJS({
|
||||||
requestContentType,
|
requestContentType,
|
||||||
responseContentType: op.get("produces_value")
|
responseContentType: producesValue
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,6 +330,24 @@ export function operationConsumes(state, pathMethod) {
|
|||||||
return spec(state).getIn(["paths", ...pathMethod, "consumes"], fromJS({}))
|
return spec(state).getIn(["paths", ...pathMethod, "consumes"], fromJS({}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the currently selected produces value for an operation
|
||||||
|
export function currentProducesFor(state, pathMethod) {
|
||||||
|
pathMethod = pathMethod || []
|
||||||
|
|
||||||
|
const operation = spec(state).getIn(["paths", ...pathMethod], null)
|
||||||
|
|
||||||
|
if(operation === null) {
|
||||||
|
// return nothing if the operation does not exist
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentProducesValue = state.getIn(["meta", "paths", ...pathMethod, "produces_value"], null)
|
||||||
|
const firstProducesArrayItem = operation.getIn(["produces", 0], null)
|
||||||
|
|
||||||
|
return currentProducesValue || firstProducesArrayItem || "application/json"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export const operationScheme = ( state, path, method ) => {
|
export const operationScheme = ( state, path, method ) => {
|
||||||
let url = state.get("url")
|
let url = state.get("url")
|
||||||
let matchResult = url.match(/^([a-z][a-z0-9+\-.]*):/)
|
let matchResult = url.match(/^([a-z][a-z0-9+\-.]*):/)
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import reducer from "corePlugins/spec/reducers"
|
|||||||
|
|
||||||
describe("spec plugin - reducer", function(){
|
describe("spec plugin - reducer", function(){
|
||||||
|
|
||||||
describe("update operation value", function() {
|
describe("update operation meta value", function() {
|
||||||
it("should update the operation at the specified key", () => {
|
it("should update the operation metadata at the specified key", () => {
|
||||||
const updateOperationValue = reducer["spec_update_operation_value"]
|
const updateOperationValue = reducer["spec_update_operation_meta_value"]
|
||||||
|
|
||||||
const state = fromJS({
|
const state = fromJS({
|
||||||
resolved: {
|
resolved: {
|
||||||
@@ -34,7 +34,15 @@ describe("spec plugin - reducer", function(){
|
|||||||
"paths": {
|
"paths": {
|
||||||
"/pet": {
|
"/pet": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "my operation",
|
"description": "my operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
paths: {
|
||||||
|
"/pet": {
|
||||||
|
post: {
|
||||||
"consumes_value": "application/json"
|
"consumes_value": "application/json"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +54,7 @@ describe("spec plugin - reducer", function(){
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("shouldn't throw an error if we try to update the consumes_value of a null operation", () => {
|
it("shouldn't throw an error if we try to update the consumes_value of a null operation", () => {
|
||||||
const updateOperationValue = reducer["spec_update_operation_value"]
|
const updateOperationValue = reducer["spec_update_operation_meta_value"]
|
||||||
|
|
||||||
const state = fromJS({
|
const state = fromJS({
|
||||||
resolved: {
|
resolved: {
|
||||||
@@ -56,6 +56,13 @@ describe("spec plugin - selectors", function(){
|
|||||||
// Given
|
// Given
|
||||||
let state = fromJS({
|
let state = fromJS({
|
||||||
resolved: {
|
resolved: {
|
||||||
|
paths: {
|
||||||
|
"/one": {
|
||||||
|
get: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
paths: {
|
paths: {
|
||||||
"/one": {
|
"/one": {
|
||||||
get: {
|
get: {
|
||||||
@@ -76,6 +83,71 @@ describe("spec plugin - selectors", function(){
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should default to the first `produces` array value if current is not set", function(){
|
||||||
|
// Given
|
||||||
|
let state = fromJS({
|
||||||
|
resolved: {
|
||||||
|
paths: {
|
||||||
|
"/one": {
|
||||||
|
get: {
|
||||||
|
produces: [
|
||||||
|
"application/xml",
|
||||||
|
"application/whatever"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
paths: {
|
||||||
|
"/one": {
|
||||||
|
get: {
|
||||||
|
"consumes_value": "one"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
let contentTypes = contentTypeValues(state, [ "/one", "get" ])
|
||||||
|
// Then
|
||||||
|
expect(contentTypes.toJS()).toEqual({
|
||||||
|
requestContentType: "one",
|
||||||
|
responseContentType: "application/xml"
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should default to `application/json` if a default produces value is not available", function(){
|
||||||
|
// Given
|
||||||
|
let state = fromJS({
|
||||||
|
resolved: {
|
||||||
|
paths: {
|
||||||
|
"/one": {
|
||||||
|
get: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
paths: {
|
||||||
|
"/one": {
|
||||||
|
get: {
|
||||||
|
"consumes_value": "one"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
let contentTypes = contentTypeValues(state, [ "/one", "get" ])
|
||||||
|
// Then
|
||||||
|
expect(contentTypes.toJS()).toEqual({
|
||||||
|
requestContentType: "one",
|
||||||
|
responseContentType: "application/json"
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it("should prioritize consumes value first from an operation", function(){
|
it("should prioritize consumes value first from an operation", function(){
|
||||||
// Given
|
// Given
|
||||||
let state = fromJS({
|
let state = fromJS({
|
||||||
@@ -83,13 +155,21 @@ describe("spec plugin - selectors", function(){
|
|||||||
paths: {
|
paths: {
|
||||||
"/one": {
|
"/one": {
|
||||||
get: {
|
get: {
|
||||||
"consumes_value": "one",
|
"parameters": [{
|
||||||
"parameters": [{
|
|
||||||
"type": "file"
|
"type": "file"
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
paths: {
|
||||||
|
"/one": {
|
||||||
|
get: {
|
||||||
|
"consumes_value": "one",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -106,7 +186,7 @@ describe("spec plugin - selectors", function(){
|
|||||||
paths: {
|
paths: {
|
||||||
"/one": {
|
"/one": {
|
||||||
get: {
|
get: {
|
||||||
"parameters": [{
|
"parameters": [{
|
||||||
"type": "file"
|
"type": "file"
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
@@ -128,7 +208,7 @@ describe("spec plugin - selectors", function(){
|
|||||||
paths: {
|
paths: {
|
||||||
"/one": {
|
"/one": {
|
||||||
get: {
|
get: {
|
||||||
"parameters": [{
|
"parameters": [{
|
||||||
"type": "formData"
|
"type": "formData"
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
@@ -143,7 +223,7 @@ describe("spec plugin - selectors", function(){
|
|||||||
expect(contentTypes.toJS().requestContentType).toEqual("application/x-www-form-urlencoded")
|
expect(contentTypes.toJS().requestContentType).toEqual("application/x-www-form-urlencoded")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be ok, if no operation found", function(){
|
it("should return nothing, if the operation does not exist", function(){
|
||||||
// Given
|
// Given
|
||||||
let state = fromJS({ })
|
let state = fromJS({ })
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user