Skip to content

Commit eb69360

Browse files
authored
Merge pull request #69 from advanced-rest-client/fix/W-17413312/Incorrect-rendering-of-OAS-Specification-in-Design-centre-and-Exchange
Fix/W-17413312/Incorrect-rendering-of-OAS-Specification-in-Design-centre-and-Exchange
2 parents cb577a9 + 2cd0d9b commit eb69360

File tree

8 files changed

+866
-7
lines changed

8 files changed

+866
-7
lines changed

demo/W-17413312/W-17413312.json

Lines changed: 754 additions & 0 deletions
Large diffs are not rendered by default.

demo/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class ComponentDemo extends ApiDemoPage {
125125
['xml-api', 'xml-api'],
126126
['W-11843862', 'W-11843862'],
127127
['W-17309546', 'W-17309546'],
128+
['W-17413312', 'W-17413312'],
128129
['v4_0_0_api_specs', 'v4_0_0_api_specs']
129130
].map(
130131
([file, label]) => html`

demo/model.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ files.set('APIC-332/APIC-332.raml', { type: 'RAML 1.0' });
2323
files.set('APIC-690/APIC-690.raml', { type: 'RAML 1.0' });
2424
files.set('10732397/10732397.raml', { type: 'RAML 1.0' });
2525
files.set('W-17309546/W-17309546.raml', { type: 'RAML 1.0' });
26+
files.set('W-17413312/W-17413312.json', { type: 'OAS 3.0', mime: 'application/json' });
2627
files.set('oas-3-api/oas-3-api.yaml', { type: 'OAS 3.0', mime: 'application/yaml' });
2728
files.set('allof-types/allof-types.yaml', { type: 'OAS 3.0', mime: 'application/yaml' });
2829
files.set('APIC-679/APIC-679.yaml', { type: 'OAS 3.0', mime: 'application/yaml' });

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@api-components/api-example-generator",
33
"description": "Examples generator from AMF model",
4-
"version": "4.4.30",
4+
"version": "4.4.31",
55
"license": "Apache-2.0",
66
"main": "index.js",
77
"module": "index.js",

src/ExampleGenerator.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,6 +1425,9 @@ export class ExampleGenerator extends AmfHelperMixin(Object) {
14251425
return this._computeJsonPropertyValue(oneOfOptions[0], typeName);
14261426
}
14271427
}
1428+
if (this._hasType(range, this.ns.w3.shacl.Shape)) {
1429+
return this._computeJsonOrValue(range);
1430+
}
14281431
return undefined;
14291432
}
14301433

@@ -1649,6 +1652,43 @@ export class ExampleGenerator extends AmfHelperMixin(Object) {
16491652
return examples.reduce((acc, value) => ({ ...acc, ...value }), {});
16501653
}
16511654

1655+
/**
1656+
* Computes a JSON object or value from a given range.
1657+
*
1658+
* @param {Object} range AMF's range definition for a shape.
1659+
* @return {any|undefined} A JavaScript object or value computed from the range.
1660+
*/
1661+
_computeJsonOrValue(range) {
1662+
const key = this._getAmfKey(this.ns.w3.shacl.or);
1663+
const list = this._ensureArray(range[key]);
1664+
if (!list) {
1665+
return undefined;
1666+
}
1667+
1668+
const examples = [];
1669+
const anyOfKey = this._getAmfKey(this.ns.aml.vocabularies.shapes.anyOf);
1670+
1671+
// Iterate over all items in the list
1672+
for (const item of list) {
1673+
const properties = this._ensureArray(item[anyOfKey]);
1674+
if (properties) {
1675+
// Iterate over all properties to get all propertiesSchemas
1676+
for (const property of properties) {
1677+
const propertiesSchemas = this._listProperties(property);
1678+
if (propertiesSchemas) {
1679+
const propertiesExamples = this._jsonExampleFromProperties(propertiesSchemas);
1680+
if (propertiesExamples && typeof propertiesExamples === 'object') {
1681+
examples.push(propertiesExamples);
1682+
}
1683+
}
1684+
}
1685+
}
1686+
}
1687+
1688+
// Merge all examples into a single object
1689+
return examples.reduce((acc, value) => ({ ...acc, ...value }), {});
1690+
}
1691+
16521692
/**
16531693
* Computes JSON object as an example from a range that is an object.
16541694
*

test/ExampleGenerator.test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -688,11 +688,11 @@ describe('ExampleGenerator', () => {
688688
assert.equal(root.querySelector('etag').textContent.trim(), 'W\\\\244m4n5kj3gbn2nj4k4n4', 'the etag value');
689689

690690
const image = root.querySelector('image');
691-
691+
692692
assert.ok(image, 'has the image node');
693693
assert.equal(image.querySelector('url').textContent.trim(), 'https://www.domain.com/people/Qawer63J73HJ6khjswuqyq62382jG21s/image', 'the image.url value');
694694
assert.equal(image.querySelector('thumb').textContent.trim(), 'https://www.domain.com/people/Qawer63J73HJ6khjswuqyq62382jG21s/image/thumb', 'the image.thumb value');
695-
695+
696696
assert.typeOf(ex2.raw, 'string', 'example 2 has the raw value');
697697
});
698698

@@ -2321,7 +2321,7 @@ describe('ExampleGenerator', () => {
23212321
schema = element._resolve(schema);
23222322
const result = element._computeJsonPropertyValue(schema);
23232323
assert.typeOf(result, 'object');
2324-
assert.deepEqual(result, { messages: [{ "referrers": [{"type": "Salesforce:Core:Bot:Id", "value": ""}], "sequenceId": 1, "text": "", "type": "init", "tz": "", "variables": [] }]})
2324+
assert.deepEqual(result, { messages: [{ "referrers": [{"type": "Salesforce:Core:Bot:Id", "value": ""}], "sequenceId": 1, "text": "", "type": "init", "tz": "", "variables": [{}] }]})
23252325
});
23262326
});
23272327
});
@@ -2525,7 +2525,7 @@ describe('ExampleGenerator', () => {
25252525
assert.typeOf(parsed, 'array', 'represents an array');
25262526
assert.lengthOf(parsed, 2, 'has 2 items');
25272527
const [e1, e2] = parsed;
2528-
2528+
25292529
assert.equal(e1.id, 1, 'has the example1.id');
25302530
assert.equal(e1.name, 'John', 'has the example1.name');
25312531
assert.equal(e2.id, 2, 'has the example2.id');

test/W-17413312.test.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { fixture, assert, html } from '@open-wc/testing';
2+
import { AmfLoader } from './amf-loader.js';
3+
import '../api-example-generator.js';
4+
5+
describe('W-17413312', () => {
6+
async function basicFixture(amf) {
7+
return (await fixture(html`<api-example-generator
8+
.amf="${amf}"></api-example-generator>`));
9+
}
10+
11+
const apiFile = 'W-17413312';
12+
13+
[
14+
['json+ld data model', false],
15+
['Compact data model', true]
16+
].forEach(([label, compact]) => {
17+
describe(label, () => {
18+
let element;
19+
let amf;
20+
21+
before(async () => {
22+
amf = await AmfLoader.load(compact, apiFile);
23+
});
24+
25+
beforeEach(async () => {
26+
element = await basicFixture(amf);
27+
});
28+
29+
it('renders examples right', () => {
30+
const payloads = AmfLoader.lookupReturnsPayload(amf, '/sources', 'get', 200);
31+
const result = element.generatePayloadsExamples(payloads, 'application/json');
32+
assert.typeOf(result, 'array');
33+
const item = result[0];
34+
assert.equal(item.value, `{
35+
"data": [
36+
{
37+
"id": "64f1f0d46ad16b6acdaa3e0e",
38+
"name": "Main Station Track 5a",
39+
"type": "Camera",
40+
"class": "Common",
41+
"audio": {
42+
"isEnabled": true
43+
},
44+
"externalReference": "b8755c8d-ef9d-4a7e-a8a2-7b5abace1af7",
45+
"streams": [
46+
{
47+
"id": "64f1eff26ad16b6acdaa3e08",
48+
"url": "rtsp://ipcam573.example.com:554/live/ch0",
49+
"decoderOptions": {
50+
"protocols": 2,
51+
"tcp-timeout": 10000000
52+
}
53+
}
54+
],
55+
"authentication": {}
56+
}
57+
],
58+
"meta": {}
59+
}`);
60+
});
61+
});
62+
});
63+
});

0 commit comments

Comments
 (0)