Skip to content

Commit 83667b8

Browse files
committed
added resolution of inline property allOf constructs per #459
1 parent 555555f commit 83667b8

File tree

4 files changed

+140
-19
lines changed

4 files changed

+140
-19
lines changed

lib/client.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ SwaggerClient.prototype.initialize = function (url, options) {
138138
this.progress = options.progress || function () {};
139139
this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document
140140

141+
if (options.scheme) {
142+
this.scheme = options.scheme;
143+
}
144+
141145
if (typeof options.success === 'function') {
142146
this.ready = true;
143147
this.build();
@@ -260,9 +264,9 @@ SwaggerClient.prototype.buildFromSpec = function (response) {
260264

261265
if (typeof this.url === 'string') {
262266
location = this.parseUri(this.url);
263-
if (typeof this.schemes === 'undefined' || this.schemes.length === 0) {
267+
if (typeof this.scheme === 'undefined' && typeof this.schemes === 'undefined' || this.schemes.length === 0) {
264268
this.scheme = location.scheme || 'http';
265-
} else {
269+
} else if (typeof this.scheme === 'undefined') {
266270
this.scheme = this.schemes[0];
267271
}
268272

@@ -278,7 +282,7 @@ SwaggerClient.prototype.buildFromSpec = function (response) {
278282
if (typeof this.schemes === 'undefined' || this.schemes.length === 0) {
279283
this.scheme = 'http';
280284
}
281-
else {
285+
else if (typeof this.scheme === 'undefined') {
282286
this.scheme = this.schemes[0];
283287
}
284288
}

lib/resolver.js

+25-15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,24 @@ var _ = {
1212
*/
1313
var Resolver = module.exports = function () {};
1414

15+
Resolver.prototype.processAllOf = function(name, definition, resolutionTable, unresolvedRefs, spec) {
16+
var i, location, property;
17+
18+
definition['x-resolved-from'] = [ '#/definitions/' + name ];
19+
var allOf = definition.allOf;
20+
// the refs go first
21+
allOf.sort(function(a, b) {
22+
if(a.$ref && b.$ref) { return 0; }
23+
else if(a.$ref) { return -1; }
24+
else { return 1; }
25+
});
26+
for (i = 0; i < allOf.length; i++) {
27+
property = allOf[i];
28+
location = '/definitions/' + name + '/allOf';
29+
this.resolveInline(null, spec, property, resolutionTable, unresolvedRefs, location);
30+
}
31+
}
32+
1533
Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) {
1634
var root = arg1, callback = arg2, scope = arg3, location, i;
1735
if(typeof arg1 === 'function') {
@@ -32,23 +50,16 @@ Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) {
3250
var definition = spec.definitions[name];
3351
for (propertyName in definition.properties) {
3452
property = definition.properties[propertyName];
35-
this.resolveTo(root, property, resolutionTable, '/definitions');
53+
if(_.isArray(property.allOf)) {
54+
this.processAllOf(name, property, resolutionTable, unresolvedRefs, spec);
55+
}
56+
else {
57+
this.resolveTo(root, property, resolutionTable, '/definitions');
58+
}
3659
}
3760

3861
if(definition.allOf) {
39-
definition['x-resolved-from'] = [ '#/definitions/' + name ];
40-
var allOf = definition.allOf;
41-
// the refs go first
42-
allOf.sort(function(a, b) {
43-
if(a.$ref && b.$ref) { return 0; }
44-
else if(a.$ref) { return -1; }
45-
else { return 1; }
46-
});
47-
for (i = 0; i < allOf.length; i++) {
48-
property = allOf[i];
49-
location = '/definitions/' + name + '/allOf';
50-
this.resolveInline(null, spec, property, resolutionTable, unresolvedRefs, location);
51-
}
62+
this.processAllOf(name, definition, resolutionTable, unresolvedRefs, spec);
5263
}
5364
}
5465

@@ -461,7 +472,6 @@ Resolver.prototype.resolveInline = function (root, spec, property, resolutionTab
461472

462473
Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) {
463474
var ref = property.$ref;
464-
465475
if (ref) {
466476
if(ref.indexOf('#') >= 0) {
467477
location = ref.split('#')[1];

test/auth.js

-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ describe('2.0 authorizations', function () {
180180
// Mock out the request, will only allow one request
181181
fauxjax.once('request', function (req) {
182182

183-
console.log('req', req);
184183
expect(req.requestHeaders).to.include.keys('auth');
185184
expect(req.requestHeaders.auth).to.equal('val');
186185

test/composition.js

+108
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,112 @@ describe('swagger resolver', function () {
227227
});
228228
});
229229

230+
it('resolves a model with a composed response array', function (done) {
231+
var api = new Resolver();
232+
var spec = {
233+
paths: {
234+
"/test": {
235+
get: {
236+
responses: {
237+
200: {
238+
schema: {
239+
type: "array",
240+
items: {
241+
$ref: "#/definitions/Response"
242+
}
243+
}
244+
}
245+
}
246+
}
247+
}
248+
},
249+
definitions: {
250+
Request: {
251+
properties: {
252+
name: {
253+
type: "string"
254+
}
255+
}
256+
},
257+
Response: {
258+
allOf: [
259+
{
260+
$ref: "#/definitions/Request"
261+
},
262+
{
263+
properties: {
264+
id: {
265+
description: "ID of entry",
266+
type: "integer"
267+
}
268+
}
269+
}
270+
]
271+
}
272+
}
273+
};
274+
275+
api.resolve(spec, 'http://localhost:8000/v2/petstore.json', function (spec, unresolved) {
276+
expect(Object.keys(unresolved).length).toBe(0);
277+
test.object(spec);
278+
done();
279+
});
280+
});
281+
282+
it('tests issue #459', function (done) {
283+
var api = new Resolver();
284+
var spec = {
285+
definitions: {
286+
new_model: {
287+
properties: {
288+
subclass: {
289+
allOf: [
290+
{
291+
$ref: "#/definitions/superclass"
292+
},
293+
{
294+
properties: {
295+
name: {
296+
type: "string"
297+
}
298+
}
299+
}
300+
]
301+
}
302+
}
303+
},
304+
superclass: {
305+
properties: {
306+
id: {
307+
format: "int32",
308+
type: "integer"
309+
}
310+
}
311+
}
312+
}
313+
};
314+
api.resolve(spec, 'http://localhost:8000/v2/petstore.json', function (spec, unresolved) {
315+
expect(Object.keys(unresolved).length).toBe(0);
316+
test.object(spec);
317+
var schema = spec.definitions.new_model.properties.subclass;
318+
319+
expect(schema['x-composed']).toBe(true);
320+
expect(Array.isArray(schema['x-resolved-from'])).toBe(true);
321+
expect(schema['x-resolved-from'][0]).toBe('#/definitions/new_model');
322+
expect(schema['x-resolved-from'][1]).toBe('#/definitions/superclass');
323+
324+
expect(Object.keys(schema.properties).length).toBe(2);
325+
326+
var id = schema.properties.id;
327+
expect(id.type).toBe("integer");
328+
expect(id.format).toBe("int32");
329+
expect(id['x-resolved-from']).toBe('#/definitions/superclass');
330+
331+
var name = schema.properties.name;
332+
expect(name.type).toBe("string");
333+
expect(name['x-resolved-from']).toBe('self');
334+
335+
done();
336+
});
337+
});
230338
});

0 commit comments

Comments
 (0)