From fa40595fa012986666114985850fa05b82a67b1f Mon Sep 17 00:00:00 2001 From: Francisco Di Giandomenico Date: Tue, 21 Dec 2021 14:08:11 -0500 Subject: [PATCH 1/6] chore(models): add APIC-743 model --- demo/APIC-743/APIC-743.yaml | 367 ++++++++++++++++++++++++++++++++++++ demo/apis.json | 3 +- 2 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 demo/APIC-743/APIC-743.yaml diff --git a/demo/APIC-743/APIC-743.yaml b/demo/APIC-743/APIC-743.yaml new file mode 100644 index 0000000..93f3d9b --- /dev/null +++ b/demo/APIC-743/APIC-743.yaml @@ -0,0 +1,367 @@ +openapi: 3.0.0 +info: + title: safeco-xapi + description: |- + # safeco-api specification + --- + ## Initial Draft + version: v0 + +paths: + /ping: + get: + security: + - oauth_2_0: + - manage:scope + tags: + - Ping + summary: Get api status + responses: + '200': + description: ok + content: + application/json: + schema: + $ref: "#/components/schemas/pingResponse" + + /rates: + post: + security: + - oauth_2_0: + - manage:scope + tags: + - Rate + summary: "Get the rates for pet insurance premiums by passing necessary information" + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/getRateRequest' + responses: + '201' : + description: success + content: + application/json: + schema: + $ref: '#/components/schemas/getRateResponse' + + '400': + $ref: "#/components/responses/badRequest400" + '401': + $ref: "#/components/responses/unauthorised401" + '404': + $ref: "#/components/responses/notFound404" + '5XX': + $ref: "#/components/responses/serverError5XX" + + +components: + securitySchemes: + oauth_2_0: + type: oauth2 + description: This API supports OAuth 2.0 for authenticating all API requests. + flows: + authorizationCode: + authorizationUrl: https://petscovered.okta.com/oauth2/default/v1/authorize + tokenUrl: https://petscovered.okta.com/oauth2/default/v1/token + scopes: + manage:scope: Manage scope for resource + + + schemas: + getRateRequest: + type: object + properties: + producer: + description: Details of Producer or Agent related with the request. + allOf: + - $ref: "#/components/schemas/commonNameProperties" + - $ref: "#/components/schemas/commonAddressProperties" + - $ref : '#/components/schemas/producerProperties' + required: + - producerId + - isActive + - lastName + customer: + description: Details of Customer related with the request. + allOf: + - $ref: "#/components/schemas/commonNameProperties" + - $ref: "#/components/schemas/commonAddressProperties" + - $ref : '#/components/schemas/customerProperties' + required: + - lastName + - email + pet: + $ref : '#/components/schemas/pet' + ratingFactors: + type: array + description: Each rating as a separate object with unique setName property. Duplicate setName properties are not processed. + items: + $ref : '#/components/schemas/ratingFactor' + required: + - producer + - customer + - pet + - ratingFactors + + + getRateResponse: + type: object + properties: + leadId: + type: string + example: "4224901b30414542e46c01394baa190e" + petId: + type: string + example: "405ea8b7b7708033116ba6f2adb89c92" + rates: + $ref : '#/components/schemas/rates' + + + pingResponse: + type: object + properties: + success: + type: boolean + example: true + code: + type: number + example: 200 + status: + type: string + example: Alive + env: + type: string + example: dev + moduleName: + type: string + example: safeco-api + + commonNameProperties: + type: object + properties: + firstName: + type: string + example: "Leonel" + middleName: + type: string + example: "Andreas" + lastName: + type: string + example: "Messi" + + commonAddressProperties: + type: object + properties: + address: + type: string + example: "221B Baker Street" + addressCont: + type: string + example: "Near Scotland Yard" + city: + type: string + example: "New York" + state: + type: string + example: "IN" + zip: + type: string + example: "85001" + + + producerProperties: + type: object + properties: + producerId: + type: string + example: "1234567890" + npn: + type: string + example: "1234567890" + type: + type: string + example: " " + mobilePhone: + type: string + example: "987898799" + officePhone: + type: string + example: "02166728988" + email: + type: string + example: "insurance.agent@companionprotect.com" + websiteUrl: + type: string + example: "www.companionprotect.com" + managerId: + type: string + example: "b12F005" + locationId: + type: string + example: "0AB234" + locationName: + type: string + example: "xyz" + isActive: + type: boolean + example: true + riskState: + type: string + example: "" + + + + customerProperties: + type: object + properties: + leadId: + type: string + example: "4224901b30414542e46c01394baa190e" + phone: + type: string + example: "5052331872" + email: + type: string + example: "abc@gmail.com" + required: + - email + + + pet: + description: Details of the pet related with the request. + type: object + properties: + name: + type: string + example: "max" + species: + type: string + example: "Dog" + breed: + type: string + example: "akita" + gender: + type: string + example: "Male" + ageInYears: + type: integer + example: 4 + required: + - name + - species + - breed + + + ratingFactor: + type: object + properties: + setName: + type: string + example: "option1" + deductible: + type: number + example: 90 + reimbursement: + type: number + example: 200 + annualLimit: + type: number + example: 10000 + required: + - setName + - deductible + - reimbursement + - annualLimit + + + rates: + type: array + items: + type: object + properties: + setName: + type: string + example: "name" + premiumAmount: + type: number + multipleOf: 0.01 + example: 48.6 + wellnessPremiumAmount: + type: number + multipleOf: 0.01 + example: 48.48 + totalMonthlyPremiumAmount: + type: number + multipleOf: 0.01 + example: 8.09 + totalAnnualPremiumAmount: + type: number + multipleOf: 0.01 + example: 97.08 + + + + responses: + badRequest400: + description: Bad Request + content: + application/json: + schema: + type: object + examples: + badRequest400: + $ref: "#/components/examples/badRequest400" + unauthorised401: + description: Unauthorised + content: + application/json: + schema: + type: object + examples: + unauthorised401: + $ref: "#/components/examples/unauthorised401" + serverError5XX: + description: Internal Server Error + content: + application/json: + schema: + type: object + examples: + serverError5xx: + $ref: "#/components/examples/serverError5XX" + notFound404: + description: Resource Notfound + content: + application/json: + schema: + type: object + examples: + notFound404: + $ref: "#/components/examples/notFound404" + examples: + badRequest400: + value: + success: false + code: 400 + reasonCode: Bad Request + message: Required header Authorization not specified + unauthorised401: + value: + success: false + code: 401 + reasonCode: Unauthorised + message: unauthorised request + notFound404: + value: + success: false + code: 404 + reasonCode: Resource Not found + message: requested resource not found or does not exist + serverError5XX: + value: + success: false + code: 500 + reasonCode: Internal Server Error + message: Internal Server Error \ No newline at end of file diff --git a/demo/apis.json b/demo/apis.json index 53dd7b2..10f7a9d 100644 --- a/demo/apis.json +++ b/demo/apis.json @@ -18,5 +18,6 @@ "new-oas3-types/new-oas3-types.yaml": { "type": "OAS 3.0", "mime": "application/yaml" }, "oas-api/read-only-properties.yaml": { "type": "OAS 3.0", "mime": "application/yaml" }, "APIC-649/APIC-649.yaml": { "type": "OAS 3.0", "mime": "application/yaml" }, - "APIC-671/APIC-671.yaml": { "type": "OAS 3.0", "mime": "application/yaml" } + "APIC-671/APIC-671.yaml": { "type": "OAS 3.0", "mime": "application/yaml" }, + "APIC-743/APIC-743.yaml": { "type": "OAS 3.0", "mime": "application/yaml" } } From 9028d4220344b818954451286f41ba3ec2685ce5 Mon Sep 17 00:00:00 2001 From: Francisco Di Giandomenico Date: Tue, 21 Dec 2021 14:08:46 -0500 Subject: [PATCH 2/6] fix(allof): add support for allOf property shapes as complex types --- src/PropertyDocumentMixin.d.ts | 11 +++++++++++ src/PropertyDocumentMixin.js | 12 ++++++++++++ src/PropertyShapeDocument.js | 11 ++++++++--- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/PropertyDocumentMixin.d.ts b/src/PropertyDocumentMixin.d.ts index 5b79d6d..d6cd6d1 100644 --- a/src/PropertyDocumentMixin.d.ts +++ b/src/PropertyDocumentMixin.d.ts @@ -115,6 +115,17 @@ interface PropertyDocumentMixin extends AmfHelperMixin { */ _computeIsAnyOf(range: Object): boolean + + /** + * Computes value for `isAllOf` property. + * AllOf type is identified as `http://www.w3.org/ns/shacl#and` + * Returns true if `and` property is present in shape. Otherwise returns false. + * + * @param {Object} range Range object of current shape. + * @returns {boolean} + */ + _computeIsAllOf(range: Object): boolean + /** * Computes list of type labels to render. * diff --git a/src/PropertyDocumentMixin.js b/src/PropertyDocumentMixin.js index 71b6940..cc039ce 100644 --- a/src/PropertyDocumentMixin.js +++ b/src/PropertyDocumentMixin.js @@ -345,6 +345,18 @@ const mxFunction = (base) => { return this._hasProperty(range, this.ns.w3.shacl.or); } + + /** + * Computes value for `isAllOf` property. + * Returns true if `and` property is present in shape. Otherwise returns false. + * + * @param {Object} range Range object of current shape. + * @returns {boolean} + */ + _computeIsAllOf(range) { + return this._hasProperty(range, this.ns.w3.shacl.and); + } + /** * Computes list of type labels to render. * diff --git a/src/PropertyShapeDocument.js b/src/PropertyShapeDocument.js index a920162..892e940 100644 --- a/src/PropertyShapeDocument.js +++ b/src/PropertyShapeDocument.js @@ -272,12 +272,14 @@ export class PropertyShapeDocument extends PropertyDocumentMixin(LitElement) { this.isReadOnly = this._isReadOnly(range); this.isAnyOf = this._computeIsAnyOf(range); this.isOneOf = this._computeIsOneOf(range); + this.isAllOf = this._computeIsAllOf(range); this.isComplex = this._computeIsComplex( this.isUnion, this.isObject, this.isArray, this.isAnyOf, - this.isOneOf + this.isOneOf, + this.isAllOf ); this.isScalarArray = this.isArray ? this._computeIsScalarArray(range) @@ -465,10 +467,13 @@ export class PropertyShapeDocument extends PropertyDocumentMixin(LitElement) { * @param {boolean} isUnion * @param {boolean} isObject * @param {boolean} isArray + * @param {boolean} isAnyOf + * @param {boolean} isOneOf + * @param {boolean} isAllOf * @return {boolean} */ - _computeIsComplex(isUnion, isObject, isArray, isAnyOf, isOneOf) { - return isUnion || isObject || isArray || isAnyOf || isOneOf; + _computeIsComplex(isUnion, isObject, isArray, isAnyOf, isOneOf, isAllOf) { + return isUnion || isObject || isArray || isAnyOf || isOneOf || isAllOf; } _evaluateGraph() { From 0dfe5a048e93a5342ae739f5092991d9d4571662 Mon Sep 17 00:00:00 2001 From: Francisco Di Giandomenico Date: Tue, 21 Dec 2021 14:09:00 -0500 Subject: [PATCH 3/6] test: add test for allOf property having SHOW button --- test/api-type-document.test.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/api-type-document.test.js b/test/api-type-document.test.js index b80a0d4..0590393 100644 --- a/test/api-type-document.test.js +++ b/test/api-type-document.test.js @@ -757,6 +757,25 @@ describe('', () => { ); }); }); + + describe('APIC-743', () => { + let element = /** @type ApiTypeDocument */ (null); + + beforeEach(async () => { + const data = await AmfLoader.loadType('getRateRequest', item[1], 'APIC-743'); + element = await basicFixture(); + element.amf = data[0]; + element.type = data[1]; + await aTimeout(50); + }); + + it('should render "Show" button for type\'s "allOf" property', () => { + const psdNode = Array.from(element.shadowRoot.querySelectorAll('property-shape-document')).find(node => node.propertyName === 'producer'); + assert.exists(psdNode, 'Could not find "producer" property-shape-document node'); + const showButton = psdNode.shadowRoot.querySelector('anypoint-button.complex-toggle'); + assert.exists(showButton, '"producer" node did not have the "Show" button'); + }); + }); }); }); From 52e9ab9f03e12e9e7c8121b363061241464d2e58 Mon Sep 17 00:00:00 2001 From: Francisco Di Giandomenico Date: Tue, 21 Dec 2021 14:09:10 -0500 Subject: [PATCH 4/6] 4.2.16 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ae7c18b..3b7cefb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@api-components/api-type-document", - "version": "4.2.15", + "version": "4.2.16", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4531178..ded08ea 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@api-components/api-type-document", "description": "A documentation table for type (resource) properties. Works with AMF data model", - "version": "4.2.15", + "version": "4.2.16", "license": "Apache-2.0", "main": "index.js", "module": "index.js", From cbb3d33f57534d73de4eb37ad84af409296b4d32 Mon Sep 17 00:00:00 2001 From: Francisco Di Giandomenico Date: Tue, 21 Dec 2021 14:14:52 -0500 Subject: [PATCH 5/6] test: remove waiting for aTimeout --- test/api-type-document.test.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/api-type-document.test.js b/test/api-type-document.test.js index 0590393..5e19733 100644 --- a/test/api-type-document.test.js +++ b/test/api-type-document.test.js @@ -1,7 +1,8 @@ /* eslint-disable prefer-destructuring */ -import { fixture, assert, nextFrame, aTimeout } from '@open-wc/testing'; +import { fixture, assert, nextFrame, aTimeout, waitUntil } from '@open-wc/testing' import { AmfLoader } from './amf-loader.js'; import '../api-type-document.js'; +import { PropertyShapeDocument } from '../src/PropertyShapeDocument.js'; /** @typedef {import('..').ApiTypeDocument} ApiTypeDocument */ @@ -766,13 +767,16 @@ describe('', () => { element = await basicFixture(); element.amf = data[0]; element.type = data[1]; - await aTimeout(50); }); - it('should render "Show" button for type\'s "allOf" property', () => { - const psdNode = Array.from(element.shadowRoot.querySelectorAll('property-shape-document')).find(node => node.propertyName === 'producer'); - assert.exists(psdNode, 'Could not find "producer" property-shape-document node'); - const showButton = psdNode.shadowRoot.querySelector('anypoint-button.complex-toggle'); + it('should render "Show" button for type\'s "allOf" property', async () => { + let producerNode = /** @type {PropertyShapeDocument} */ (null); + await waitUntil(() => { + const propertyShapeDocumentNodes = Array.from(element.shadowRoot.querySelectorAll('property-shape-document')); + producerNode = propertyShapeDocumentNodes.find(node => node.propertyName === 'producer'); + return Boolean(producerNode); + }, 'Could not find "producer" property-shape-document node'); + const showButton = producerNode.shadowRoot.querySelector('anypoint-button.complex-toggle'); assert.exists(showButton, '"producer" node did not have the "Show" button'); }); }); From 867f67b4622f41383383a57f8047823501c78202 Mon Sep 17 00:00:00 2001 From: Francisco Di Giandomenico Date: Tue, 21 Dec 2021 14:17:34 -0500 Subject: [PATCH 6/6] test: change type import method --- test/api-type-document.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/api-type-document.test.js b/test/api-type-document.test.js index 5e19733..c19d331 100644 --- a/test/api-type-document.test.js +++ b/test/api-type-document.test.js @@ -2,9 +2,9 @@ import { fixture, assert, nextFrame, aTimeout, waitUntil } from '@open-wc/testing' import { AmfLoader } from './amf-loader.js'; import '../api-type-document.js'; -import { PropertyShapeDocument } from '../src/PropertyShapeDocument.js'; /** @typedef {import('..').ApiTypeDocument} ApiTypeDocument */ +/** @typedef {import('..').PropertyShapeDocument} PropertyShapeDocument */ describe('', () => { const newOas3Types = 'new-oas3-types';