Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
Provide a first pass at a json data type
Browse files Browse the repository at this point in the history
Still broken:
- type says 'string'
- textarea needs styling
- need to confirm it works with explorer disabled
  • Loading branch information
Dom Harrington committed Aug 14, 2018
1 parent 013e469 commit ed42e99
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 4 deletions.
29 changes: 29 additions & 0 deletions packages/api-explorer/__tests__/Params.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const Description = require('../src/form-components/DescriptionField');
const createParams = require('../src/Params');

const Oas = require('../src/lib/Oas');
const { Operation } = Oas;
const petstore = require('./fixtures/petstore/oas.json');

const oas = new Oas(petstore);
Expand Down Expand Up @@ -60,6 +61,34 @@ test('boolean should render as <select>', () => {
expect(select.find('option').map(el => el.text())).toEqual(['', 'true', 'false']);
});

test('json should render as <textarea>', () => {
const jsonOperation = new Operation(oas, '/path', 'post', {
requestBody: {
content: {
'application/json': {
schema: {
type: 'object',
required: ['a'],
properties: {
a: {
type: 'json',
},
},
},
},
},
},
});

const params = mount(
<div>
<Params {...props} operation={jsonOperation} />
</div>,
);

expect(params.find('textarea').length).toBe(1);
});

describe('x-explorer-enabled', () => {
const oasWithExplorerDisabled = Object.assign({}, oas, { [extensions.EXPLORER_ENABLED]: false });
const ParamsWithExplorerDisabled = createParams(oasWithExplorerDisabled);
Expand Down
86 changes: 86 additions & 0 deletions packages/api-explorer/__tests__/lib/oas-to-har.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,92 @@ describe('body values', () => {
).log.entries[0].request.postData.text,
).toEqual(JSON.stringify(true));
});

describe('`json` type', () => {
it('should work for refs that require a lookup', () => {
expect(
oasToHar(
{
components: {
requestBodies: {
schema: {
content: {
'application/json': {
schema: { type: 'object', properties: { a: { type: 'json' } } },
},
},
},
},
},
},
{
path: '/body',
method: 'get',
requestBody: {
$ref: '#/components/requestBodies/schema',
},
},
{ body: { a: '{ "b": 1 }' } },
).log.entries[0].request.postData.text,
).toEqual(JSON.stringify({ a: JSON.parse('{ "b": 1 }') }));
});

it('should leave invalid JSON as strings', () => {
expect(
oasToHar(
{},
{
path: '/body',
method: 'post',
requestBody: {
content: {
'application/json': {
schema: {
type: 'object',
required: ['a'],
properties: {
a: {
type: 'json',
},
},
},
},
},
},
},
{ body: { a: '{ "b": invalid json' } },
).log.entries[0].request.postData.text,
).toEqual(JSON.stringify({ a: '{ "b": invalid json' }));
});

it('should parse valid JSON as an object', () => {
expect(
oasToHar(
{},
{
path: '/body',
method: 'post',
requestBody: {
content: {
'application/json': {
schema: {
type: 'object',
required: ['a'],
properties: {
a: {
type: 'json',
},
},
},
},
},
},
},
{ body: { a: '{ "b": "valid json" }' } },
).log.entries[0].request.postData.text,
).toEqual(JSON.stringify({ a: JSON.parse('{ "b": "valid json" }') }));
});
});
});

describe('formData values', () => {
Expand Down
2 changes: 2 additions & 0 deletions packages/api-explorer/src/Params.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Form = require('react-jsonschema-form').default;
const UpDownWidget = require('react-jsonschema-form/lib/components/widgets/UpDownWidget').default;
const TextWidget = require('react-jsonschema-form/lib/components/widgets/TextWidget').default;
const FileWidget = require('react-jsonschema-form/lib/components/widgets/FileWidget').default;
const TextAreaWidget = require('react-jsonschema-form/lib/components/widgets/TextAreaWidget').default;
const DateTimeWidget = require('react-jsonschema-form/lib/components/widgets/DateTimeWidget')
.default;

Expand Down Expand Up @@ -56,6 +57,7 @@ function Params({
integer: UpDownWidget,
BaseInput,
SelectWidget,
json: TextAreaWidget,
}}
onSubmit={onSubmit}
formData={formData[schema.type]}
Expand Down
3 changes: 3 additions & 0 deletions packages/api-explorer/src/form-components/SchemaField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const BaseSchemaField = require('react-jsonschema-form/lib/components/fields/Sch

function createSchemaField() {
function SchemaField(props) {
if (props.schema.type === 'json') {
return <BaseSchemaField {...props} schema={Object.assign({}, props.schema, { type: 'string' })} uiSchema={{ 'ui:widget': 'json' }} />;
}
if (props.schema.type === 'boolean') {
props.schema.enumNames = ['true', 'false'];
return <BaseSchemaField {...props} uiSchema={{ 'ui:widget': 'select' }} />;
Expand Down
23 changes: 19 additions & 4 deletions packages/api-explorer/src/lib/oas-to-har.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,30 @@ module.exports = (

const schema = getSchema(pathOperation, oas) || { schema: {} };

function stringify(json) {
// Default to JSON.stringify
har.postData.text = JSON.stringify(
typeof json.RAW_BODY !== 'undefined' ? json.RAW_BODY : json,
);
}

if (schema.schema && Object.keys(schema.schema).length) {
// If there is formData, then the type is application/x-www-form-urlencoded
if (Object.keys(formData.formData).length) {
har.postData.text = querystring.stringify(formData.formData);
} else if (isPrimitive(formData.body) || Object.keys(formData.body).length) {
// Default to JSON.stringify
har.postData.text = JSON.stringify(
typeof formData.body.RAW_BODY !== 'undefined' ? formData.body.RAW_BODY : formData.body,
);
try {
const jsonTypes = Object.keys(schema.schema.properties).filter(key => schema.schema.properties[key].type === 'json');
if (jsonTypes.length) {
const cloned = JSON.parse(JSON.stringify(formData.body));
jsonTypes.forEach(prop => {
cloned[prop] = JSON.parse(cloned[prop]);
});
stringify(cloned);
} else stringify(formData.body);
} catch (e) {
stringify(formData.body);
}
}
}

Expand Down

0 comments on commit ed42e99

Please sign in to comment.