@@ -78,7 +104,6 @@ export default class Responses extends React.Component {
{
responses.entrySeq().map( ([code, response]) => {
-
let className = tryItOutResponse && tryItOutResponse.get("status") == code ? "response_current" : ""
return (
)
diff --git a/src/core/plugins/oas3/actions.js b/src/core/plugins/oas3/actions.js
index 4a5bf9ac..ad81f3e7 100644
--- a/src/core/plugins/oas3/actions.js
+++ b/src/core/plugins/oas3/actions.js
@@ -4,6 +4,7 @@
export const UPDATE_SELECTED_SERVER = "oas3_set_servers"
export const UPDATE_REQUEST_BODY_VALUE = "oas3_set_request_body_value"
export const UPDATE_REQUEST_CONTENT_TYPE = "oas3_set_request_content_type"
+export const UPDATE_RESPONSE_CONTENT_TYPE = "oas3_set_response_content_type"
export const UPDATE_SERVER_VARIABLE_VALUE = "oas3_set_server_variable_value"
export function setSelectedServer (selectedServerUrl) {
@@ -27,6 +28,13 @@ export function setRequestContentType ({ value, pathMethod }) {
}
}
+export function setResponseContentType ({ value, pathMethod }) {
+ return {
+ type: UPDATE_RESPONSE_CONTENT_TYPE,
+ payload: { value, pathMethod }
+ }
+}
+
export function setServerVariableValue ({ server, key, val }) {
return {
type: UPDATE_SERVER_VARIABLE_VALUE,
diff --git a/src/core/plugins/oas3/reducers.js b/src/core/plugins/oas3/reducers.js
index 810c1ba0..149f55e3 100644
--- a/src/core/plugins/oas3/reducers.js
+++ b/src/core/plugins/oas3/reducers.js
@@ -2,7 +2,8 @@ import {
UPDATE_SELECTED_SERVER,
UPDATE_REQUEST_BODY_VALUE,
UPDATE_REQUEST_CONTENT_TYPE,
- UPDATE_SERVER_VARIABLE_VALUE
+ UPDATE_SERVER_VARIABLE_VALUE,
+ UPDATE_RESPONSE_CONTENT_TYPE
} from "./actions"
export default {
@@ -17,6 +18,10 @@ export default {
let [path, method] = pathMethod
return state.setIn( [ "requestData", path, method, "requestContentType" ], value)
},
+ [UPDATE_RESPONSE_CONTENT_TYPE]: (state, { payload: { value, pathMethod } } ) =>{
+ let [path, method] = pathMethod
+ return state.setIn( [ "requestData", path, method, "responseContentType" ], value)
+ },
[UPDATE_SERVER_VARIABLE_VALUE]: (state, { payload: { server, key, val } } ) =>{
return state.setIn( [ "serverVariableValues", server, key ], val)
},
diff --git a/src/core/plugins/oas3/selectors.js b/src/core/plugins/oas3/selectors.js
index a6c57761..86fc617f 100644
--- a/src/core/plugins/oas3/selectors.js
+++ b/src/core/plugins/oas3/selectors.js
@@ -30,6 +30,11 @@ export const requestContentType = onlyOAS3((state, path, method) => {
}
)
+export const responseContentType = onlyOAS3((state, path, method) => {
+ return state.getIn(["requestData", path, method, "responseContentType"]) || null
+ }
+)
+
export const serverVariableValue = onlyOAS3((state, server, key) => {
return state.getIn(["serverVariableValues", server, key]) || null
}
diff --git a/src/core/plugins/spec/actions.js b/src/core/plugins/spec/actions.js
index 7465574c..98919880 100644
--- a/src/core/plugins/spec/actions.js
+++ b/src/core/plugins/spec/actions.js
@@ -218,6 +218,7 @@ export const executeRequest = (req) =>
req.server = oas3Selectors.selectedServer()
req.serverVariables = oas3Selectors.serverVariables(req.server).toJS()
req.requestContentType = oas3Selectors.requestContentType(pathName, method)
+ req.responseContentType = oas3Selectors.responseContentType(pathName, method) || "*/*"
const requestBody = oas3Selectors.requestBodyValue(pathName, method)
if(isJSONObject(requestBody)) {
diff --git a/src/core/utils.js b/src/core/utils.js
index b64b29cf..1a835d3f 100644
--- a/src/core/utils.js
+++ b/src/core/utils.js
@@ -652,5 +652,28 @@ export const shallowEqualKeys = (a,b, keys) => {
})
}
+export function getAcceptControllingResponse(responses) {
+ if(!Im.OrderedMap.isOrderedMap(responses)) {
+ // wrong type!
+ return null
+ }
+
+ if(!responses.size) {
+ // responses is empty
+ return null
+ }
+
+ const suitable2xxResponse = responses.find((res, k) => {
+ return k.startsWith("2") && Object.keys(res.get("content") || {}).length > 0
+ })
+
+ // try to find a suitable `default` responses
+ const defaultResponse = responses.get("default") || Im.OrderedMap()
+ const defaultResponseMediaTypes = (defaultResponse.get("content") || Im.OrderedMap()).keySeq().toJS()
+ const suitableDefaultResponse = defaultResponseMediaTypes.length ? defaultResponse : null
+
+ return suitable2xxResponse || suitableDefaultResponse
+}
+
export const createDeepLinkPath = (str) => typeof str == "string" || str instanceof String ? str.trim().replace(/\s/g, "_") : ""
-export const escapeDeepLinkPath = (str) => cssEscape( createDeepLinkPath(str) )
\ No newline at end of file
+export const escapeDeepLinkPath = (str) => cssEscape( createDeepLinkPath(str) )
diff --git a/src/style/_layout.scss b/src/style/_layout.scss
index edb21360..d070c96c 100644
--- a/src/style/_layout.scss
+++ b/src/style/_layout.scss
@@ -775,6 +775,17 @@
.response-content-type {
padding-top: 1em;
+
+ &.controls-accept-header {
+ select {
+ border-color: green;
+ }
+
+ small {
+ color: green;
+ font-size: .7em;
+ }
+ }
}
@keyframes blinker
diff --git a/test/core/utils.js b/test/core/utils.js
index c9921ef7..b4be6c1b 100644
--- a/test/core/utils.js
+++ b/test/core/utils.js
@@ -1,7 +1,7 @@
/* eslint-env mocha */
import expect from "expect"
-import { fromJS } from "immutable"
-import { mapToList, validateNumber, validateInteger, validateParam, validateFile, fromJSOrdered, createDeepLinkPath, escapeDeepLinkPath } from "core/utils"
+import { fromJS, OrderedMap } from "immutable"
+import { mapToList, validateNumber, validateInteger, validateParam, validateFile, fromJSOrdered, getAcceptControllingResponse, createDeepLinkPath, escapeDeepLinkPath } from "core/utils"
import win from "core/window"
describe("utils", function() {
@@ -583,6 +583,103 @@ describe("utils", function() {
})
})
+ describe.only("getAcceptControllingResponse", () => {
+ it("should return the first 2xx response with a media type", () => {
+ const responses = fromJSOrdered({
+ "200": {
+ content: {
+ "application/json": {
+ schema: {
+ type: "object"
+ }
+ }
+ }
+ },
+ "201": {
+ content: {
+ "application/json": {
+ schema: {
+ type: "object"
+ }
+ }
+ }
+ }
+ })
+
+ expect(getAcceptControllingResponse(responses)).toEqual(responses.get("200"))
+ })
+ it("should skip 2xx responses without defined media types", () => {
+ const responses = fromJSOrdered({
+ "200": {
+ content: {
+ "application/json": {
+ schema: {
+ type: "object"
+ }
+ }
+ }
+ },
+ "201": {
+ content: {
+ "application/json": {
+ schema: {
+ type: "object"
+ }
+ }
+ }
+ }
+ })
+
+ expect(getAcceptControllingResponse(responses)).toEqual(responses.get("201"))
+ })
+ it("should default to the `default` response if it has defined media types", () => {
+ const responses = fromJSOrdered({
+ "200": {
+ description: "quite empty"
+ },
+ "201": {
+ description: "quite empty"
+ },
+ default: {
+ content: {
+ "application/json": {
+ schema: {
+ type: "object"
+ }
+ }
+ }
+ }
+ })
+
+ expect(getAcceptControllingResponse(responses)).toEqual(responses.get("default"))
+ })
+ it("should return null if there are no suitable controlling responses", () => {
+ const responses = fromJSOrdered({
+ "200": {
+ description: "quite empty"
+ },
+ "201": {
+ description: "quite empty"
+ },
+ "default": {
+ description: "also empty.."
+ }
+ })
+
+ expect(getAcceptControllingResponse(responses)).toBe(null)
+ })
+ it("should return null if an empty OrderedMap is passed", () => {
+ const responses = fromJSOrdered()
+
+ expect(getAcceptControllingResponse(responses)).toBe(null)
+ })
+ it("should return null if anything except an OrderedMap is passed", () => {
+ const responses = {}
+
+ expect(getAcceptControllingResponse(responses)).toBe(null)
+ })
+ })
+
describe("createDeepLinkPath", function() {
it("creates a deep link path replacing spaces with underscores", function() {
const result = createDeepLinkPath("tag id with spaces")