From 4899f3e08fce5017b8f80e48590cd584efaac2e7 Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Thu, 9 Mar 2017 19:56:50 +0200 Subject: [PATCH] fix: x-extendedDiscriminator not working closes #217 --- lib/utils/spec-manager.ts | 20 +++++++++--- manual-types/index.d.ts | 5 +++ tests/unit/SpecManager.spec.ts | 19 +++++++++++ tests/unit/x-extended-defs.json | 57 +++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 tests/unit/x-extended-defs.json diff --git a/lib/utils/spec-manager.ts b/lib/utils/spec-manager.ts index 379f624a41..b0535c5c99 100644 --- a/lib/utils/spec-manager.ts +++ b/lib/utils/spec-manager.ts @@ -9,6 +9,7 @@ import { MdRenderer } from './md-renderer'; import { SwaggerOperation, SwaggerParameter } from './swagger-typings'; import { snapshot } from './helpers'; +import { WarningsService } from '../services/warnings.service'; function getDiscriminator(obj) { return obj.discriminator || obj['x-extendedDiscriminator']; @@ -204,12 +205,23 @@ export class SpecManager { if (idx < 0) continue; - let derivedName = defName; + let derivedName; if (extendedDiscriminatorProp) { - let prop = def.properties && def.properties[extendedDiscriminatorProp]; - if (prop && prop.enum && prop.enum.length === 1) { - derivedName = prop.enum[0]; + let subDefs = def.allOf || []; + for (let def of subDefs) { + let prop = def.properties && def.properties[extendedDiscriminatorProp]; + if (prop && prop.enum && prop.enum.length === 1) { + derivedName = prop.enum[0]; + break; + } } + if (!derivedName) { + WarningsService.warn(`Incorrect usage of x-extendedDiscriminator at ${defPointer}: ` + + `can't find corresponding enum with single value in definition "${defName}"`); + continue; + } + } else { + derivedName = defName; } res.push({name: derivedName, $ref: `#/definitions/${defName}`}); diff --git a/manual-types/index.d.ts b/manual-types/index.d.ts index 1a39435e2d..ba8e22db8d 100644 --- a/manual-types/index.d.ts +++ b/manual-types/index.d.ts @@ -13,6 +13,11 @@ declare module "*.css" { export default content; } +declare module "*.json" { + const content: string; + export default content; +} + declare var LIB_VERSION: any; declare var IS_PRODUCTION: any; declare var AOT: any; diff --git a/tests/unit/SpecManager.spec.ts b/tests/unit/SpecManager.spec.ts index f79e1409e8..ec12878851 100644 --- a/tests/unit/SpecManager.spec.ts +++ b/tests/unit/SpecManager.spec.ts @@ -1,6 +1,8 @@ 'use strict'; import { SpecManager } from '../../lib/utils/spec-manager'; +import * as xExtendedDefs from './x-extended-defs.json'; + describe('Utils', () => { describe('Schema manager', () => { let specMgr: SpecManager; @@ -175,6 +177,23 @@ describe('Utils', () => { deriveDefs.should.be.instanceof(Array); deriveDefs.should.be.empty(); }); + + it('should correctly work with x-extendedDiscriminator', () => { + specMgr._schema = { + definitions: xExtendedDefs + }; + + let deriveDefs = specMgr.findDerivedDefinitions('#/definitions/Payment'); + deriveDefs.should.be.instanceof(Array); + deriveDefs.should.be.deepEqual([ + { + name: 'cash', + $ref: '#/definitions/CashPayment' + }, { + name: 'paypal', + $ref: '#/definitions/PayPalPayment' + }]) + }); }); }); }); diff --git a/tests/unit/x-extended-defs.json b/tests/unit/x-extended-defs.json new file mode 100644 index 0000000000..b0d487ea72 --- /dev/null +++ b/tests/unit/x-extended-defs.json @@ -0,0 +1,57 @@ +{ + "Payment": { + "x-extendedDiscriminator": "type", + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "CashPayment": { + "allOf": [ + { + "$ref": "#/definitions/Payment" + }, + { + "properties": { + "type": { + "type": "string", + "enum": [ + "cash" + ] + }, + "currency": { + "type": "string" + } + } + } + ] + }, + "PayPalPayment": { + "allOf": [ + { + "$ref": "#/definitions/Payment" + }, + { + "properties": { + "type": { + "type": "string", + "enum": [ + "paypal" + ] + }, + "userEmail": { + "type": "string" + } + } + } + ] + } +}