Skip to content

Commit

Permalink
fix(editor): pick correct media type on parameter parsing (#215)
Browse files Browse the repository at this point in the history
closes #214
  • Loading branch information
ostridm authored Sep 21, 2023
1 parent 18888f0 commit aead75c
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 7 deletions.
42 changes: 35 additions & 7 deletions packages/editor/src/editor/oas/v2/OasV2ParameterObjectsParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export class OasV2ParameterObjectsParser extends BaseOasParameterObjectsParser<
OpenAPIV2.Document,
OpenAPIV2.ReferenceObject | OpenAPIV2.Parameter
> {
private readonly DEFAULT_CONSUME_MEDIA_TYPE: OpenAPIV2.MimeTypes = [
'application/json'
];

constructor(doc: OpenAPIV2.Document, dereferencedDoc: OpenAPIV2.Document) {
super(doc, dereferencedDoc);
}
Expand Down Expand Up @@ -73,14 +77,38 @@ export class OasV2ParameterObjectsParser extends BaseOasParameterObjectsParser<
this.dereferencedDoc,
jsonPointer.compile(jsonPointer.parse(pointer).slice(0, -2))
);
const mimeTypes = operationObject.consumes || ['application/json'];

if ('$ref' in parameter.schema) {
parameter = jsonPointer.get(this.dereferencedDoc, pointer);
}

const value = parameter.schema?.default;

return mimeTypes.map((mimeType) => ({
paramType: 'requestBody',
bodyType: mimeType,
...(value != null ? { value } : {}),
valueJsonPointer: this.getValueJsonPointer(`${pointer}/schema`)
}));
return this.resolveOperationConsumeMediaTypes(operationObject).map(
(mediaType) => ({
paramType: 'requestBody',
bodyType: mediaType,
...(value != null ? { value } : {}),
valueJsonPointer: this.getValueJsonPointer(`${pointer}/schema`)
})
);
}

private resolveOperationConsumeMediaTypes(
operation: OpenAPIV2.OperationObject
): OpenAPIV2.MimeTypes {
let mediaTypes: OpenAPIV2.MimeTypes;

if (operation.consumes?.length) {
mediaTypes = operation.consumes;
} else if (this.doc.consumes?.length) {
mediaTypes = this.doc.consumes;
}

mediaTypes = mediaTypes
?.map((mediaType) => mediaType?.trim())
.filter(Boolean);

return mediaTypes?.length ? mediaTypes : this.DEFAULT_CONSUME_MEDIA_TYPE;
}
}
36 changes: 36 additions & 0 deletions packages/editor/tests/fixtures/oas2-missing-consumes.result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"children": [
{
"children": [
{
"jsonPointer": "/paths/~1pet/post",
"method": "POST",
"parameters": [
{
"bodyType": "application/json",
"paramType": "requestBody",
"value": {
"name": "Jack"
},
"valueJsonPointer": "/paths/~1pet/post/parameters/0/schema/default"
}
],
"path": "/pet"
}
],
"jsonPointer": "/paths/~1pet",
"path": "/pet"
}
],
"jsonPointer": "/",
"name": "Swagger Petstore",
"parameters": [
{
"name": "host",
"paramType": "variable",
"value": "petstore.swagger.io",
"valueJsonPointer": "/host"
}
],
"path": "/"
}
32 changes: 32 additions & 0 deletions packages/editor/tests/fixtures/oas2-missing-consumes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
swagger: '2.0'
info:
title: Swagger Petstore
version: 1.0.0
host: petstore.swagger.io
basePath: /v2
schemes:
- https
paths:
/pet:
post:
parameters:
- in: body
name: body
schema:
$ref: '#/definitions/Pet'
responses:
200:
description: successful operation
definitions:
Pet:
properties:
name:
example: doggie
type: string
required:
- name
type: object
xml:
name: Pet
default:
name: Jack
59 changes: 59 additions & 0 deletions packages/editor/tests/fixtures/oas2-override-consumes.result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"children": [
{
"children": [
{
"jsonPointer": "/paths/~1pet/post",
"method": "POST",
"parameters": [
{
"bodyType": "application/x-www-form-urlencoded",
"paramType": "requestBody",
"value": {
"name": "Jack"
},
"valueJsonPointer": "/paths/~1pet/post/parameters/0/schema/default"
},
{
"bodyType": "multipart/form-data",
"paramType": "requestBody",
"value": {
"name": "Jack"
},
"valueJsonPointer": "/paths/~1pet/post/parameters/0/schema/default"
}
],
"path": "/pet"
},
{
"jsonPointer": "/paths/~1pet/put",
"method": "PUT",
"parameters": [
{
"bodyType": "application/json",
"paramType": "requestBody",
"value": {
"name": "Jack"
},
"valueJsonPointer": "/paths/~1pet/put/parameters/0/schema/default"
}
],
"path": "/pet"
}
],
"jsonPointer": "/paths/~1pet",
"path": "/pet"
}
],
"jsonPointer": "/",
"name": "Swagger Petstore",
"parameters": [
{
"name": "host",
"paramType": "variable",
"value": "petstore.swagger.io",
"valueJsonPointer": "/host"
}
],
"path": "/"
}
49 changes: 49 additions & 0 deletions packages/editor/tests/fixtures/oas2-override-consumes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
swagger: '2.0'
info:
title: Swagger Petstore
version: 1.0.0
host: petstore.swagger.io
basePath: /v2
schemes:
- https
consumes:
- application/xml
paths:
/pet:
post:
consumes:
- application/x-www-form-urlencoded
- multipart/form-data
parameters:
- in: body
name: body
schema:
$ref: '#/definitions/Pet'
responses:
200:
description: successful operation
put:
consumes:
-
parameters:
- in: body
name: body
schema:
$ref: '#/definitions/Pet'
responses:
200:
description: successful operation
definitions:
Pet:
properties:
name:
example: doggie
type: string
required:
- name
type: object
xml:
name: Pet
default:
name: Jack

27 changes: 27 additions & 0 deletions packages/editor/tests/oas2.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,33 @@ describe('OasV2Editor', () => {
expect(result).toEqual(expected);
});

it.each([
{
testCase: 'operation and root consumes nodes are missing',
input: 'oas2-missing-consumes.yaml',
expected: 'oas2-missing-consumes.result.json'
},
{
testCase: 'operation consumes overrides root consumes node',
input: 'oas2-override-consumes.yaml',
expected: 'oas2-override-consumes.result.json'
}
])('should pick media type when $testCase', async ({ input, expected }) => {
const sourceYaml = readFileSync(
resolve(__dirname, `./fixtures/${input}`),
'utf-8'
);
await openApiParser.setup(sourceYaml);

const expectedJson = JSON.parse(
readFileSync(resolve(__dirname, `./fixtures/${expected}`), 'utf-8')
);

const result = openApiParser.parse();

expect(result).toEqual(expectedJson);
});

it('should be exception on call "parse" before "setup"', () =>
expect(() => openApiParser.parse()).toThrowError(
'You have to call "setup" to initialize the document'
Expand Down

0 comments on commit aead75c

Please sign in to comment.