diff --git a/packages/api-explorer/__tests__/ResponseSchema.test.jsx b/packages/api-explorer/__tests__/ResponseSchema.test.jsx
index 79084cca1..44f39cd12 100644
--- a/packages/api-explorer/__tests__/ResponseSchema.test.jsx
+++ b/packages/api-explorer/__tests__/ResponseSchema.test.jsx
@@ -93,55 +93,10 @@ test('should not contain ResponseSchemaBody element if $ref not exist', () => {
oas,
};
const responseSchema = shallow();
- expect(responseSchema.find('table').length).toBe(0);
-});
-
-test('should show "string" response type', () => {
- const testProps = {
- operation: oas.operation('/user/login', 'get'),
- oas,
- };
-
- const responseSchema = shallow();
- expect(
- responseSchema
- .find('p span')
- .last()
- .text(),
- ).toBe('string');
-});
-
-test('should show "object" response schema type', () => {
- const testProps = {
- operation: oas.operation('/store/inventory', 'get'),
- oas,
- };
-
- const responseSchema = shallow();
- expect(
- responseSchema
- .find('p span')
- .last()
- .text(),
- ).toBe('object');
-});
-
-test('should show "array" response schema type', () => {
- const testProps = {
- operation: oas.operation('/pet/findByTags', 'get'),
- oas,
- };
-
- const responseSchema = shallow();
- expect(
- responseSchema
- .find('p span')
- .last()
- .text(),
- ).toBe('array of objects');
+ expect(responseSchema.find('ResponseSchemaBody').length).toBe(0);
});
-test('should render schema type from "application/json"', () => {
+test('should render schema from "application/json"', () => {
const testProps = {
operation: new Operation(
{},
@@ -166,12 +121,7 @@ test('should render schema type from "application/json"', () => {
};
const responseSchema = shallow();
- expect(
- responseSchema
- .find('p span')
- .last()
- .text(),
- ).toBe('string');
+ expect(responseSchema.find('ResponseSchemaBody').length).toBe(1);
});
test('should contain ResponseSchemaBody element if $ref exist for "application/xml"', () => {
@@ -206,7 +156,6 @@ test('should change selectedStatus in component', () => {
const responseSchema = shallow();
const selectedStatus = responseSchema.state().selectedStatus;
- // const selectedStatus = responseSchema.instance().selectedStatus
responseSchema.instance().changeHandler({ target: { value: '404' } });
const newSelectedStatus = responseSchema.state().selectedStatus;
@@ -214,45 +163,6 @@ test('should change selectedStatus in component', () => {
expect(newSelectedStatus).toEqual('404');
});
-test('should show "object" response schema type for "application/xml" content', () => {
- const testProps = {
- operation: new Operation(
- {},
- '/',
- 'get',
- Object.assign({}, oas.operation('/pet/findByTags', 'get'), {
- responses: {
- '200': {
- content: {
- 'application/xml': {
- description: 'successful operation',
- schema: {
- type: 'object',
- properties: {
- code: {
- type: 'integer',
- format: 'int32',
- },
- },
- },
- },
- },
- },
- },
- }),
- ),
- oas,
- };
-
- const responseSchema = shallow();
- expect(
- responseSchema
- .find('p span')
- .last()
- .text(),
- ).toBe('object');
-});
-
test('should not break if schema property missing', () => {
const testProps = {
operation: new Operation(
diff --git a/packages/api-explorer/__tests__/ResponseSchemaBody.test.jsx b/packages/api-explorer/__tests__/ResponseSchemaBody.test.jsx
index a677f8d84..b90f1af59 100644
--- a/packages/api-explorer/__tests__/ResponseSchemaBody.test.jsx
+++ b/packages/api-explorer/__tests__/ResponseSchemaBody.test.jsx
@@ -3,6 +3,7 @@ const { shallow, mount } = require('enzyme');
const ResponseSchemaBody = require('../src/ResponseSchemaBody');
const flattenResponseSchema = require('../src/ResponseSchemaBody').flattenResponseSchema;
+const flatten = require('../src/ResponseSchemaBody').flatten;
const Oas = require('../src/lib/Oas');
const petstore = require('./fixtures/petstore/oas.json');
@@ -19,8 +20,8 @@ test('display object properties in the table', () => {
};
const responseSchemaBody = shallow();
- expect(responseSchemaBody.find('th').text()).toContain('a');
- expect(responseSchemaBody.find('td').text()).toEqual('string');
+ expect(responseSchemaBody.find('th').text()).toContain('String');
+ expect(responseSchemaBody.find('td').text()).toEqual('a');
});
test('display properties if object contains $ref type', () => {
@@ -41,13 +42,13 @@ test('display properties if object contains $ref type', () => {
const responseSchemaBody = shallow();
expect(
responseSchemaBody
- .find('th')
+ .find('td')
.map(a => a.text())
.filter(a => a === 'category.name').length,
).toBe(1);
});
-test('should flatten array ', () => {
+test('should flatten schema to an array', () => {
const responseSchema = {
type: 'object',
properties: {
@@ -55,7 +56,6 @@ test('should flatten array ', () => {
type: 'array',
items: {
type: 'string',
- properties: null,
},
},
},
@@ -63,7 +63,7 @@ test('should flatten array ', () => {
expect(flattenResponseSchema(responseSchema)).toEqual([
{
name: 'category',
- type: 'array of strings',
+ type: '[String]',
description: undefined,
},
]);
@@ -86,7 +86,7 @@ test('display object properties inside another object in the table', () => {
const responseSchemaBody = shallow();
expect(
responseSchemaBody
- .find('th')
+ .find('td')
.map(a => a.text())
.filter(a => a === 'a.a').length,
).toBe(1);
@@ -126,15 +126,15 @@ test('display $ref items inside object', () => {
const responseSchemaBody = shallow();
expect(
responseSchemaBody
- .find('td')
+ .find('th')
.map(a => a.text())
- .filter(a => a === 'array of objects').length,
+ .filter(a => a === '[Object]').length,
).toBe(1);
expect(
responseSchemaBody
- .find('th')
+ .find('td')
.map(a => a.text())
- .filter(a => a === '| | index').length,
+ .filter(a => a === 'a.pets[].index').length,
).toBe(1);
});
@@ -177,15 +177,15 @@ test('render top level array of $ref', () => {
const responseSchemaBody = shallow();
expect(
responseSchemaBody
- .find('th')
+ .find('td')
.map(a => a.text())
.filter(a => a === 'name').length,
).toBe(1);
expect(
responseSchemaBody
- .find('td')
+ .find('th')
.map(a => a.text())
- .filter(a => a === 'string').length,
+ .filter(a => a === 'String').length,
).toBe(1);
});
@@ -217,13 +217,13 @@ test('not render more than 3 level deep object', () => {
const responseSchemaBody = shallow();
expect(
responseSchemaBody
- .find('th')
+ .find('td')
.map(a => a.text())
.filter(a => a === 'a.a.a').length,
).toBe(1);
expect(
responseSchemaBody
- .find('th')
+ .find('td')
.map(a => a.text())
.filter(a => a === 'a.a.a.a').length,
).toBe(0);
@@ -246,15 +246,15 @@ test('render top level array of objects', () => {
const responseSchemaBody = shallow();
expect(
responseSchemaBody
- .find('th')
+ .find('td')
.map(a => a.text())
.filter(a => a === 'name').length,
).toBe(1);
expect(
responseSchemaBody
- .find('td')
+ .find('th')
.map(a => a.text())
- .filter(a => a === 'string').length,
+ .filter(a => a === 'String').length,
).toBe(1);
});
@@ -275,3 +275,67 @@ test('should render markdown in the description', () => {
'Description',
);
});
+
+test('should show "string" response type', () => {
+ const schema = {
+ type: 'string',
+ };
+
+ const responseSchemaBody = mount();
+
+ expect(
+ responseSchemaBody
+ .find('p span')
+ .last()
+ .text(),
+ ).toBe('string');
+});
+
+test('should show "string" response type', () => {
+ const schema = {
+ type: 'object',
+ properties: {
+ items: {
+ type: 'string',
+ },
+ },
+ };
+
+ const responseSchemaBody = mount();
+
+ expect(
+ responseSchemaBody
+ .find('p span')
+ .last()
+ .text(),
+ ).toBe('object');
+});
+
+test('should show "array" response schema type', () => {
+ const schema = {
+ type: 'array',
+ items: {
+ type: 'object',
+ properties: {
+ name: {
+ type: 'string',
+ example: 'doggie',
+ },
+ },
+ },
+ };
+
+ const responseSchemaBody = mount();
+
+ expect(
+ responseSchemaBody
+ .find('p span')
+ .last()
+ .text(),
+ ).toBe('array of objects');
+});
+
+test('should flatten array ', () => {
+ const array = [[1], [2, 3], [[4, 5]]];
+ expect(flatten(array)).toEqual([1, 2, 3, 4, 5]);
+});
diff --git a/packages/api-explorer/api-explorer.css b/packages/api-explorer/api-explorer.css
index bff528e2b..4f5d2125d 100644
--- a/packages/api-explorer/api-explorer.css
+++ b/packages/api-explorer/api-explorer.css
@@ -466,3 +466,8 @@ form.rjsf fieldset {
float: right;
margin-right: 3%;
}*/
+
+.response-schema{
+ overflow-y: auto;
+ max-height: 600px;
+}
diff --git a/packages/api-explorer/src/ResponseSchema.jsx b/packages/api-explorer/src/ResponseSchema.jsx
index 138525887..b26ad7442 100644
--- a/packages/api-explorer/src/ResponseSchema.jsx
+++ b/packages/api-explorer/src/ResponseSchema.jsx
@@ -7,16 +7,6 @@ const ResponseSchemaBody = require('./ResponseSchemaBody');
const { Operation } = Oas;
-function getSchemaType(schema) {
- if (schema.type !== 'array') {
- return schema.type;
- }
- if (schema.items.$ref) {
- return 'array of objects';
- }
- return `array of ${schema.items.type}s`;
-}
-
class ResponseSchema extends React.Component {
constructor(props) {
super(props);
@@ -28,37 +18,34 @@ class ResponseSchema extends React.Component {
}
getSchema(operation) {
- if (!this.validateOperation(operation)) return null;
+ const content = this.getContent(operation);
+
+ if (!content) return null;
- const content = operation.responses[this.state.selectedStatus].content;
const oas = this.props.oas;
if (
- content['application/json'] &&
- content['application/json'].schema &&
- content['application/json'].schema.$ref
+ (content['application/json'] || content['application/xml']) &&
+ (content['application/json'] || content['application/xml']).schema &&
+ (content['application/json'] || content['application/xml']).schema.$ref
) {
- return findSchemaDefinition(content['application/json'].schema.$ref, oas);
+ return findSchemaDefinition(
+ (content['application/json'] || content['application/xml']).schema.$ref,
+ oas,
+ );
}
+
if (
- content['application/xml'] &&
- content['application/xml'].schema &&
- content['application/xml'].schema.$ref
+ (content['application/xml'] || content['application/json']) &&
+ (content['application/xml'] || content['application/json']).schema
) {
- return findSchemaDefinition(content['application/xml'].schema.$ref, oas);
- }
- if (content['application/xml'] && content['application/xml'].schema) {
- return content['application/xml'].schema;
- }
-
- if (content['application/json'] && content['application/json'].schema) {
- return content['application/json'].schema;
+ return (content['application/xml'] || content['application/json']).schema;
}
return null;
}
- validateOperation(operation) {
+ getContent(operation) {
const status = this.state.selectedStatus;
return (
operation &&
@@ -106,17 +93,10 @@ class ResponseSchema extends React.Component {
return (
{this.renderHeader()}
-
+
{operation.responses[this.state.selectedStatus].description && (
{operation.responses[this.state.selectedStatus].description}
)}
- {schema &&
- schema.type && (
-
- {`Response schema type: `}
- {getSchemaType(schema)}
-
- )}
{schema &&
}
diff --git a/packages/api-explorer/src/ResponseSchemaBody.jsx b/packages/api-explorer/src/ResponseSchemaBody.jsx
index b2c8e1b18..477a5e532 100644
--- a/packages/api-explorer/src/ResponseSchemaBody.jsx
+++ b/packages/api-explorer/src/ResponseSchemaBody.jsx
@@ -11,26 +11,20 @@ const getName = (parent, prop) => {
return `${parent}.${prop}`;
};
-function flattenResponseSchema(obj, oas, parent = '', level = 0) {
- const prefix = new Array(level + 2).join('| ');
- if (level > 2) {
- return [];
- }
+const capitalizeFirstLetter = string => (string || '').charAt(0).toUpperCase() + string.slice(1);
- // top level array
- if (obj.type === 'array' && obj.items) {
- if (obj.items.$ref) {
- const value = findSchemaDefinition(obj.items.$ref, oas);
- return flattenResponseSchema(value, oas);
- }
-
- return flattenResponseSchema(obj.items, oas);
+function getSchemaType(schema) {
+ if (schema.type !== 'array') {
+ return schema.type;
}
-
- if (obj && !obj.properties) {
- return [];
+ if (schema.items.$ref) {
+ return 'array of objects';
}
+ return `array of ${schema.items.type}s`;
+}
+/* eslint-disable no-use-before-define */
+function flattenObject(obj, parent, level, oas) {
return flatten(
Object.keys(obj.properties).map(prop => {
let value = obj.properties[prop];
@@ -44,47 +38,98 @@ function flattenResponseSchema(obj, oas, parent = '', level = 0) {
}
if (value.type === 'array' && value.items) {
- if (value.items.$ref) {
- value.items = findSchemaDefinition(value.items.$ref, oas);
+ let items = value.items;
+ if (items.$ref) {
+ items = findSchemaDefinition(items.$ref, oas);
}
- if (value.items.type) {
+ if (items.type) {
array.push({
name: getName(parent, prop),
- type: `array of ${value.items.type}s`,
+ type: `[${capitalizeFirstLetter(items.type)}]`,
description: value.description,
});
}
- if (value.items.type === 'object') {
- array.push(flattenResponseSchema(value.items, oas, `${prefix}`, level + 1));
+ const newParent = parent ? `${parent}.` : '';
+ if (items.type === 'object') {
+ array.push(flattenResponseSchema(items, oas, `${newParent}${prop}[]`, level + 1));
}
return array;
}
array.unshift({
name: getName(parent, prop),
- type: value.type,
+ type: capitalizeFirstLetter(value.type),
description: value.description,
});
return array;
}),
);
}
+/* eslint-enable no-use-before-define */
+
+function flattenResponseSchema(obj, oas, parent = '', level = 0) {
+ if (level > 2) {
+ return [];
+ }
+ let newParent;
+ // top level array
+ if (obj.type === 'array' && obj.items) {
+ if (obj.items.$ref) {
+ const value = findSchemaDefinition(obj.items.$ref, oas);
+ return flattenResponseSchema(value, oas);
+ }
+ newParent = parent ? `${parent}.[]` : '';
+ return flattenResponseSchema(obj.items, oas, `${newParent}`, level + 1);
+ }
+
+ if (obj && !obj.properties) {
+ return [];
+ }
+
+ return flattenObject(obj, parent, level, oas);
+}
function ResponseSchemaBody({ schema, oas }) {
- const rows = flattenResponseSchema(schema, oas).map(row => (
-
- {row.name} |
-
+ const rows = flatten(flattenResponseSchema(schema, oas)).map(row => (
+ |
+
{row.type}
+ |
+
+ {row.name}
{row.description && marked(row.description)}
|
));
return (
-
+
+ {schema &&
+ schema.type && (
+
+ {`Response schema type: `}
+ {getSchemaType(schema)}
+
+ )}
+
+
);
}