Skip to content

Commit

Permalink
feat(W-17309546): add RAML definition and example data for user API
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpmule committed Dec 9, 2024
1 parent a1a0aaf commit 00f6b62
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 25 deletions.
24 changes: 24 additions & 0 deletions demo/W-17309546/W-17309546.raml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#%RAML 1.0
title: test_for_support
mediaType: application/json



types:
User:
type: object
properties:
id: integer
name: string
email: string
postal_code: string
companyDateEntry: date-only

/test:
get:
description: Obtenir la liste des utilisateurs
responses:
200:
body:
type: User[]
example: !include /examples/employees/user-examples.raml
17 changes: 17 additions & 0 deletions demo/W-17309546/examples/employees/user-examples.raml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#%RAML 1.0 NamedExample
value:
- id: 1
name: Alice Dupont
email: [email protected]
companyDateEntry: 2003-05-14
postal_code: "075001"
- id: 2
name: Bob Martin
email: [email protected]
companyDateEntry: 2004-05-04
postal_code: "169002"
- id: 3
name: Charlie Durand
email: [email protected]
companyDateEntry: 2003-08-11
postal_code: "013003"
1 change: 1 addition & 0 deletions demo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ class ComponentDemo extends ApiDemoPage {
['APIC-655', 'APIC-655'],
['xml-api', 'xml-api'],
['W-11843862', 'W-11843862'],
['W-17309546', 'W-17309546'],
['v4_0_0_api_specs', 'v4_0_0_api_specs']
].map(
([file, label]) => html`
Expand Down
1 change: 1 addition & 0 deletions demo/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ files.set('SE-22063/SE-22063.raml', { type: 'RAML 1.0' });
files.set('APIC-332/APIC-332.raml', { type: 'RAML 1.0' });
files.set('APIC-690/APIC-690.raml', { type: 'RAML 1.0' });
files.set('10732397/10732397.raml', { type: 'RAML 1.0' });
files.set('W-17309546/W-17309546.raml', { type: 'RAML 1.0' });
files.set('oas-3-api/oas-3-api.yaml', { type: 'OAS 3.0', mime: 'application/yaml' });
files.set('allof-types/allof-types.yaml', { type: 'OAS 3.0', mime: 'application/yaml' });
files.set('APIC-679/APIC-679.yaml', { type: 'OAS 3.0', mime: 'application/yaml' });
Expand Down
67 changes: 42 additions & 25 deletions src/ExampleGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -653,19 +653,19 @@ export class ExampleGenerator extends AmfHelperMixin(Object) {

// Map raw to external fragment
if (!raw) {
// It first retrieves the @id property from the first element
// It first retrieves the @id property from the first element
// of referenceIdData array and assigns it to referenceId.
const referenceId = referenceIdData[0]['@id']

// It calls the _computeReferences method with this.amf as an
// argument to get the root references and assigns
// It calls the _computeReferences method with this.amf as an
// argument to get the root references and assigns
// the result to rootReferences.
const rootReferences = this._computeReferences(this.amf)

// It maps over each item in rootReferences,
// and for each item, it computes references twice in a nested manner.
// and for each item, it computes references twice in a nested manner.
// It then gets the second element from externalFragments and computes its encodes.
// The result of this map operation is an array of
// The result of this map operation is an array of
// encoded external fragments, which is assigned to encodesOfExternalFragments.
const encodesOfExternalFragments = rootReferences.map((item) => {
const shapeFragment = this._computeReferences(item)
Expand All @@ -675,16 +675,16 @@ export class ExampleGenerator extends AmfHelperMixin(Object) {
return this._computeEncodes(externalFragmentExample)
})

// It finds an element in encodesOfExternalFragments where
// the @id property matches referenceId and assigns
// It finds an element in encodesOfExternalFragments where
// the @id property matches referenceId and assigns
// it to exmapleExternalFragmentByReferenceId.
const exmapleExternalFragmentByReferenceId = encodesOfExternalFragments.find(externalFrament => (
externalFrament['@id'] === referenceId
))

const rawKey = this._getAmfKey(this.ns.aml.vocabularies.document.raw)
// Finally, it calls the _getValue method with
// exmapleExternalFragmentByReferenceId and rawKey
// exmapleExternalFragmentByReferenceId and rawKey
// as arguments and assigns the result to raw.
raw = this._getValue(exmapleExternalFragmentByReferenceId, rawKey)
}
Expand Down Expand Up @@ -801,7 +801,7 @@ export class ExampleGenerator extends AmfHelperMixin(Object) {
}
});
if (isJson) {
// if raw (original example) exists try to parse it to JSON
// if raw (original example) exists try to parse it to JSON
// if the parse process fails then use parts to build example value
if (result.raw) {
try {
Expand Down Expand Up @@ -847,27 +847,44 @@ export class ExampleGenerator extends AmfHelperMixin(Object) {
return undefined;
}

parseToJSON (arr) {
return arr
.filter(item => item.trim() !== "") // Remove empty strings
.map(item => {
if (item.startsWith("- ")) {
// Handle case where item is a list of numbers
return item.split("- ")
.filter(subItem => subItem.trim() !== "")
.map(subItem => Number(subItem.trim()));
}
// Handle case where item is a key-value pair
const entries = item.trim().split("\n").map(line => {
const index = line.indexOf(":");
const key = line.slice(0, index).trim();
const value = line.slice(index + 1).trim();
if (value.startsWith("\"") && value.endsWith("\"")) {
return [key, value.slice(1, -1)]; // Preserve leading zeros
}
if (!Number.isNaN(Number(value))) {
return [key, Number(value)];
}
return [key, value];
});
return Object.fromEntries(entries);

});
};

/**
* @param {String} raw
* @param {String} raw
* @returns string JSON formatted
*/
computeRaw(raw) {
const accountEntries = raw.split('-\n');
const accounts = [];
for (const entry of accountEntries) {
if (entry !== '') {
const lines = entry.split('\n');
const account = {};
for (const line of lines) {
if (line !== '') {
const [key, value] = line.split(': ');
account[key.trim()] = Number(value) ? Number(value) : value.trim()
}
}
accounts.push(account);
}
}
return JSON.stringify(accounts, null, 2);
const parsed = this.parseToJSON(accountEntries)
// Ensure the parsed result is always an array
const result = Array.isArray(parsed[0]) ? parsed.flat() : parsed;
return JSON.stringify(result, null, 2);
}


Expand Down
60 changes: 60 additions & 0 deletions test/W-17309546.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { fixture, assert, html } from '@open-wc/testing';
import { AmfLoader } from './amf-loader.js';
import '../api-example-generator.js';

describe('W-17309546', () => {
async function basicFixture(amf) {
return (await fixture(html`<api-example-generator
.amf="${amf}"></api-example-generator>`));
}

const apiFile = 'W-17309546';

[
['json+ld data model', false],
['Compact data model', true]
].forEach(([label, compact]) => {
describe(label, () => {
let element;
let amf;

before(async () => {
amf = await AmfLoader.load(compact, apiFile);
});

beforeEach(async () => {
element = await basicFixture(amf);
});

it('renders examples right', () => {
const payloads = AmfLoader.lookupReturnsPayload(amf, '/test', 'get', 200);
const result = element.generatePayloadsExamples(payloads, 'application/json');
assert.typeOf(result, 'array');
const item = result[0];
assert.equal(item.value, `[
{
"id": 1,
"name": "Alice Dupont",
"email": "[email protected]",
"companyDateEntry": "2003-05-14",
"postal_code": "075001"
},
{
"id": 2,
"name": "Bob Martin",
"email": "[email protected]",
"companyDateEntry": "2004-05-04",
"postal_code": "169002"
},
{
"id": 3,
"name": "Charlie Durand",
"email": "[email protected]",
"companyDateEntry": "2003-08-11",
"postal_code": "013003"
}
]`);
});
});
});
});

0 comments on commit 00f6b62

Please sign in to comment.