Skip to content

Commit 8b5176a

Browse files
committed
fix(reference): fix bug in reference predicate logic
Refs swagger-api/oss-planning#133
1 parent 8168986 commit 8b5176a

File tree

6 files changed

+189
-6
lines changed

6 files changed

+189
-6
lines changed

apidom/packages/apidom-reference/src/resolve-strategies/openapi-3-1/reference-objects/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ const ReferenceObjectsResolveStrategy: stampit.Stamp<IResolveStrategy> = stampit
9393
return [
9494
'application/vnd.oai.openapi;version=3.1.0',
9595
'application/vnd.oai.openapi+json;version=3.1.0',
96+
'application/vnd.oai.openapi+yaml;version=3.1.0',
9697
].includes(file.mediaType);
9798
};
9899

apidom/packages/apidom-reference/src/resolve-strategies/openapi-3-1/reference-objects/predicates.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { startsWith } from 'ramda';
2+
import { isNonEmptyString } from 'ramda-adjunct';
23
import { isStringElement, isObjectElement } from 'apidom';
34
import { isReferenceElement } from 'apidom-ns-openapi-3-1';
45

@@ -16,7 +17,9 @@ export const isExternalReferenceElement = (element: any): boolean => {
1617
return false;
1718
}
1819

19-
return !startsWith('#', $refElement.toValue());
20+
const value = $refElement.toValue();
21+
22+
return isNonEmptyString(value) && !startsWith('#', value);
2023
};
2124

2225
/**

apidom/packages/apidom-reference/test/index.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { assert } from 'chai';
22
import { isParseResultElement } from 'apidom';
33
import path from 'path';
44

5-
import { parse, resolve } from '../src';
5+
import { parse, resolve, resolveApiDOM } from '../src';
66

77
describe('apidom-reference', function () {
88
context('parse', function () {
@@ -38,4 +38,19 @@ describe('apidom-reference', function () {
3838
});
3939
});
4040
});
41+
42+
context('resolveApiDOM', function () {
43+
context('given ApiDOM data', function () {
44+
specify('should resolve ApiDOM', async function () {
45+
const uri = path.join(__dirname, 'fixtures', 'resolve', 'sample-openapi-3-1-api.json');
46+
const options = {
47+
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
48+
};
49+
const parseResult = await parse(uri, options);
50+
const refSet = await resolveApiDOM(parseResult, options);
51+
52+
assert.strictEqual(refSet.size, 1);
53+
});
54+
});
55+
});
4156
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# stream comment
2+
---
3+
openapi: 3.1.0
4+
x-top-level: value
5+
info:
6+
title: Sample API
7+
unknownFixedField: value
8+
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/)
9+
or HTML.
10+
summary: example summary
11+
termsOfService: Terms of service
12+
version: 0.1.9
13+
x-version: 0.1.9-beta
14+
license:
15+
name: Apache License 2.0
16+
x-fullName: Apache License 2.0
17+
identifier: Apache License 2.0
18+
url: https://www.apache.org/licenses/LICENSE-2.0
19+
contact:
20+
name: Vladimir Gorej
21+
x-username: char0n
22+
url: https://www.linkedin.com/in/vladimirgorej/
23+
24+
servers:
25+
- url: http://api.example.com/v1
26+
description: Optional server description, e.g. Main (production) server
27+
- url: http:{port}//staging-api.example.com
28+
description: Optional server description, e.g. Internal staging server for testing
29+
variables:
30+
port:
31+
enum:
32+
- 8443
33+
- 443
34+
default: 8443
35+
description: Port description
36+
components:
37+
x-extension: value
38+
schemas:
39+
x-model:
40+
type: object
41+
properties:
42+
id:
43+
type: integer
44+
User:
45+
type: object
46+
properties:
47+
id:
48+
type: integer
49+
name:
50+
type: string
51+
profile:
52+
$ref: #/components/schemas/UserProfile
53+
UserProfile:
54+
type: object
55+
properties:
56+
email:
57+
type: string
58+
x-nullable: true
59+
parameters:
60+
userId:
61+
$ref: #/components/parameters/userIdRef
62+
userIdRef:
63+
name: userId,
64+
in: query,
65+
description: ID of the user,
66+
required: true
67+
security:
68+
- {}
69+
- petstore_auth:
70+
- write:pets
71+
- read:pets
72+
paths:
73+
/users:
74+
summary: path item summary
75+
description: path item description
76+
get:
77+
tags:
78+
- tag1
79+
- tag2
80+
summary: Returns a list of users.
81+
description: Optional extended description in CommonMark or HTML.
82+
externalDocs:
83+
description: Find more info here
84+
url: https://example.com
85+
operationId: getUserList
86+
parameters:
87+
- "$ref": #/components/parameters/userId
88+
requestBody:
89+
content: {}
90+
responses:
91+
200:
92+
description: A JSON array of user names
93+
content:
94+
application/json:
95+
schema:
96+
type: array
97+
items:
98+
type: string
99+
201:
100+
description: A response
101+
content:
102+
application/json:
103+
schema:
104+
$ref: #/components/schemas/User
105+
xxx:
106+
key: val
107+
callbacks:
108+
myCallback:
109+
'{$request.query.queryUrl}':
110+
post:
111+
requestBody:
112+
description: Callback payload
113+
content:
114+
application/json:
115+
schema:
116+
$ref: #/components/schemas/User
117+
responses:
118+
200:
119+
description: callback successfully processed
120+
deprecated: true
121+
security:
122+
- {}
123+
- petstore_auth:
124+
- write:pets
125+
- read:pets
126+
servers:
127+
- url: http://api.example.com/v3
128+
description: Redundant server description, e.g. redundant server
129+
servers:
130+
- url: http://api.example.com/v2
131+
description: Redundant server description, e.g. redundant server
132+
parameters:
133+
- name: userId
134+
in: query
135+
description: ID of the user
136+
required: true
137+
...
138+
prop: value

apidom/packages/apidom-reference/test/resolve-strategies/openapi-3-1/index.ts

+25
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,31 @@ describe('resolve-strategies', function () {
256256
});
257257
});
258258
});
259+
260+
context('given YAML OpenApi 3.1.x document with no external reference', function () {
261+
let rootFile: IFile;
262+
let refSet: IReferenceSet;
263+
264+
beforeEach(async function () {
265+
const uri = path.join(__dirname, 'fixtures', 'sample-api.yaml');
266+
const mediaType = 'application/vnd.oai.openapi+yaml;version=3.1.0';
267+
const data = fs.readFileSync(uri);
268+
const parseResult = await parse(uri, { parse: { mediaType } });
269+
270+
rootFile = File({ uri, mediaType, data, parseResult });
271+
refSet = await strategy.resolve(rootFile, defaultOptions);
272+
});
273+
274+
specify('should have 1 reference in reference set', async function () {
275+
assert.strictEqual(refSet.size, 1);
276+
});
277+
278+
specify('should have root reference set to baseURI', async function () {
279+
const { rootRef } = refSet;
280+
281+
assert.strictEqual(rootRef.uri, rootFile.uri);
282+
});
283+
});
259284
});
260285
});
261286
});

apidom/packages/apidom-reference/test/resolvers/HttpResolverAxios.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ describe('resolvers', function () {
7878

7979
specify('should throw on timeout', async function () {
8080
resolver = HttpResolverAxios({ timeout: 1 });
81+
axiosInstance = resolver.getHttpClient();
82+
axiosMock = new MockAdapter(resolver.getHttpClient());
8183
const url = 'https://httpbin.org/anything';
8284

8385
axiosMock.onGet(url).timeout();
@@ -108,18 +110,17 @@ describe('resolvers', function () {
108110
});
109111

110112
context('given withCredentials option', function () {
111-
specify('should allow cross-site Access-Control requests', function (done) {
113+
specify('should allow cross-site Access-Control requests', async function () {
112114
resolver = HttpResolverAxios({ withCredentials: true });
113115
axiosInstance = resolver.getHttpClient();
114116
axiosMock = new MockAdapter(axiosInstance);
115117
const url = 'https://httpbin.org/anything';
116118

117119
axiosMock.onGet(url).reply((config: AxiosRequestConfig) => {
118120
assert.isTrue(config.withCredentials);
119-
done();
120-
return [200];
121+
return [200, Buffer.from('data')];
121122
});
122-
resolver.read(File({ uri: url }));
123+
await resolver.read(File({ uri: url }));
123124
});
124125
});
125126

0 commit comments

Comments
 (0)