Skip to content

Commit 8e33d85

Browse files
authored
fix: don't throw an error when there is a property named content of the type array (#198)
1 parent d91880a commit 8e33d85

File tree

6 files changed

+101
-5
lines changed

6 files changed

+101
-5
lines changed

src/impl/v2/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const cloneDeep = require('lodash.clonedeep'),
88

99
// CONSTANTS
1010

11-
const PATH__EXAMPLES = '$..examples[?(@property.match(/[\/+]json/))]',
11+
const PATH__EXAMPLES = '$..examples[?(@property && typeof @property === "string" && @property.match(/[\/+]json/))]',
1212
PROP__SCHEMA = 'schema',
1313
PROP__EXAMPLES = 'examples';
1414

src/impl/v3/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ const cloneDeep = require('lodash.clonedeep'),
99

1010
// CONSTANTS
1111

12-
const RESPONSES = '$..responses..content[?(@property.match(/[\/+]json/))]';
13-
const REQUEST = '$..requestBody.content[?(@property.match(/[\/+]json/))]';
12+
// eslint-disable-next-line max-len
13+
const RESPONSES = '$..responses..content[?(@property && typeof @property === "string" && @property.match(/[\/+]json/))]';
14+
const REQUEST = '$..requestBody.content[?(@property && typeof @property === "string" && @property.match(/[\/+]json/))]';
1415
const SINGLE_EXAMPLE = '.example';
1516
const MANY_EXAMPLES = '.examples.*.value';
1617

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
swagger: '2.0'
2+
info:
3+
title: API
4+
version: 1.0.0
5+
paths:
6+
/metrics:
7+
get:
8+
summary: Get info
9+
operationId: get_info
10+
description: |
11+
This API hook returns server metrics.
12+
produces:
13+
- application/json
14+
responses:
15+
200:
16+
description: OK
17+
schema:
18+
type: object
19+
properties:
20+
examples:
21+
type: array
22+
description: Array of valid entries
23+
items:
24+
type: object
25+
properties:
26+
type:
27+
type: integer
28+
description: RR type of entry
29+
examples:
30+
application/json:
31+
examples:
32+
- type: 0
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
openapi: 3.0.2
2+
components:
3+
paths:
4+
metrics:
5+
get:
6+
summary: Get info
7+
operationId: "get_info"
8+
description: |
9+
This API hook returns server metrics.
10+
responses:
11+
'200':
12+
description: OK
13+
content:
14+
application/json:
15+
schema:
16+
type: object
17+
properties:
18+
content:
19+
type: array
20+
description: Array of valid entries
21+
items:
22+
type: object
23+
properties:
24+
type:
25+
type: integer
26+
description: RR type of entry
27+
examples:
28+
metrics:
29+
summary: Server metrics
30+
value:
31+
content:
32+
- type: 0

test/specs/impl/v2/index.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const path = require('path'),
44
{ validateExample, 'default': validateExamples, validateExamplesByMap } = require('../../../../src/index'),
55
{ ApplicationError, ErrorType } = require('../../../../src/application-error');
66
const { prepare } = require('../../../../src/impl/v2');
7+
const { validateFile } = require('../../../../src');
78

89
const PATH__SCHEMA_EXTERNAL_EXAMPLE = '$.paths./.get.responses.200.schema',
910
PATH__SCHEMA_EXTERNAL_EXAMPLE_INVALID = '$.hmm.what.am.i.gonna.get.for.lunch',
@@ -27,7 +28,9 @@ const PATH__SCHEMA_EXTERNAL_EXAMPLE = '$.paths./.get.responses.200.schema',
2728
FILE_PATH__NOT_EXISTS = 'there is no spoon',
2829
FILE_PATH__EXTERNAL_EXAMPLE_INVALID_TYPE = path.join('test', 'data', 'v2', 'external-examples-invalid-type.json'),
2930
FILE_PATH__EXTERNAL_EXAMPLE_INVALID_MISSING_LINK = path.join('test', 'data', 'v2',
30-
'external-examples-invalid-missing-link.json');
31+
'external-examples-invalid-missing-link.json'),
32+
FILE_PATH__VALID__RESPONSE__EXAMPLES_CONTENT_ARRAY
33+
= path.join(__dirname, '../../../data/v2/response-valid-content-array.yaml');
3134

3235
describe('Main-module, for v2 should', () => {
3336
describe('recognize', () => {
@@ -421,6 +424,19 @@ describe('Main-module, for v2 should', () => {
421424
preparedOpenapi.should.deep.equal(loadTestData('v2/valid-with-all-properties-required'));
422425
});
423426
});
427+
describe('handle elements named "content" which are Arrays', function() {
428+
it('should validate successfully', async function() {
429+
const { valid, statistics } = structuredClone(
430+
await validateFile(FILE_PATH__VALID__RESPONSE__EXAMPLES_CONTENT_ARRAY)
431+
);
432+
valid.should.equal(true);
433+
statistics.should.deep.equal({
434+
schemasWithExamples: 1,
435+
examplesWithoutSchema: 0,
436+
examplesTotal: 1
437+
});
438+
});
439+
});
424440
});
425441

426442
function removeMapFilePath(errors) {

test/specs/impl/v3/index.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ const JSON_PATH__CONTEXT_MUTUALLY_EXCLUSIVE = '/paths/~1pets/get/responses/200/c
8080
= path.join(__dirname, '../../../data/v3/simple-api-with-examples-exclusive-minimum-invalid.json'),
8181
FILE_PATH__EXAMPLE_NAMES_TO_BE_ESCAPED
8282
= path.join(__dirname, '../../../data/v3/simple-api-with-example-names-to-be-escaped.json'),
83-
FILE_PATH__UNKNOWN_FORMATS = path.join(__dirname, '../../../data/v3/unknown-formats.json');
83+
FILE_PATH__UNKNOWN_FORMATS = path.join(__dirname, '../../../data/v3/unknown-formats.json'),
84+
FILE_PATH__VALID__RESPONSE__EXAMPLES_CONTENT_ARRAY
85+
= path.join(__dirname, '../../../data/v3/response-valid-content-array.yaml');
8486

8587
describe('Main-module, for v3 should', function() {
8688
describe('recognize', function() {
@@ -514,6 +516,19 @@ unknown format "country-code-2" ignored in schema at path "#/properties/country"
514516
})).valid.should.equal(true);
515517
});
516518
});
519+
describe('handle elements named "content" which are Arrays', function() {
520+
it('should validate successfully', async function() {
521+
const { valid, statistics } = structuredClone(
522+
await validateFile(FILE_PATH__VALID__RESPONSE__EXAMPLES_CONTENT_ARRAY)
523+
);
524+
valid.should.equal(true);
525+
statistics.should.deep.equal({
526+
schemasWithExamples: 1,
527+
examplesWithoutSchema: 0,
528+
examplesTotal: 1
529+
});
530+
});
531+
});
517532
});
518533

519534
function _expandFilePathOfErrors(errors, propertyName) {

0 commit comments

Comments
 (0)