@adobe/acc-js-sdk 1.0.7 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,729 +16,2133 @@ governing permissions and limitations under the License.
16
16
  * Unit tests for the schema data objects
17
17
  *
18
18
  *********************************************************************************/
19
- const { DomUtil, XPath, XPathElement } = require('../src/domUtil.js');
19
+ const { SchemaCache } = require('../src/application.js');
20
+ const { DomUtil, XPath } = require('../src/domUtil.js');
21
+ const sdk = require('../src/index.js');
20
22
  const newSchema = require('../src/application.js').newSchema;
21
23
  const newCurrentLogin = require('../src/application.js').newCurrentLogin;
22
24
  const Mock = require('./mock.js').Mock;
23
25
 
24
- describe('Schemas', function() {
25
-
26
- describe("Root node", () => {
26
+ describe('Application', () => {
27
+ describe('Schemas', function() {
28
+
29
+ describe("Root node", () => {
30
+
31
+ it("No root node", () => {
32
+ var xml = DomUtil.parse("<schema namespace='nms' name='recipient'></schema>");
33
+ var schema = newSchema(xml);
34
+ var root = schema.root;
35
+ expect(root).toBeFalsy();
36
+ });
37
+
38
+ it("Just the root node", () => {
39
+ var xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='recipient' label='Recipients'/></schema>");
40
+ var schema = newSchema(xml);
41
+ var root = schema.root;
42
+ expect(root).toBeTruthy();
43
+ expect(root.name).toBe("recipient");
44
+ expect(root.label).toBe("Recipients");
45
+ });
46
+
47
+ it("Duplicate root nodes", () => {
48
+ expect(() => {
49
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
50
+ <element name='recipient' label='Recipients'/>
51
+ <element name='recipient' label='Recipients2'/>
52
+ </schema>`);
53
+ newSchema(xml);
54
+ }).toThrow("Failed to add element 'recipient' to ArrayMap. There's already an item with the same name");
55
+ });
56
+
57
+ it("Should find root node", () => {
58
+ const schema = sdk.TestUtil.newSchema(`
59
+ <schema namespace="nms" name="recipient">
60
+ <element name="recipient">
61
+ <attribute name="id" type="long"/>
62
+ <attribute name="name" type="string"/>
63
+ </element>
64
+ </schema>`);
65
+ expect(schema.root).toBeTruthy();
66
+ });
27
67
 
28
- it("No root node", () => {
29
- var xml = DomUtil.parse("<schema namespace='nms' name='recipient'></schema>");
30
- var schema = newSchema(xml);
31
- var root = schema.root;
32
- expect(root).toBeFalsy();
33
68
  });
34
69
 
35
- it("Just the root node", () => {
36
- var xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='recipient' label='Recipients'/></schema>");
37
- var schema = newSchema(xml);
38
- var root = schema.root;
39
- expect(root).toBeTruthy();
40
- expect(root.name).toBe("recipient");
41
- expect(root.label).toBe("Recipients");
70
+ describe("isRoot", () => {
71
+ it("Shema node is not root node", () => {
72
+ var xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='recipient' label='Recipients'/></schema>");
73
+ var schema = newSchema(xml);
74
+ expect(schema.isRoot).toBeFalsy();
75
+ });
76
+
77
+ it("Should be root node", () => {
78
+ var xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='recipient' label='Recipients'/></schema>");
79
+ var schema = newSchema(xml);
80
+ var root = schema.root;
81
+ expect(root.isRoot).toBe(true);
82
+ });
83
+
84
+ it("Should not be root node", () => {
85
+ var xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='lib'/><element name='recipient' label='Recipients'/></schema>");
86
+ var schema = newSchema(xml);
87
+ var lib = schema.children["lib"];
88
+ expect(lib.isRoot).toBeFalsy();
89
+ });
90
+
91
+ it("Should not be root node (second level with same name", () => {
92
+ var xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='recipient' label='Recipients'><element name='recipient' label='Recipients (inner)'/></element></schema>");
93
+ var schema = newSchema(xml);
94
+ var root = schema.root;
95
+ var inner = root.children["recipient"];
96
+ expect(inner.label).toBe("Recipients (inner)")
97
+ expect(inner.isRoot).toBe(false);
98
+ });
99
+ })
100
+
101
+ describe("Attributes", () => {
102
+
103
+ it("Should find unique attribute", () => {
104
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
105
+ <element name='recipient' label='Recipients'>
106
+ <attribute name='email' type='string' length='3'/>
107
+ </element>
108
+ </schema>`);
109
+ var schema = newSchema(xml);
110
+ var root = schema.root;
111
+ expect(!!root.children.get("@email")).toBe(true);
112
+ var email = root.children["@email"];
113
+ expect(email).not.toBeNull();
114
+ expect(email.name).toBe("@email");
115
+ expect(email.type).toBe("string");
116
+ expect(email.length).toBe(3);
117
+ });
118
+
119
+ it("Should not find inexistant attribute", () => {
120
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
121
+ <element name='recipient' label='Recipients'>
122
+ <attribute name='email' type='string' length='3'/>
123
+ </element>
124
+ </schema>`);
125
+ var schema = newSchema(xml);
126
+ var root = schema.root;
127
+ expect(!!root.children.get("email")).toBe(false);
128
+ expect(!!root.children.get("@dummy")).toBe(false);
129
+ });
130
+
131
+ it("Should not find inexistant attribute (@-syntax)", () => {
132
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
133
+ <element name='recipient' label='Recipients'>
134
+ <attribute name='email' type='string' length='3'/>
135
+ </element>
136
+ </schema>`);
137
+ var schema = newSchema(xml);
138
+ var root = schema.root;
139
+ expect(!!root.children.get("@email")).toBe(true);
140
+ expect(!!root.children.get("email")).toBe(false);
141
+ });
42
142
  });
43
143
 
44
- it("Duplicate root nodes", () => {
45
- expect(() => {
144
+ describe("Children", () => {
145
+ it("Should browse root children", () => {
46
146
  var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
47
- <element name='recipient' label='Recipients'/>
48
- <element name='recipient' label='Recipients2'/>
147
+ <element name='recipient' label='Recipients'>
148
+ <attribute name='email' type='string' length='3'/>
149
+ </element>
150
+ <element name='lib'/>
49
151
  </schema>`);
50
- newSchema(xml);
51
- }).toThrow("there's a already a node");
152
+ var schema = newSchema(xml);
153
+ expect(schema.childrenCount).toBe(2);
154
+ expect(schema.children["recipient"]).not.toBeNull();
155
+ expect(schema.children["lib"]).not.toBeNull();
156
+ expect(schema.children["dummy"]).toBeFalsy();
157
+ });
52
158
  });
53
159
 
54
- });
160
+ describe("Find node", () => {
55
161
 
56
- describe("isRoot", () => {
57
- it("Shema node is not root node", () => {
58
- var xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='recipient' label='Recipients'/></schema>");
59
- var schema = newSchema(xml);
60
- expect(schema.isRoot).toBeFalsy();
61
- });
162
+ it("Should find nodes", async () => {
163
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
164
+ <element name='recipient' label='Recipients'>
165
+ <attribute name='email' label="Email" type='string' length='3'/>
166
+ <element name='country' label="Country">
167
+ <attribute name='isoA3' label="Country name" type='string' length='3'/>
168
+ <attribute name='country-id' label="Country id" type='string' length='3'/>
169
+ <element name="terminal" label="Terminal"/>
170
+ </element>
171
+ </element>
172
+ </schema>`);
173
+ var schema = newSchema(xml);
174
+ var root = schema.root;
175
+
176
+ // Relative path
177
+ await expect(root.findNode("@email")).resolves.toMatchObject({ label: "Email" });
178
+ await expect(root.findNode("country")).resolves.toMatchObject({ label: "Country" });
179
+ await expect(root.findNode("country/@isoA3")).resolves.toMatchObject({ label: "Country name" });
180
+ await expect(root.findNode("country/@country-id")).resolves.toMatchObject({ label: "Country id" });
181
+
182
+ await expect(root.findNode("@dummy")).resolves.toBeFalsy();
183
+ await expect(root.findNode("dummy")).resolves.toBeFalsy();
184
+ await expect(root.findNode("dummy/@dummy")).resolves.toBeFalsy();
185
+ await expect(root.findNode("country/@dummy")).resolves.toBeFalsy();
186
+ await expect(root.findNode("country/dummy/@dummy")).resolves.toBeFalsy();
187
+
188
+ // Starting from schema
189
+ await expect(schema.findNode("recipient")).resolves.toMatchObject({ label: 'Recipients' });
190
+
191
+ // Absolute path (/ means schema root node, not schema node)
192
+ await expect(root.findNode("/@email")).resolves.toMatchObject({ label: "Email" });
193
+ const country = await root.findNode("country");
194
+ await expect(country.findNode("/@email")).resolves.toMatchObject({ label: "Email" });
195
+ await expect(country.findNode("/country")).resolves.toMatchObject({ label: "Country" });
196
+
197
+ // Self and parent
198
+ await expect(country.findNode("./@isoA3")).resolves.toMatchObject({ label: "Country name" });
199
+ await expect(country.findNode("../@email")).resolves.toMatchObject({ label: "Email" });
200
+ await expect(country.findNode(".././@email")).resolves.toMatchObject({ label: "Email" });
201
+ await expect(country.findNode("./../@email")).resolves.toMatchObject({ label: "Email" });
202
+ await expect(root.findNode("./country/..")).resolves.toMatchObject({ label: "Recipients" });
203
+
204
+ // Special cases
205
+ await expect(root.findNode("")).resolves.toMatchObject({ label: "Recipients" });
206
+ await expect(root.findNode(".")).resolves.toMatchObject({ label: "Recipients" });
207
+
208
+ // Non strict
209
+ await expect(root.findNode("country/@isoA3", false, false)).resolves.toMatchObject({ label: "Country name" });
210
+ await expect(root.findNode("country/isoA3", false, false)).resolves.toBeFalsy();
211
+ await expect(country.findNode("@isoA3", false, false)).resolves.toMatchObject({ label: "Country name" });
212
+ await expect(country.findNode("isoA3", false, false)).resolves.toBeFalsy();
213
+ await expect(country.findNode("@terminal", false, false)).resolves.toBeFalsy();
214
+ await expect(country.findNode("terminal", false, false)).resolves.toMatchObject({ label: "Terminal" });
215
+ await expect(country.findNode("@notFound", false, false)).resolves.toBeFalsy();
216
+ await expect(country.findNode("notFound", false, false)).resolves.toBeFalsy();
217
+ });
218
+
219
+ it("Empty or absolute path requires a schema and root node", async () => {
62
220
 
63
- it("Should be root node", () => {
64
- var xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='recipient' label='Recipients'/></schema>");
65
- var schema = newSchema(xml);
66
- var root = schema.root;
67
- expect(root.isRoot).toBe(true);
221
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
222
+ <element name='profile' label='Recipients'>
223
+ <attribute name='email' label="Email" type='string' length='3'/>
224
+ <element name='country' label="Country">
225
+ <attribute name='isoA3' label="Country name" type='string' length='3'/>
226
+ <attribute name='country-id' label="Country id" type='string' length='3'/>
227
+ </element>
228
+ </element>
229
+ </schema>`);
230
+ var schemaNoRoot = newSchema(xml);
231
+ var root = schemaNoRoot.root;
232
+ expect(root).toBeUndefined();
233
+ await expect(schemaNoRoot.findNode("")).resolves.toBeFalsy();
234
+ await expect(schemaNoRoot.findNode("/")).resolves.toBeFalsy();
235
+
236
+ var profile = await schemaNoRoot.findNode("profile");
237
+ expect(profile).toBeTruthy();
238
+ await expect(profile.findNode("country/@isoA3")).resolves.toMatchObject({ label: "Country name" });
239
+ await expect(profile.findNode("/country/@isoA3")).resolves.toBeFalsy();
240
+ await expect(profile.findNode("")).resolves.toBeFalsy();
241
+ });
242
+
243
+ it("Should find node by xpath", async () => {
244
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
245
+ <element name='recipient' label='Recipients'>
246
+ <attribute name='email' label="Email" type='string' length='3'/>
247
+ <element name='country' label="Country">
248
+ <attribute name='isoA3' label="Country name" type='string' length='3'/>
249
+ <attribute name='country-id' label="Country id" type='string' length='3'/>
250
+ </element>
251
+ </element>
252
+ </schema>`);
253
+ var schema = newSchema(xml);
254
+ var root = schema.root;
255
+
256
+ await expect(root.findNode(new XPath("@email"))).resolves.toMatchObject({ label: "Email" });
257
+ });
68
258
  });
69
259
 
70
- it("Should not be root node", () => {
71
- var xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='lib'/><element name='recipient' label='Recipients'/></schema>");
72
- var schema = newSchema(xml);
73
- var lib = schema.children["lib"];
74
- expect(lib.isRoot).toBeFalsy();
75
- });
260
+ describe("Enumerations", () => {
261
+ it("Should list enumerations", () => {
262
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
263
+ <enumeration name="gender" basetype="byte"/>
264
+ <enumeration name="status" basetype="byte"/>
265
+ <element name='recipient' label='Recipients'></element>
266
+ </schema>`);
267
+ var schema = newSchema(xml);
268
+ var enumerations = schema.enumerations;
269
+ expect(enumerations.gender.dummy).toBeFalsy();
270
+ expect(enumerations.gender.shortName).toBe("gender");
271
+ expect(enumerations.status.shortName).toBe("status");
272
+ expect(enumerations.gender.name).toBe("nms:recipient:gender");
273
+ expect(enumerations.status.name).toBe("nms:recipient:status");
274
+ });
275
+
276
+ it("Should support forEach and map", () => {
277
+ const xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
278
+ <enumeration name="gender" basetype="byte"/>
279
+ <enumeration name="status" basetype="byte"/>
280
+ <element name='recipient' label='Recipients'></element>
281
+ </schema>`);
282
+ const schema = newSchema(xml);
283
+ const enumerations = schema.enumerations;
284
+
285
+ // Use forEach to concatenate enumeration names
286
+ let cat = "";
287
+ enumerations.forEach(e => cat = cat + e.name);
288
+ expect(cat).toBe("nms:recipient:gendernms:recipient:status");
289
+
290
+ // Use map to get get an array of enumeration names
291
+ expect(enumerations.map(e => e.name).join(',')).toBe("nms:recipient:gender,nms:recipient:status");
292
+ });
293
+
294
+ it("Should support index based access", () => {
295
+ const xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
296
+ <enumeration name="gender" basetype="byte"/>
297
+ <enumeration name="status" basetype="byte"/>
298
+ <element name='recipient' label='Recipients'></element>
299
+ </schema>`);
300
+ const schema = newSchema(xml);
301
+ const enumerations = schema.enumerations;
302
+ expect(enumerations[0].name).toBe("nms:recipient:gender");
303
+ expect(enumerations[1].name).toBe("nms:recipient:status");
304
+
305
+ // Use a for-loop
306
+ let cat = "";
307
+ for (let i=0; i<enumerations.length; i++)
308
+ cat = cat + enumerations[i].name;
309
+ expect(cat).toBe("nms:recipient:gendernms:recipient:status");
310
+
311
+ // Use the for ... of iterator
312
+ cat = "";
313
+ for (const enumeration of enumerations)
314
+ cat = cat + enumeration.name;
315
+ });
316
+
317
+ it("Should set default label", () => {
318
+ const xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
319
+ <enumeration name="gender" basetype="byte"/>
320
+ <enumeration name="status" basetype="byte" label="Status code"/>
321
+ <element name='recipient' label='Recipients'></element>
322
+ </schema>`);
323
+ const schema = newSchema(xml);
324
+ const enumerations = schema.enumerations;
325
+ expect(enumerations[0].label).toBe("Gender");
326
+ expect(enumerations[1].label).toBe("Status code");
327
+ });
328
+
329
+ it("Should test images", () => {
330
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
331
+ <enumeration name="gender" basetype="byte">
332
+ <value name="male" value="0"/>
333
+ <value name="female" value="1"/>
334
+ </enumeration>
335
+ <enumeration name="status" basetype="byte">
336
+ <value name="prospect" label="Prospect" value="0" img="xtk:prospect"/>
337
+ <value name="customer" label="Client" value="1"/>
338
+ </enumeration>
339
+ <enumeration name="status2" basetype="byte">
340
+ <value name="prospect" label="Prospect" value="0" img=""/>
341
+ <value name="customer" label="Client" value="1" img=""/>
342
+ </enumeration>
343
+ <element name='recipient' label='Recipients'>
344
+ <attribute advanced="true" desc="Recipient sex" enum="nms:recipient:gender"
345
+ label="Gender" name="gender" sqlname="iGender" type="byte"/>
346
+ </element>
347
+ </schema>`);
348
+ var schema = newSchema(xml);
349
+ var enumerations = schema.enumerations;
350
+ // no img attribute
351
+ expect(enumerations.gender.name).toBe("nms:recipient:gender");
352
+ expect(enumerations.gender.hasImage).toBe(false);
353
+ // at least one img attribute
354
+ expect(enumerations.status.name).toBe("nms:recipient:status");
355
+ expect(enumerations.status.hasImage).toBe(true);
356
+ // at least one img attribute
357
+ expect(enumerations.status2.name).toBe("nms:recipient:status2");
358
+ expect(enumerations.status2.hasImage).toBe(false);
359
+ expect(schema.root.children["@gender"].enum).toBe("nms:recipient:gender");
360
+ })
361
+
362
+ it("Should list enumeration values", () => {
363
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
364
+ <enumeration name="gender" basetype="byte"/>
365
+ <enumeration name="status" basetype="byte">
366
+ <value name="prospect" label="Prospect" value="0"/>
367
+ <value name="customer" label="Client" value="1"/>
368
+ </enumeration>
369
+ <element name='recipient' label='Recipients'></element>
370
+ </schema>`);
371
+ var schema = newSchema(xml);
372
+ var enumerations = schema.enumerations;
373
+ expect(enumerations.status.values.prospect.label).toBe("Prospect");
374
+ expect(enumerations.status.values.customer.label).toBe("Client");
375
+ })
376
+
377
+ it("Should support forEach and map on enumeration values", () => {
378
+ const xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
379
+ <enumeration name="gender" basetype="byte"/>
380
+ <enumeration name="status" basetype="byte">
381
+ <value name="prospect" label="Prospect" value="0"/>
382
+ <value name="customer" label="Client" value="1"/>
383
+ </enumeration>
384
+ <element name='recipient' label='Recipients'></element>
385
+ </schema>`);
386
+ const schema = newSchema(xml);
387
+ const enumerations = schema.enumerations;
388
+ const status = enumerations.status.values;
389
+
390
+
391
+ // Use forEach to concatenate enumeration names
392
+ let cat = "";
393
+ status.forEach(e => cat = cat + e.name);
394
+ expect(cat).toBe("prospectcustomer");
395
+
396
+ // Use map to get get an array of enumeration names
397
+ expect(status.map(e => e.name).join(',')).toBe("prospect,customer");
398
+ });
399
+
400
+
401
+ it("Should support index based access", () => {
402
+ const xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
403
+ <enumeration name="gender" basetype="byte"/>
404
+ <enumeration name="status" basetype="byte">
405
+ <value name="prospect" label="Prospect" value="0"/>
406
+ <value name="customer" label="Client" value="1"/>
407
+ </enumeration>
408
+ <element name='recipient' label='Recipients'></element>
409
+ </schema>`);
410
+ const schema = newSchema(xml);
411
+ const enumerations = schema.enumerations;
412
+ const status = enumerations.status.values;
413
+ expect(status[0].name).toBe("prospect");
414
+ expect(status[1].name).toBe("customer");
415
+ });
416
+
417
+ it("Should set default label", () => {
418
+ const xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
419
+ <enumeration name="gender" basetype="byte"/>
420
+ <enumeration name="status" basetype="byte">
421
+ <value name="prospect" value="0"/>
422
+ <value name="customer" label="Client" value="1"/>
423
+ </enumeration>
424
+ <element name='recipient' label='Recipients'></element>
425
+ </schema>`);
426
+ const schema = newSchema(xml);
427
+ const enumerations = schema.enumerations;
428
+ const status = enumerations.status.values;
429
+ expect(status[0].label).toBe("Prospect");
430
+ expect(status[1].label).toBe("Client");
431
+ });
432
+
433
+ it("Byte enumerations", () => {
434
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
435
+ <enumeration basetype="byte" name="instanceType">
436
+ <value label="One-off event" name="single" value="0"/>
437
+ <value label="Reference recurrence" name="master" value="1"/>
438
+ <value label="Instance of a recurrence" name="instance" value="2"/>
439
+ <value label="Exception to a recurrence" name="exception" value="3"/>
440
+ </enumeration>
441
+ <element name='recipient' label='Recipients'></element>
442
+ </schema>`);
443
+ var schema = newSchema(xml);
444
+ var enumerations = schema.enumerations;
445
+ expect(enumerations.instanceType.values.single.label).toBe("One-off event");
446
+ expect(enumerations.instanceType.values.single.value).toBe(0);
447
+ })
76
448
 
77
- it("Should not be root node (second level with same name", () => {
78
- var xml = DomUtil.parse("<schema namespace='nms' name='recipient'><element name='recipient' label='Recipients'><element name='recipient' label='Recipients (inner)'/></element></schema>");
79
- var schema = newSchema(xml);
80
- var root = schema.root;
81
- var inner = root.children["recipient"];
82
- expect(inner.label).toBe("Recipients (inner)")
83
- expect(inner.isRoot).toBe(false);
449
+ it("Should support default values", () => {
450
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
451
+ <enumeration basetype="byte" name="instanceType" default="1">
452
+ <value label="One-off event" name="single" value="0"/>
453
+ <value label="Reference recurrence" name="master" value="1"/>
454
+ <value label="Instance of a recurrence" name="instance" value="2"/>
455
+ <value label="Exception to a recurrence" name="exception" value="3"/>
456
+ </enumeration>
457
+ <element name='recipient' label='Recipients'></element>
458
+ </schema>`);
459
+ var schema = newSchema(xml);
460
+ var enumerations = schema.enumerations;
461
+ expect(enumerations.instanceType.default.value).toBe(1);
462
+ });
463
+
464
+ describe("Using application.getSysEnum", () => {
465
+
466
+ it("Should find simple enumeration (from schema id)", async () => {
467
+ const client = await Mock.makeClient();
468
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
469
+ await client.NLWS.xtkSession.logon();
470
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
471
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
472
+ <SOAP-ENV:Body>
473
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
474
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
475
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
476
+ <enumeration basetype="byte" name="instanceType" default="1" label="Instance type">
477
+ <value label="One-off event" name="single" value="0"/>
478
+ <value label="Reference recurrence" name="master" value="1"/>
479
+ <value label="Instance of a recurrence" name="instance" value="2"/>
480
+ <value label="Exception to a recurrence" name="exception" value="3"/>
481
+ </enumeration>
482
+ </schema>
483
+ </pdomDoc>
484
+ </GetEntityIfMoreRecentResponse>
485
+ </SOAP-ENV:Body>
486
+ </SOAP-ENV:Envelope>`));
487
+ const enumeration = await client.application.getSysEnum("instanceType", "nms:profile");
488
+ expect(enumeration.label).toBe("Instance type");
489
+ });
490
+
491
+ it("Should find node enumeration", async () => {
492
+ const client = await Mock.makeClient();
493
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
494
+ await client.NLWS.xtkSession.logon();
495
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
496
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
497
+ <SOAP-ENV:Body>
498
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
499
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
500
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
501
+ <enumeration basetype="byte" name="instanceType" default="1" label="Instance type">
502
+ <value label="One-off event" name="single" value="0"/>
503
+ <value label="Reference recurrence" name="master" value="1"/>
504
+ <value label="Instance of a recurrence" name="instance" value="2"/>
505
+ <value label="Exception to a recurrence" name="exception" value="3"/>
506
+ </enumeration>
507
+ <element name="profile">
508
+ <attribute name="e" enum="instanceType"/>
509
+ <attribute name="a"/>
510
+ </element>
511
+ </schema>
512
+ </pdomDoc>
513
+ </GetEntityIfMoreRecentResponse>
514
+ </SOAP-ENV:Body>
515
+ </SOAP-ENV:Envelope>`));
516
+ const schema = await client.application.getSchema("nms:profile");
517
+ const e = await schema.findNode('/@e');
518
+ expect(e.enum).toBe("instanceType");
519
+ let enumeration = await e.enumeration();
520
+ expect(enumeration.name).toBe("nms:profile:instanceType");
521
+ // It's possible to pass the name
522
+ enumeration = await e.enumeration("instanceType");
523
+ expect(enumeration.name).toBe("nms:profile:instanceType");
524
+ // Should support the case when attirbute is not an enumeration
525
+ const a = await schema.findNode('/@a');
526
+ enumeration = await a.enumeration("instanceType");
527
+ expect(enumeration.name).toBe("nms:profile:instanceType");
528
+ enumeration = await a.enumeration();
529
+ expect(enumeration).toBeUndefined();
530
+ });
531
+
532
+ it("Should find simple enumeration (from schema)", async () => {
533
+ const client = await Mock.makeClient();
534
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
535
+ await client.NLWS.xtkSession.logon();
536
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
537
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
538
+ <SOAP-ENV:Body>
539
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
540
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
541
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
542
+ <enumeration basetype="byte" name="instanceType" default="1" label="Instance type">
543
+ <value label="One-off event" name="single" value="0"/>
544
+ <value label="Reference recurrence" name="master" value="1"/>
545
+ <value label="Instance of a recurrence" name="instance" value="2"/>
546
+ <value label="Exception to a recurrence" name="exception" value="3"/>
547
+ </enumeration>
548
+ </schema>
549
+ </pdomDoc>
550
+ </GetEntityIfMoreRecentResponse>
551
+ </SOAP-ENV:Body>
552
+ </SOAP-ENV:Envelope>`));
553
+ const schema = await client.application.getSchema("nms:profile");
554
+ const enumeration = await client.application.getSysEnum("instanceType", schema);
555
+ expect(enumeration.label).toBe("Instance type");
556
+ });
557
+
558
+ it("Should find fully qualified enumeration (in the same schema)", async () => {
559
+ const client = await Mock.makeClient();
560
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
561
+ await client.NLWS.xtkSession.logon();
562
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
563
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
564
+ <SOAP-ENV:Body>
565
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
566
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
567
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
568
+ <enumeration basetype="byte" name="instanceType" default="1" label="Instance type">
569
+ <value label="One-off event" name="single" value="0"/>
570
+ <value label="Reference recurrence" name="master" value="1"/>
571
+ <value label="Instance of a recurrence" name="instance" value="2"/>
572
+ <value label="Exception to a recurrence" name="exception" value="3"/>
573
+ </enumeration>
574
+ </schema>
575
+ </pdomDoc>
576
+ </GetEntityIfMoreRecentResponse>
577
+ </SOAP-ENV:Body>
578
+ </SOAP-ENV:Envelope>`));
579
+ const schema = await client.application.getSchema("nms:profile");
580
+ const enumeration = await client.application.getSysEnum("nms:profile:instanceType", schema);
581
+ expect(enumeration.label).toBe("Instance type");
582
+ });
583
+
584
+ it("Should find fully qualified enumeration (in a different schema)", async () => {
585
+ const client = await Mock.makeClient();
586
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
587
+ await client.NLWS.xtkSession.logon();
588
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
589
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
590
+ <SOAP-ENV:Body>
591
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
592
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
593
+ <schema name="recipient" namespace="nms" xtkschema="xtk:schema">
594
+ <element name="recipient">
595
+ <attribute name="status" enum="nms:profile:instanceType"/>
596
+ </element>
597
+ </schema>
598
+ </pdomDoc>
599
+ </GetEntityIfMoreRecentResponse>
600
+ </SOAP-ENV:Body>
601
+ </SOAP-ENV:Envelope>`));
602
+ const schema = await client.application.getSchema("nms:recipient");
603
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
604
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
605
+ <SOAP-ENV:Body>
606
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
607
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
608
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
609
+ <enumeration basetype="byte" name="instanceType" default="1" label="Instance type">
610
+ <value label="One-off event" name="single" value="0"/>
611
+ <value label="Reference recurrence" name="master" value="1"/>
612
+ <value label="Instance of a recurrence" name="instance" value="2"/>
613
+ <value label="Exception to a recurrence" name="exception" value="3"/>
614
+ </enumeration>
615
+ </schema>
616
+ </pdomDoc>
617
+ </GetEntityIfMoreRecentResponse>
618
+ </SOAP-ENV:Body>
619
+ </SOAP-ENV:Envelope>`));
620
+ const node = await schema.root.findNode("@status");
621
+ const enumeration = await client.application.getSysEnum(node.enum, schema);
622
+ expect(enumeration.label).toBe("Instance type");
623
+ });
624
+
625
+ it("Should fail if malformed enumeration name", async () => {
626
+ const client = await Mock.makeClient();
627
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
628
+ await client.NLWS.xtkSession.logon();
629
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
630
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
631
+ <SOAP-ENV:Body>
632
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
633
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
634
+ <schema name="recipient" namespace="nms" xtkschema="xtk:schema">
635
+ <element name="recipient">
636
+ <attribute name="status" enum="nms:profile:instanceType"/>
637
+ </element>
638
+ </schema>
639
+ </pdomDoc>
640
+ </GetEntityIfMoreRecentResponse>
641
+ </SOAP-ENV:Body>
642
+ </SOAP-ENV:Envelope>`));
643
+ const schema = await client.application.getSchema("nms:recipient");
644
+ await expect(client.application.getSysEnum("nms:profile", schema)).rejects.toMatchObject({ message: "Invalid enumeration name 'nms:profile': expecting {name} or {schemaId}:{name}" });
645
+ });
646
+
647
+ it("Should not find enumeration if schema is missing", async () => {
648
+ const client = await Mock.makeClient();
649
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
650
+ await client.NLWS.xtkSession.logon();
651
+ client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
652
+ const enumeration = await client.application.getSysEnum("instanceType", "nms:profile");
653
+ expect(enumeration).toBeFalsy();
654
+ });
655
+
656
+ it("Should not find enumeration if no schema", async () => {
657
+ const client = await Mock.makeClient();
658
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
659
+ await client.NLWS.xtkSession.logon();
660
+ let enumeration = await client.application.getSysEnum("instanceType", undefined);
661
+ expect(enumeration).toBeFalsy();
662
+ enumeration = await client.application.getSysEnum("instanceType", null);
663
+ expect(enumeration).toBeFalsy();
664
+ });
665
+
666
+ it("Should not find enumeration if schema is missing (local enum)", async () => {
667
+ const client = await Mock.makeClient();
668
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
669
+ await client.NLWS.xtkSession.logon();
670
+ client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
671
+ const enumeration = await client.application.getSysEnum("instanceType", "nms:profile");
672
+ expect(enumeration).toBeFalsy();
673
+ });
674
+
675
+ it("Should not find enumeration if schema is missing (fully qualified enum)", async () => {
676
+ const client = await Mock.makeClient();
677
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
678
+ await client.NLWS.xtkSession.logon();
679
+ client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
680
+ const enumeration = await client.application.getSysEnum("nms:recipient:instanceType", "nms:profile");
681
+ expect(enumeration).toBeFalsy();
682
+ });
683
+ });
84
684
  });
85
- })
86
685
 
87
- describe("Attributes", () => {
686
+ describe("Keys", () => {
687
+ it("Should have key", () => {
688
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
689
+ <element name='recipient' label='Recipients'>
690
+ <key name="test">
691
+ <keyfield xpath="@email"/>
692
+ </key>
693
+ <attribute name='email' type='string' length='3'/>
694
+ </element>
695
+ </schema>`);
696
+ var schema = newSchema(xml);
697
+ var root = schema.root;
698
+ expect(root.keys.test).toBeTruthy();
699
+ expect(root.keys.test.fields["email"]).toBeFalsy();
700
+ expect(root.keys.test.fields["@email"]).toBeTruthy();
701
+ })
702
+
703
+ it("Should fail if keyfield does not have xpath", () => {
704
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
705
+ <element name='recipient' label='Recipients'>
706
+ <key name="test">
707
+ <keyfield/>
708
+ </key>
709
+ <attribute name='email' type='string' length='3'/>
710
+ </element>
711
+ </schema>`);
712
+ expect(() => { newSchema(xml) }).toThrow("keyfield does not have an xpath attribute");
713
+ });
88
714
 
89
- it("Should find unique attribute", () => {
90
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
91
- <element name='recipient' label='Recipients'>
92
- <attribute name='email' type='string' length='3'/>
93
- </element>
94
- </schema>`);
95
- var schema = newSchema(xml);
96
- var root = schema.root;
97
- expect(root.hasChild("@email")).toBe(true);
98
- var email = root.children["@email"];
99
- expect(email).not.toBeNull();
100
- expect(email.name).toBe("@email");
101
- expect(email.type).toBe("string");
102
- expect(email.length).toBe(3);
103
- });
715
+ it("Should ignore missing xpaths", () => {
716
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
717
+ <element name='recipient' label='Recipients'>
718
+ <key name="test">
719
+ <keyfield xpath="@nontFound"/>
720
+ </key>
721
+ </element>
722
+ </schema>`);
723
+ var schema = newSchema(xml);
724
+ var root = schema.root;
725
+ expect(root.keys.test).toBeTruthy();
726
+ expect(root.keys.test.fields["nontFound"]).toBeFalsy();
727
+ });
104
728
 
105
- it("Should not find inexistant attribute", () => {
106
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
107
- <element name='recipient' label='Recipients'>
108
- <attribute name='email' type='string' length='3'/>
109
- </element>
110
- </schema>`);
111
- var schema = newSchema(xml);
112
- var root = schema.root;
113
- expect(root.hasChild("email")).toBe(false);
114
- expect(root.hasChild("@dummy")).toBe(false);
729
+ it("Should get first key (internal & external)", () => {
730
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
731
+ <element name='recipient' label='Recipients'>
732
+ <key name="key1">
733
+ <keyfield xpath="@email"/>
734
+ </key>
735
+ <key name="key2" internal="true">
736
+ <keyfield xpath="@id"/>
737
+ </key>
738
+ <attribute name='id' type='string'/>
739
+ <attribute name='email' type='string'/>
740
+ </element>
741
+ </schema>`);
742
+ var schema = newSchema(xml);
743
+ var root = schema.root;
744
+ expect(root.firstInternalKeyDef()).toMatchObject({ name: 'key2', isInternal: true });
745
+ expect(root.firstExternalKeyDef()).toMatchObject({ name: 'key1', isInternal: false });
746
+ expect(root.firstKeyDef()).toMatchObject({ name: 'key2', isInternal: true });
747
+ });
748
+
749
+ it("Should get first key (external only)", () => {
750
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
751
+ <element name='recipient' label='Recipients'>
752
+ <key name="key1">
753
+ <keyfield xpath="@email"/>
754
+ </key>
755
+ <key name="key2">
756
+ <keyfield xpath="@id"/>
757
+ </key>
758
+ <attribute name='id' type='string'/>
759
+ <attribute name='email' type='string'/>
760
+ </element>
761
+ </schema>`);
762
+ var schema = newSchema(xml);
763
+ var root = schema.root;
764
+ expect(root.firstInternalKeyDef()).toBeUndefined();
765
+ expect(root.firstExternalKeyDef()).toMatchObject({ name: 'key1', isInternal: false });
766
+ expect(root.firstKeyDef()).toMatchObject({ name: 'key1', isInternal: false });
767
+ });
115
768
  });
116
769
 
117
- it("Should not find inexistant attribute (@-syntax)", () => {
118
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
770
+ describe("Link", () => {
771
+ it("Should have a link element", () => {
772
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
773
+ <element name='recipient' label='Recipients'>
774
+ <element integrity="neutral" label="Info on the email" name="emailInfo"
775
+ target="nms:address" type="link" unbound="true">
776
+ <join xpath-dst="@address" xpath-src="@email"/>
777
+ <join xpath-dst="@dst" xpath-src="@source"/>
778
+ </element>
779
+ </element>
780
+ </schema>`);
781
+ var schema = newSchema(xml);
782
+ var link = schema.root.children["emailInfo"];
783
+ expect(link.target).toBe("nms:address");
784
+ expect(link.integrity).toBe("neutral");
785
+ expect(link.isUnbound()).toBe(true);
786
+ expect(link.joins.length).toBe(2);
787
+ expect(link.joins[0].dst).toBe("@address");
788
+ expect(link.joins[0].src).toBe("@email");
789
+
790
+ xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
119
791
  <element name='recipient' label='Recipients'>
120
- <attribute name='email' type='string' length='3'/>
792
+ <element integrity="neutral" label="Info on the email" name="emailInfo"
793
+ target="nms:address" type="link">
794
+ <join xpath-dst="@address" xpath-src="@email"/>
795
+ <join xpath-dst="@dst" xpath-src="@source"/>
796
+ </element>
121
797
  </element>
122
798
  </schema>`);
123
- var schema = newSchema(xml);
124
- var root = schema.root;
125
- expect(root.hasChild("@email")).toBe(true);
126
- expect(root.hasChild("email")).toBe(false);
799
+ schema = newSchema(xml);
800
+ link = schema.root.children["emailInfo"];
801
+ expect(link.isUnbound()).toBe(false);
802
+ });
803
+
804
+ it("Should get target", async() => {
805
+ const client = await Mock.makeClient();
806
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
807
+ await client.NLWS.xtkSession.logon();
808
+
809
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
810
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
811
+ <SOAP-ENV:Body>
812
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
813
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
814
+ <schema namespace='nms' name='recipient'>
815
+ <element name='recipient' label='Recipients'>
816
+ <element name="country" type="link" target="nms:country"/>
817
+ </element>
818
+ </schema>
819
+ </pdomDoc>
820
+ </GetEntityIfMoreRecentResponse>
821
+ </SOAP-ENV:Body>
822
+ </SOAP-ENV:Envelope>`));
823
+ const recipient = await client.application.getSchema('nms:recipient');
824
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
825
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
826
+ <SOAP-ENV:Body>
827
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
828
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
829
+ <schema namespace='nms' name='country'>
830
+ <element name='country' label="The Country">
831
+ <attribute name="isoA3" label="Country code"/>
832
+ </element>
833
+ </schema>
834
+ </pdomDoc>
835
+ </GetEntityIfMoreRecentResponse>
836
+ </SOAP-ENV:Body>
837
+ </SOAP-ENV:Envelope>`));
838
+ const country = await recipient.root.findNode("country");
839
+ expect(country.target).toBe("nms:country");
840
+ const target = await country.linkTarget();
841
+ expect(target.label).toBe("The Country");
842
+ })
127
843
  });
128
- });
129
844
 
130
- describe("Children", () => {
131
- it("Should browse root children", () => {
132
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
133
- <element name='recipient' label='Recipients'>
134
- <attribute name='email' type='string' length='3'/>
135
- </element>
136
- <element name='lib'/>
137
- </schema>`);
138
- var schema = newSchema(xml);
139
- expect(schema.childrenCount).toBe(2);
140
- expect(schema.children["recipient"]).not.toBeNull();
141
- expect(schema.children["lib"]).not.toBeNull();
142
- expect(schema.children["dummy"]).toBeFalsy();
845
+ describe("Joins", () => {
846
+
847
+ it("Should find join nodes", async () => {
848
+ // The schema in the ref does not exist
849
+ const client = await Mock.makeClient();
850
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
851
+ await client.NLWS.xtkSession.logon();
852
+
853
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
854
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
855
+ <SOAP-ENV:Body>
856
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
857
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
858
+ <schema namespace='nms' name='recipient'>
859
+ <element name='recipient'>
860
+ <element integrity="neutral" label="Info on the email" name="emailInfo" target="nms:address" type="link" unbound="true">
861
+ <join xpath-dst="@address" xpath-src="@email"/>
862
+ <join xpath-dst="@dst" xpath-src="@source"/>
863
+ </element>
864
+ <attribute name="email"/>
865
+ <attribute name="source"/>
866
+ </element>
867
+ </schema>
868
+ </pdomDoc>
869
+ </GetEntityIfMoreRecentResponse>
870
+ </SOAP-ENV:Body>
871
+ </SOAP-ENV:Envelope>`));
872
+ const recipient = await client.application.getSchema('nms:recipient');
873
+ expect(recipient).toBeTruthy();
874
+
875
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
876
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
877
+ <SOAP-ENV:Body>
878
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
879
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
880
+ <schema namespace='nms' name='address'>
881
+ <element name='address'>
882
+ <attribute name="dst"/>
883
+ <attribute name="address"/>
884
+ </element>
885
+ </schema>
886
+ </pdomDoc>
887
+ </GetEntityIfMoreRecentResponse>
888
+ </SOAP-ENV:Body>
889
+ </SOAP-ENV:Envelope>`));
890
+ const address = await client.application.getSchema('nms:address');
891
+ expect(address).toBeTruthy();
892
+
893
+ // Check link attributes
894
+ const link = await recipient.root.findNode("emailInfo");
895
+ expect(link.isExternalJoin).toBe(false);
896
+
897
+ // "joins" gives a description of the link source and destination xpaths
898
+ expect(link.joins.length).toBe(2);
899
+ expect(link.joins).toMatchObject([ { src: "@email", dst: "@address" }, { src: "@source", dst: "@dst" } ]);
900
+
901
+ // "joinNodes" will lookup the corresponding nodes in the source and target schemas
902
+ const nodes = await link.joinNodes();
903
+ expect(nodes.length).toBe(2);
904
+ expect(nodes[0].source).toMatchObject({ name:"@email", label: "Email" });
905
+ expect(nodes[0].destination).toMatchObject({ name:"@address", label: "Address" });
906
+ expect(nodes[1].source).toMatchObject({ name:"@source", label: "Source" });
907
+ expect(nodes[1].destination).toMatchObject({ name:"@dst", label: "Dst" });
908
+ });
909
+
910
+ it("Should find join nodes with paths", async () => {
911
+ // The schema in the ref does not exist
912
+ const client = await Mock.makeClient();
913
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
914
+ await client.NLWS.xtkSession.logon();
915
+
916
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
917
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
918
+ <SOAP-ENV:Body>
919
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
920
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
921
+ <schema namespace='nms' name='recipient'>
922
+ <element name='recipient'>
923
+ <element name="countryLink" type="link" externalJoin="true" target="nms:country" revLink="operator" revIntegrity="normal">
924
+ <join xpath-dst="@isoA2" xpath-src="location/@countryCode"/>
925
+ </element>
926
+ <element name="location">
927
+ <attribute name="countryCode" label="Country Code"/>
928
+ </element>
929
+ </element>
930
+ </schema>
931
+ </pdomDoc>
932
+ </GetEntityIfMoreRecentResponse>
933
+ </SOAP-ENV:Body>
934
+ </SOAP-ENV:Envelope>`));
935
+ const recipient = await client.application.getSchema('nms:recipient');
936
+ expect(recipient).toBeTruthy();
937
+
938
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
939
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
940
+ <SOAP-ENV:Body>
941
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
942
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
943
+ <schema namespace='nms' name='country'>
944
+ <element name='country'>
945
+ <attribute name="isoA2"/>
946
+ </element>
947
+ </schema>
948
+ </pdomDoc>
949
+ </GetEntityIfMoreRecentResponse>
950
+ </SOAP-ENV:Body>
951
+ </SOAP-ENV:Envelope>`));
952
+ const country = await client.application.getSchema('nms:country');
953
+ expect(country).toBeTruthy();
954
+
955
+ // Check link attributes
956
+ const link = await recipient.root.findNode("countryLink");
957
+ expect(link.isExternalJoin).toBe(true);
958
+
959
+ // "joins" gives a description of the link source and destination xpaths
960
+ expect(link.joins.length).toBe(1);
961
+ expect(link.joins).toMatchObject([ { src: "location/@countryCode", dst: "@isoA2" } ]);
962
+
963
+ // "joinNodes" will lookup the corresponding nodes in the source and target schemas
964
+ const nodes = await link.joinNodes();
965
+ expect(nodes.length).toBe(1);
966
+ expect(nodes[0].source).toMatchObject({ name:"@countryCode", label: "Country Code" });
967
+ expect(nodes[0].destination).toMatchObject({ name:"@isoA2", label: "IsoA2" });
968
+ });
969
+
970
+ it("Should support empty joins", async () => {
971
+ const client = await Mock.makeClient();
972
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
973
+ await client.NLWS.xtkSession.logon();
974
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
975
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
976
+ <SOAP-ENV:Body>
977
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
978
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
979
+ <schema namespace='nms' name='recipient'>
980
+ <element name='recipient'>
981
+ <element name="countryLink" type="link" target="nms:country">
982
+ </element>
983
+ </element>
984
+ </schema>
985
+ </pdomDoc>
986
+ </GetEntityIfMoreRecentResponse>
987
+ </SOAP-ENV:Body>
988
+ </SOAP-ENV:Envelope>`));
989
+ const recipient = await client.application.getSchema('nms:recipient');
990
+ expect(recipient).toBeTruthy();
991
+ const link = await recipient.root.findNode("countryLink");
992
+ expect(link.joins).toMatchObject([]);
993
+ const nodes = await link.joinNodes();
994
+ expect(nodes).toMatchObject([]);
995
+ client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
996
+ const reverseLink = await link.reverseLink();
997
+ expect(reverseLink).toBeFalsy();
998
+ });
999
+
1000
+ it("Should support non-links", async () => {
1001
+ const client = await Mock.makeClient();
1002
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1003
+ await client.NLWS.xtkSession.logon();
1004
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1005
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1006
+ <SOAP-ENV:Body>
1007
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1008
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1009
+ <schema namespace='nms' name='recipient'>
1010
+ <element name='recipient'>
1011
+ <element name="countryName" type="string">
1012
+ </element>
1013
+ </element>
1014
+ </schema>
1015
+ </pdomDoc>
1016
+ </GetEntityIfMoreRecentResponse>
1017
+ </SOAP-ENV:Body>
1018
+ </SOAP-ENV:Envelope>`));
1019
+ const recipient = await client.application.getSchema('nms:recipient');
1020
+ expect(recipient).toBeTruthy();
1021
+ const link = await recipient.root.findNode("countryName");
1022
+ expect(link.joins).toMatchObject([]);
1023
+ const nodes = await link.joinNodes();
1024
+ expect(nodes).toBeFalsy();
1025
+ const reverseLink = await link.reverseLink();
1026
+ expect(reverseLink).toBeFalsy();
1027
+ });
1028
+
1029
+ it("Should support missing target schema", async () => {
1030
+ const client = await Mock.makeClient();
1031
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1032
+ await client.NLWS.xtkSession.logon();
1033
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1034
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1035
+ <SOAP-ENV:Body>
1036
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1037
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1038
+ <schema namespace='nms' name='recipient'>
1039
+ <element name='recipient'>
1040
+ <element name="countryLink" type="link" target="cus:missing">
1041
+ </element>
1042
+ </element>
1043
+ </schema>
1044
+ </pdomDoc>
1045
+ </GetEntityIfMoreRecentResponse>
1046
+ </SOAP-ENV:Body>
1047
+ </SOAP-ENV:Envelope>`));
1048
+ const recipient = await client.application.getSchema('nms:recipient');
1049
+ expect(recipient).toBeTruthy();
1050
+ client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
1051
+ const link = await recipient.root.findNode("countryLink");
1052
+ expect(link.joins).toMatchObject([]);
1053
+ const nodes = await link.joinNodes();
1054
+ expect(nodes).toMatchObject([]);
1055
+ const reverseLink = await link.reverseLink();
1056
+ expect(reverseLink).toBeFalsy();
1057
+ });
1058
+
1059
+ it("Should support missing destination", async () => {
1060
+ const client = await Mock.makeClient();
1061
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1062
+ await client.NLWS.xtkSession.logon();
1063
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1064
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1065
+ <SOAP-ENV:Body>
1066
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1067
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1068
+ <schema namespace='nms' name='recipient'>
1069
+ <element name='recipient'>
1070
+ <element name="countryLink" type="link" target="nms:country">
1071
+ <join xpath-dst="@notFound" xpath-src="@countryCode"/>
1072
+ </element>
1073
+ <attribute name="countryCode"/>
1074
+ </element>
1075
+ </schema>
1076
+ </pdomDoc>
1077
+ </GetEntityIfMoreRecentResponse>
1078
+ </SOAP-ENV:Body>
1079
+ </SOAP-ENV:Envelope>`));
1080
+ const recipient = await client.application.getSchema('nms:recipient');
1081
+ expect(recipient).toBeTruthy();
1082
+ client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
1083
+ const link = await recipient.root.findNode("countryLink");
1084
+ expect(link.joins).toMatchObject([ { src:"@countryCode", dst:"@notFound" }]);
1085
+
1086
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1087
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1088
+ <SOAP-ENV:Body>
1089
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1090
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1091
+ <schema namespace='nms' name='country'>
1092
+ <element name='country'>
1093
+ <attribute name="isoA2"/>
1094
+ </element>
1095
+ </schema>
1096
+ </pdomDoc>
1097
+ </GetEntityIfMoreRecentResponse>
1098
+ </SOAP-ENV:Body>
1099
+ </SOAP-ENV:Envelope>`));
1100
+
1101
+ const nodes = await link.joinNodes();
1102
+ expect(nodes).toMatchObject([]);
1103
+ const reverseLink = await link.reverseLink();
1104
+ expect(reverseLink).toBeFalsy();
1105
+ });
1106
+
1107
+ it("Should find the reverse link", async () => {
1108
+ // The schema in the ref does not exist
1109
+ const client = await Mock.makeClient();
1110
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1111
+ await client.NLWS.xtkSession.logon();
1112
+
1113
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1114
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1115
+ <SOAP-ENV:Body>
1116
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1117
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1118
+ <schema namespace='nms' name='recipient'>
1119
+ <element name='recipient'>
1120
+ <element advanced="true" externalJoin="true" label="Info on the email" name="emailInfo" revLink="recipient" target="nms:address" type="link" unbound="false">
1121
+ <join xpath-dst="@address" xpath-src="@email"/>
1122
+ </element>
1123
+ <attribute name="email"/>
1124
+ </element>
1125
+ </schema>
1126
+ </pdomDoc>
1127
+ </GetEntityIfMoreRecentResponse>
1128
+ </SOAP-ENV:Body>
1129
+ </SOAP-ENV:Envelope>`));
1130
+ const recipient = await client.application.getSchema('nms:recipient');
1131
+ expect(recipient).toBeTruthy();
1132
+
1133
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1134
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1135
+ <SOAP-ENV:Body>
1136
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1137
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1138
+ <schema namespace='nms' name='address'>
1139
+ <element name='address'>
1140
+ <element advanced="false" externalJoin="false" label="Recipients" name="recipient" revLink="emailInfo" target="nms:recipient" type="link" unbound="true">
1141
+ <join xpath-dst="@email" xpath-src="@address"/>
1142
+ </element>
1143
+ </element>
1144
+ </schema>
1145
+ </pdomDoc>
1146
+ </GetEntityIfMoreRecentResponse>
1147
+ </SOAP-ENV:Body>
1148
+ </SOAP-ENV:Envelope>`));
1149
+ const address = await client.application.getSchema('nms:address');
1150
+ expect(address).toBeTruthy();
1151
+
1152
+ // Check link attributes
1153
+ const link = await recipient.root.findNode("emailInfo");
1154
+ expect(link.isExternalJoin).toBe(true);
1155
+ expect(link.revLink).toBe("recipient");
1156
+
1157
+ // Check revlink
1158
+ const revLink = await link.reverseLink();
1159
+ expect(revLink).toMatchObject({
1160
+ isExternalJoin: false,
1161
+ revLink: "emailInfo",
1162
+ name: "recipient",
1163
+ joins: [ { src:"@address", dst:"@email" }]
1164
+ });
1165
+ });
143
1166
  });
144
- });
145
1167
 
146
- describe("Find node", () => {
1168
+ describe("getnodepath", () => {
147
1169
 
148
- it("Should find nodes", () => {
149
1170
  var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
150
- <element name='recipient' label='Recipients'>
151
- <attribute name='email' label="Email" type='string' length='3'/>
152
- <element name='country' label="Country">
153
- <attribute name='isoA3' label="Country name" type='string' length='3'/>
154
- <attribute name='country-id' label="Country id" type='string' length='3'/>
155
- <element name="terminal" label="Terminal"/>
156
- </element>
157
- </element>
158
- </schema>`);
159
- var schema = newSchema(xml);
160
- var root = schema.root;
161
-
162
- // Relative path
163
- expect(root.findNode("@email").label).toBe("Email");
164
- expect(root.findNode("country").label).toBe("Country");
165
- expect(root.findNode("country/@isoA3").label).toBe("Country name");
166
- expect(root.findNode("country/@country-id").label).toBe("Country id");
167
-
168
- // Not found (defaut behavior throws)
169
- expect(() => { root.findNode("@dummy"); }).toThrow("Unknown attribute 'dummy'");
170
- expect(() => { root.findNode("dummy"); }).toThrow("Unknown element 'dummy'");
171
- expect(() => { root.findNode("dummy/@dummy"); }).toThrow("Unknown element 'dummy'");
172
- expect(() => { root.findNode("country/@dummy"); }).toThrow("Unknown attribute 'dummy'");
173
- expect(() => { root.findNode("country/dummy/@dummy"); }).toThrow("Unknown element 'dummy'");
174
-
175
- // Not found (mustExists=false)
176
- expect(root.findNode("@dummy", true, false)).toBeNull();
177
- expect(root.findNode("dummy", true, false)).toBeNull();
178
- expect(root.findNode("dummy/@dummy", true, false)).toBeNull();
179
- expect(root.findNode("country/@dummy", true, false)).toBeNull();
180
-
181
- // Starting from schema
182
- expect(schema.findNode("recipient").label).toBe('Recipients');
183
-
184
- // Absolute path
185
- expect(root.findNode("/@email").label).toBe("Email");
186
- const country = root.findNode("country");
187
- expect(country.findNode("/@email").label).toBe("Email");
188
- expect(country.findNode("/country").label).toBe("Country");
189
-
190
- // Self and parent
191
- expect(country.findNode("./@isoA3").label).toBe("Country name");
192
- expect(country.findNode("../@email").label).toBe("Email");
193
- expect(country.findNode(".././@email").label).toBe("Email");
194
- expect(country.findNode("./../@email").label).toBe("Email");
195
- expect(root.findNode("./country/..").label).toBe("Recipients");
196
-
197
- // Special cases
198
- expect(root.findNode("").label).toBe("Recipients");
199
- expect(root.findNode(".").label).toBe("Recipients");
200
-
201
- // Non strict
202
- expect(root.findNode("country/@isoA3", false, false).label).toBe("Country name");
203
- expect(root.findNode("country/isoA3", false, false).label).toBe("Country name");
204
- expect(country.findNode("@isoA3", false, false).label).toBe("Country name");
205
- expect(country.findNode("isoA3", false, false).label).toBe("Country name");
206
- expect(country.findNode("@terminal", false, false).label).toBe("Terminal");
207
- expect(country.findNode("terminal", false, false).label).toBe("Terminal");
208
- expect(country.findNode("@notFound", false, false)).toBeNull();
209
- expect(country.findNode("notFound", false, false)).toBeNull();
210
-
211
- // strict
212
- expect(root.findNode("country/@isoA3", true, false).label).toBe("Country name");
213
- expect(root.findNode("country/isoA3", true, false)).toBeNull();
214
- expect(country.findNode("@isoA3", true, false).label).toBe("Country name");
215
- expect(country.findNode("isoA3", true, false)).toBeNull();
216
- expect(country.findNode("@terminal", true, false)).toBeNull();
217
- expect(country.findNode("terminal", true, false).label).toBe("Terminal");
218
- expect(country.findNode("@notFound", true, false)).toBeNull();
219
- expect(country.findNode("notFound", true, false)).toBeNull();
1171
+ <element name='recipient' label='Recipients'>
1172
+ <attribute name='email' type='string' length='3'/>
1173
+ <element name="country">
1174
+ <attribute name='name'/>
1175
+ </element>
1176
+ </element>
1177
+ </schema>`);
1178
+
1179
+ it("Should support nodePath property", async () => {
1180
+ var schema = newSchema(xml);
1181
+ var root = schema.root;
1182
+ var email = await root.findNode("@email");
1183
+ var country = await root.findNode("country");
1184
+ var name = await country.findNode("@name");
1185
+ expect(schema.nodePath).toBe("/recipient");
1186
+ expect(root.nodePath).toBe("/");
1187
+ expect(email.nodePath).toBe("/@email");
1188
+ expect(country.nodePath).toBe("/country");
1189
+ expect(name.nodePath).toBe("/country/@name");
1190
+ });
1191
+
1192
+ it("_getNodePath", async () => {
1193
+ var schema = newSchema(xml);
1194
+ var root = schema.root;
1195
+ var email = await root.findNode("@email");
1196
+ var country = await root.findNode("country");
1197
+ var name = await country.findNode("@name");
1198
+
1199
+ // No parameters => absolute
1200
+ expect(schema._getNodePath()._path).toBe("/recipient");
1201
+ expect(root._getNodePath()._path).toBe("/");
1202
+ expect(email._getNodePath()._path).toBe("/@email");
1203
+ expect(country._getNodePath()._path).toBe("/country");
1204
+ expect(name._getNodePath()._path).toBe("/country/@name");
1205
+
1206
+ // Absolute
1207
+ expect(schema._getNodePath(true)._path).toBe("/recipient");
1208
+ expect(root._getNodePath(true)._path).toBe("/");
1209
+ expect(email._getNodePath(true)._path).toBe("/@email");
1210
+ expect(country._getNodePath(true)._path).toBe("/country");
1211
+ expect(name._getNodePath(true)._path).toBe("/country/@name");
1212
+
1213
+ // Relative
1214
+ expect(schema._getNodePath(false)._path).toBe("recipient");
1215
+ expect(root._getNodePath(false)._path).toBe("");
1216
+ expect(email._getNodePath(false)._path).toBe("@email");
1217
+ expect(country._getNodePath(false)._path).toBe("country");
1218
+ expect(name._getNodePath(false)._path).toBe("country/@name");
1219
+ });
220
1220
  });
221
1221
 
222
-
223
- it("Empty or absolute path requires a schema and root node", () => {
1222
+ describe("Ref target", () => {
224
1223
 
225
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
226
- <element name='profile' label='Recipients'>
227
- <attribute name='email' label="Email" type='string' length='3'/>
228
- <element name='country' label="Country">
229
- <attribute name='isoA3' label="Country name" type='string' length='3'/>
230
- <attribute name='country-id' label="Country id" type='string' length='3'/>
231
- </element>
1224
+ it("Should follow ref", async () => {
1225
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1226
+ <element name='recipient' label='Recipients'>
1227
+ <element name="myAddress" ref="address"/>
1228
+ </element>
1229
+ <element name='address'>
1230
+ <element name="country">
1231
+ <attribute name='name' label="Country Name"/>
232
1232
  </element>
233
- </schema>`);
234
- var schemaNoRoot = newSchema(xml);
235
- var root = schemaNoRoot.root;
236
- expect(root).toBeUndefined();
237
- expect(() => { schemaNoRoot.findNode("") }).toThrow("does not have a root node");
238
- expect(() => { schemaNoRoot.findNode("/") }).toThrow("does not have a root node");
239
-
240
- var profile = schemaNoRoot.findNode("profile");
241
- expect(profile).toBeTruthy();
242
- expect(profile.findNode("country/@isoA3").label).toBe("Country name");
243
- expect(() => { profile.findNode("/country/@isoA3") }).toThrow("does not have a root node");
244
- expect(() => { profile.findNode("") }).toThrow("does not have a root node");
245
- });
246
-
247
- it("Should find node by xpath", () => {
248
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
249
- <element name='recipient' label='Recipients'>
250
- <attribute name='email' label="Email" type='string' length='3'/>
251
- <element name='country' label="Country">
252
- <attribute name='isoA3' label="Country name" type='string' length='3'/>
253
- <attribute name='country-id' label="Country id" type='string' length='3'/>
254
- </element>
255
- </element>
256
- </schema>`);
257
- var schema = newSchema(xml);
258
- var root = schema.root;
259
-
260
- expect(root.findNode(new XPath("@email")).label).toBe("Email");
1233
+ </element>
1234
+ </schema>`);
1235
+ var schema = newSchema(xml);
1236
+ // Pointing to the node with ref itself => return it
1237
+ var node = await schema.root.findNode("myAddress");
1238
+ expect(node).toMatchObject({ name:"myAddress", ref:"address", childrenCount:0 });
1239
+ // Follow ref
1240
+ let target = await node.refTarget();
1241
+ expect(target).toMatchObject({ name:"address", ref:"", childrenCount:1 });
1242
+ });
1243
+
1244
+ it("Should support nodes with no ref", async () => {
1245
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1246
+ <element name='address'>
1247
+ <element name="country">
1248
+ <attribute name='name' label="Country Name"/>
1249
+ </element>
1250
+ </element>
1251
+ </schema>`);
1252
+ var schema = newSchema(xml);
1253
+ var node = await schema.findNode("address");
1254
+ var target = await node.refTarget();
1255
+ expect(target).toBeFalsy();
1256
+ });
261
1257
  });
262
1258
 
263
- });
264
-
265
- describe("Enumerations", () => {
266
- it("Should list enumerations", () => {
267
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
268
- <enumeration name="gender" basetype="byte"/>
269
- <enumeration name="status" basetype="byte"/>
270
- <element name='recipient' label='Recipients'></element>
271
- </schema>`);
272
- var schema = newSchema(xml);
273
- var enumerations = schema.enumerations;
274
- expect(enumerations.gender.dummy).toBeFalsy();
275
- expect(enumerations.gender.name).toBe("gender");
276
- expect(enumerations.status.name).toBe("status");
277
- })
278
-
279
- it("Should test images", () => {
280
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
281
- <enumeration name="gender" basetype="byte">
282
- <value name="male" value="0"/>
283
- <value name="female" value="1"/>
284
- </enumeration>
285
- <enumeration name="status" basetype="byte">
286
- <value name="prospect" label="Prospect" value="0" img="xtk:prospect"/>
287
- <value name="customer" label="Client" value="1"/>
288
- </enumeration>
289
- <enumeration name="status2" basetype="byte">
290
- <value name="prospect" label="Prospect" value="0" img=""/>
291
- <value name="customer" label="Client" value="1" img=""/>
292
- </enumeration>
293
- <element name='recipient' label='Recipients'>
294
- <attribute advanced="true" desc="Recipient sex" enum="nms:recipient:gender"
295
- label="Gender" name="gender" sqlname="iGender" type="byte"/>
296
- </element>
297
- </schema>`);
298
- var schema = newSchema(xml);
299
- var enumerations = schema.enumerations;
300
- // no img attribute
301
- expect(enumerations.gender.name).toBe("gender");
302
- expect(enumerations.gender.hasImage).toBe(false);
303
- // at least one img attribute
304
- expect(enumerations.status.name).toBe("status");
305
- expect(enumerations.status.hasImage).toBe(true);
306
- // at least one img attribute
307
- expect(enumerations.status2.name).toBe("status2");
308
- expect(enumerations.status2.hasImage).toBe(false);
309
- expect(schema.root.children["@gender"].enum).toBe("nms:recipient:gender");
310
- })
311
-
312
- it("Should list enumeration values", () => {
313
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
314
- <enumeration name="gender" basetype="byte"/>
315
- <enumeration name="status" basetype="byte">
316
- <value name="prospect" label="Prospect" value="0"/>
317
- <value name="customer" label="Client" value="1"/>
318
- </enumeration>
319
- <element name='recipient' label='Recipients'></element>
320
- </schema>`);
321
- var schema = newSchema(xml);
322
- var enumerations = schema.enumerations;
323
- expect(enumerations.status.values.prospect.label).toBe("Prospect");
324
- expect(enumerations.status.values.customer.label).toBe("Client");
325
- })
326
-
1259
+ describe("Links", () => {
1260
+ it("Should find link node", async () => {
1261
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1262
+ <element name='recipient' label='Recipients'>
1263
+ <element name="country" type="link" target="nms:country"/>
1264
+ </element>
1265
+ </schema>`);
1266
+ var schema = newSchema(xml);
1267
+ var node = await schema.root.findNode("country");
1268
+ expect(node).toMatchObject({ name:"country", type:"link", childrenCount:0, target:"nms:country" });
1269
+ });
327
1270
 
328
- it("Byte enumerations", () => {
329
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
330
- <enumeration basetype="byte" name="instanceType">
331
- <value label="One-off event" name="single" value="0"/>
332
- <value label="Reference recurrence" name="master" value="1"/>
333
- <value label="Instance of a recurrence" name="instance" value="2"/>
334
- <value label="Exception to a recurrence" name="exception" value="3"/>
335
- </enumeration>
336
- <element name='recipient' label='Recipients'></element>
337
- </schema>`);
338
- var schema = newSchema(xml);
339
- var enumerations = schema.enumerations;
340
- expect(enumerations.instanceType.values.single.label).toBe("One-off event");
341
- expect(enumerations.instanceType.values.single.value).toBe(0);
342
- })
1271
+ it("Should fail on invalid link target", async () => {
1272
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1273
+ <element name='recipient' label='Recipients'>
1274
+ <element name="country" type="link" target="country"/>
1275
+ </element>
1276
+ </schema>`);
1277
+ var schema = newSchema(xml);
1278
+ await expect(schema.root.findNode("country/@name")).rejects.toMatchObject({ message: "Cannot find target of link 'country': target is not a valid link target (missing schema id)" });
1279
+ });
343
1280
 
344
- it("Should support default values", () => {
345
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
346
- <enumeration basetype="byte" name="instanceType" default="1">
347
- <value label="One-off event" name="single" value="0"/>
348
- <value label="Reference recurrence" name="master" value="1"/>
349
- <value label="Instance of a recurrence" name="instance" value="2"/>
350
- <value label="Exception to a recurrence" name="exception" value="3"/>
351
- </enumeration>
352
- <element name='recipient' label='Recipients'></element>
353
- </schema>`);
354
- var schema = newSchema(xml);
355
- var enumerations = schema.enumerations;
356
- expect(enumerations.instanceType.default.value).toBe(1);
1281
+ it("Should fail if link target has multiple schemas (like the owner link in nms:operation)", async () => {
1282
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1283
+ <element name='recipient' label='Recipients'>
1284
+ <element name="owner" type="link" target="xtk:opsecurity, xtk:operator"/>
1285
+ </element>
1286
+ </schema>`);
1287
+ var schema = newSchema(xml);
1288
+ await expect(schema.root.findNode("owner/@name")).rejects.toMatchObject({ message: "Cannot find target of link 'xtk:opsecurity, xtk:operator': target has multiple schemas" });
1289
+ });
1290
+
1291
+ it("Should follow link", async () => {
1292
+ // The schema in the ref does not exist
1293
+ const client = await Mock.makeClient();
1294
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1295
+ await client.NLWS.xtkSession.logon();
1296
+
1297
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1298
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1299
+ <SOAP-ENV:Body>
1300
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1301
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1302
+ <schema namespace='nms' name='recipient'>
1303
+ <element name='recipient' label='Recipients'>
1304
+ <element name="country" type="link" target="nms:country"/>
1305
+ </element>
1306
+ </schema>
1307
+ </pdomDoc>
1308
+ </GetEntityIfMoreRecentResponse>
1309
+ </SOAP-ENV:Body>
1310
+ </SOAP-ENV:Envelope>`));
1311
+ const recipient = await client.application.getSchema('nms:recipient');
1312
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1313
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1314
+ <SOAP-ENV:Body>
1315
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1316
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1317
+ <schema namespace='nms' name='country'>
1318
+ <element name='country'>
1319
+ <attribute name="isoA3" label="Country code"/>
1320
+ </element>
1321
+ </schema>
1322
+ </pdomDoc>
1323
+ </GetEntityIfMoreRecentResponse>
1324
+ </SOAP-ENV:Body>
1325
+ </SOAP-ENV:Envelope>`));
1326
+ const isoA3 = await recipient.root.findNode("country/@isoA3");
1327
+ expect(isoA3).toMatchObject({ name:"@isoA3", type:"string", label:"Country code", isAttribute:true, childrenCount:0, target:"" });
1328
+ });
1329
+
1330
+ it("Should follow link pointing to a sub-element", async () => {
1331
+ // The schema in the ref does not exist
1332
+ const client = await Mock.makeClient();
1333
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1334
+ await client.NLWS.xtkSession.logon();
1335
+
1336
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1337
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1338
+ <SOAP-ENV:Body>
1339
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1340
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1341
+ <schema namespace='nms' name='recipient'>
1342
+ <element name='recipient' label='Recipients'>
1343
+ <element name="country" type="link" target="nms:country/test"/>
1344
+ </element>
1345
+ </schema>
1346
+ </pdomDoc>
1347
+ </GetEntityIfMoreRecentResponse>
1348
+ </SOAP-ENV:Body>
1349
+ </SOAP-ENV:Envelope>`));
1350
+ const recipient = await client.application.getSchema('nms:recipient');
1351
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1352
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1353
+ <SOAP-ENV:Body>
1354
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1355
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1356
+ <schema namespace='nms' name='country'>
1357
+ <element name='country'>
1358
+ <attribute name="isoA3" label="Country code"/>
1359
+ <element name="test">
1360
+ <attribute name="isoA3" label="Country code 2"/>
1361
+ </element>
1362
+ </element>
1363
+ </schema>
1364
+ </pdomDoc>
1365
+ </GetEntityIfMoreRecentResponse>
1366
+ </SOAP-ENV:Body>
1367
+ </SOAP-ENV:Envelope>`));
1368
+ const isoA3 = await recipient.root.findNode("country/@isoA3");
1369
+ expect(isoA3).toMatchObject({ name:"@isoA3", type:"string", label:"Country code 2", isAttribute:true, childrenCount:0, target:"" });
1370
+ });
1371
+
1372
+ it("Should find target of non-links", async () => {
1373
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1374
+ <element name='recipient' label='Recipients'>
1375
+ <element name="country"/>
1376
+ </element>
1377
+ </schema>`);
1378
+ var schema = newSchema(xml);
1379
+ var node = await schema.root.findNode("country");
1380
+ node = await node.linkTarget();
1381
+ expect(node).toMatchObject({ name:"recipient" });
1382
+ });
1383
+
1384
+ it("Should support link target schema not found", async () => {
1385
+ // The schema in the ref does not exist
1386
+ const client = await Mock.makeClient();
1387
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1388
+ await client.NLWS.xtkSession.logon();
1389
+
1390
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1391
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1392
+ <SOAP-ENV:Body>
1393
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1394
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1395
+ <schema namespace='nms' name='recipient'>
1396
+ <element name='recipient' label='Recipients'>
1397
+ <element name="country" type="link" target="nms:country"/>
1398
+ </element>
1399
+ </schema>
1400
+ </pdomDoc>
1401
+ </GetEntityIfMoreRecentResponse>
1402
+ </SOAP-ENV:Body>
1403
+ </SOAP-ENV:Envelope>`));
1404
+ const recipient = await client.application.getSchema('nms:recipient');
1405
+ client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
1406
+ const isoA3 = await recipient.root.findNode("country/@isoA3");
1407
+ expect(isoA3).toBeFalsy();
1408
+ });
1409
+
1410
+
1411
+ it("Should support target schema with no root", async () => {
1412
+ // The schema in the ref does not exist
1413
+ const client = await Mock.makeClient();
1414
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1415
+ await client.NLWS.xtkSession.logon();
1416
+
1417
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1418
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1419
+ <SOAP-ENV:Body>
1420
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1421
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1422
+ <schema namespace='nms' name='recipient'>
1423
+ <element name='recipient' label='Recipients'>
1424
+ <element name="country" type="link" target="nms:country/test"/>
1425
+ </element>
1426
+ </schema>
1427
+ </pdomDoc>
1428
+ </GetEntityIfMoreRecentResponse>
1429
+ </SOAP-ENV:Body>
1430
+ </SOAP-ENV:Envelope>`));
1431
+ const recipient = await client.application.getSchema('nms:recipient');
1432
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1433
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1434
+ <SOAP-ENV:Body>
1435
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1436
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1437
+ <schema namespace='nms' name='country'>
1438
+ </schema>
1439
+ </pdomDoc>
1440
+ </GetEntityIfMoreRecentResponse>
1441
+ </SOAP-ENV:Body>
1442
+ </SOAP-ENV:Envelope>`));
1443
+ const isoA3 = await recipient.root.findNode("country/@isoA3");
1444
+ expect(isoA3).toBeFalsy();
1445
+ });
357
1446
  });
358
- })
359
-
360
- describe("Keys", () => {
361
- it("Should have key", () => {
362
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
363
- <element name='recipient' label='Recipients'>
364
- <key name="test">
365
- <keyfield xpath="@email"/>
366
- </key>
367
- <attribute name='email' type='string' length='3'/>
368
- </element>
369
- </schema>`);
370
- var schema = newSchema(xml);
371
- var root = schema.root;
372
- expect(root.keys.test).toBeTruthy();
373
- expect(root.keys.test.fields["email"]).toBeFalsy();
374
- expect(root.keys.test.fields["@email"]).toBeTruthy();
375
- })
376
-
377
- it("Should fail if keyfield does not have xpath", () => {
378
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
379
- <element name='recipient' label='Recipients'>
380
- <key name="test">
381
- <keyfield/>
382
- </key>
383
- <attribute name='email' type='string' length='3'/>
384
- </element>
385
- </schema>`);
386
- expect(() => { newSchema(xml) }).toThrow("keyfield does not have an xpath attribute");
387
- })
388
- });
389
1447
 
390
- describe("Link", () => {
391
- it("Should have a link element", () => {
392
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
393
- <element name='recipient' label='Recipients'>
394
- <element integrity="neutral" label="Info on the email" name="emailInfo"
395
- target="nms:address" type="link" unbound="true">
396
- <join xpath-dst="@address" xpath-src="@email"/>
397
- <join xpath-dst="@dst" xpath-src="@source"/>
398
- </element>
399
- </element>
400
- </schema>`);
401
- var schema = newSchema(xml);
402
- var link = schema.root.children["emailInfo"];
403
- expect(link.target).toBe("nms:address");
404
- expect(link.integrity).toBe("neutral");
405
- expect(link.isUnbound()).toBe(true);
406
- expect(link.joins.length).toBe(2);
407
- expect(link.joins[0].dst).toBe("@address");
408
- expect(link.joins[0].src).toBe("@email");
409
-
410
- xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
411
- <element name='recipient' label='Recipients'>
412
- <element integrity="neutral" label="Info on the email" name="emailInfo"
413
- target="nms:address" type="link">
414
- <join xpath-dst="@address" xpath-src="@email"/>
415
- <join xpath-dst="@dst" xpath-src="@source"/>
416
- </element>
417
- </element>
418
- </schema>`);
419
- schema = newSchema(xml);
420
- link = schema.root.children["emailInfo"];
421
- expect(link.isUnbound()).toBe(false);
422
- })
423
- })
424
-
425
- describe("getnodepath", () => {
426
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
427
- <element name='recipient' label='Recipients'>
428
- <attribute name='email' type='string' length='3'/>
429
- <element name="country">
430
- <attribute name='name'/>
1448
+ describe("Ref nodes", () => {
1449
+ it("Should follow ref elements in same schema (not qualified)", async () => {
1450
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1451
+ <element name='recipient' label='Recipients'>
1452
+ <element name="myAddress" ref="address"/>
1453
+ </element>
1454
+ <element name='address'>
1455
+ <element name="country">
1456
+ <attribute name='name' label="Country Name"/>
1457
+ </element>
1458
+ </element>
1459
+ </schema>`);
1460
+ var schema = newSchema(xml);
1461
+ // Pointing to the node with ref itself => return it
1462
+ var node = await schema.root.findNode("myAddress");
1463
+ expect(node).toMatchObject({ name:"myAddress", ref:"address", childrenCount:0 });
1464
+ // Accessing nodes following the ref
1465
+ node = await schema.root.findNode("myAddress/country");
1466
+ expect(node).toMatchObject({ name:"country", label:"Country", ref:"", childrenCount:1 });
1467
+ node = await schema.root.findNode("myAddress/country/@name");
1468
+ expect(node).toMatchObject({ name:"@name", label:"Country Name", ref:"", childrenCount:0 });
1469
+ });
1470
+ it("Should follow ref elements in same schema (fully qualified)", async () => {
1471
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1472
+ <element name='recipient' label='Recipients'>
1473
+ <element name="myAddress" ref="nms:recipient:address"/>
1474
+ </element>
1475
+ <element name='address'>
1476
+ <element name="country">
1477
+ <attribute name='name' label="Country Name"/>
1478
+ </element>
1479
+ </element>
1480
+ </schema>`);
1481
+ var schema = newSchema(xml);
1482
+ // Pointing to the node with ref itself => return it
1483
+ var node = await schema.root.findNode("myAddress");
1484
+ expect(node).toMatchObject({ name:"myAddress", ref:"nms:recipient:address", childrenCount:0 });
1485
+ // Accessing nodes following the ref
1486
+ node = await schema.root.findNode("myAddress/country");
1487
+ expect(node).toMatchObject({ name:"country", label:"Country", ref:"", childrenCount:1 });
1488
+ node = await schema.root.findNode("myAddress/country/@name");
1489
+ expect(node).toMatchObject({ name:"@name", label:"Country Name", ref:"", childrenCount:0 });
1490
+ });
1491
+
1492
+ it("Should fail on malformed refs", async () => {
1493
+ // Refs should be {schemaId}:{xpath}, meaning at least two ":"
1494
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1495
+ <element name='recipient' label='Recipients'>
1496
+ <element name="myAddress" ref="nms:recipient"/>
1497
+ <attribute name="firstName"/>
1498
+ </element>
1499
+ </schema>`);
1500
+ var schema = newSchema(xml);
1501
+ await expect(schema.root.findNode("myAddress/@firstName")).rejects.toMatchObject({ message: "Cannot find ref target 'nms:recipient' from node '/myAddress' of schema 'nms:recipient': ref value is not correct (expeted <schemaId>:<path>)" });
1502
+ });
1503
+
1504
+ it("Should support inexisting schemas", async () => {
1505
+ // The schema in the ref does not exist
1506
+ const client = await Mock.makeClient();
1507
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1508
+ await client.NLWS.xtkSession.logon();
1509
+
1510
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1511
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1512
+ <SOAP-ENV:Body>
1513
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1514
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1515
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
1516
+ <element name="profile">
1517
+ <element name="address" ref="nms:recipient:address"/>
1518
+ </element>
1519
+ </schema>
1520
+ </pdomDoc>
1521
+ </GetEntityIfMoreRecentResponse>
1522
+ </SOAP-ENV:Body>
1523
+ </SOAP-ENV:Envelope>`));
1524
+ const schema = await client.application.getSchema("nms:profile");
1525
+ const address = await schema.root.findNode("address");
1526
+ expect(address.ref).toBe("nms:recipient:address");
1527
+
1528
+ client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
1529
+ const city = await schema.root.findNode("address/@city");
1530
+ expect(city).toBeFalsy();
1531
+ });
1532
+
1533
+ it("Should follow ref elements in a different scheam", async () => {
1534
+ const client = await Mock.makeClient();
1535
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1536
+ await client.NLWS.xtkSession.logon();
1537
+
1538
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1539
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1540
+ <SOAP-ENV:Body>
1541
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1542
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1543
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
1544
+ <element name="profile">
1545
+ <element name="address" ref="nms:recipient:address"/>
1546
+ </element>
1547
+ </schema>
1548
+ </pdomDoc>
1549
+ </GetEntityIfMoreRecentResponse>
1550
+ </SOAP-ENV:Body>
1551
+ </SOAP-ENV:Envelope>`));
1552
+ const schema = await client.application.getSchema("nms:profile");
1553
+ const address = await schema.root.findNode("address");
1554
+ expect(address.ref).toBe("nms:recipient:address");
1555
+
1556
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1557
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1558
+ <SOAP-ENV:Body>
1559
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1560
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1561
+ <schema name="recipient" namespace="nms" xtkschema="xtk:schema">
1562
+ <element name="recipient">
1563
+ </element>
1564
+ <element name="address" ref="nms:recipient:address">
1565
+ <attribute name="city"/>
1566
+ </element>
1567
+ </schema>
1568
+ </pdomDoc>
1569
+ </GetEntityIfMoreRecentResponse>
1570
+ </SOAP-ENV:Body>
1571
+ </SOAP-ENV:Envelope>`));
1572
+ const city = await schema.root.findNode("address/@city");
1573
+ expect(city).toMatchObject({ name: "@city" });
1574
+ });
1575
+
1576
+ it("Should find path from ref node", async () => {
1577
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1578
+ <element name='recipient' label='Recipients'>
1579
+ <element name="myAddress" ref="address"/>
1580
+ </element>
1581
+ <element name='address'>
1582
+ <element name="country">
1583
+ <attribute name='name' label="Country Name"/>
1584
+ </element>
431
1585
  </element>
432
- </element>
433
- </schema>`);
434
- var schema = newSchema(xml);
435
- var root = schema.root;
436
- var email = root.findNode("@email");
437
- var country = root.findNode("country");
438
- var name = country.findNode("@name");
439
-
440
- it("Should support nodePath property", () => {
441
- expect(schema.nodePath).toBe("/recipient");
442
- expect(root.nodePath).toBe("/");
443
- expect(email.nodePath).toBe("/@email");
444
- expect(country.nodePath).toBe("/country");
445
- expect(name.nodePath).toBe("/country/@name");
1586
+ </schema>`);
1587
+ var schema = newSchema(xml);
1588
+ // Pointing to the node with ref itself => return it
1589
+ var node = await schema.root.findNode("myAddress");
1590
+ expect(node).toMatchObject({ name:"myAddress", ref:"address", childrenCount:0 });
1591
+ // Follow path
1592
+ let target = await node.findNode("country/@name");
1593
+ expect(target).toMatchObject({ name:"@name", ref:"" });
1594
+ });
446
1595
  });
447
1596
 
448
- it("_getNodePath", () => {
449
- // No parameters => absolute
450
- expect(schema._getNodePath()._path).toBe("/recipient");
451
- expect(root._getNodePath()._path).toBe("/");
452
- expect(email._getNodePath()._path).toBe("/@email");
453
- expect(country._getNodePath()._path).toBe("/country");
454
- expect(name._getNodePath()._path).toBe("/country/@name");
455
-
456
- // Absolute
457
- expect(schema._getNodePath(true)._path).toBe("/recipient");
458
- expect(root._getNodePath(true)._path).toBe("/");
459
- expect(email._getNodePath(true)._path).toBe("/@email");
460
- expect(country._getNodePath(true)._path).toBe("/country");
461
- expect(name._getNodePath(true)._path).toBe("/country/@name");
462
-
463
- // Relative
464
- expect(schema._getNodePath(false)._path).toBe("recipient");
465
- expect(root._getNodePath(false)._path).toBe("");
466
- expect(email._getNodePath(false)._path).toBe("@email");
467
- expect(country._getNodePath(false)._path).toBe("country");
468
- expect(name._getNodePath(false)._path).toBe("country/@name");
1597
+ describe("More tests", () => {
1598
+
1599
+ it("Should set label to name with upper case if no label", async () => {
1600
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1601
+ <element name='recipient' label='Recipients'>
1602
+ <attribute name='email' type='string' length='3'/>
1603
+ <element name="country">
1604
+ <attribute name='name'/>
1605
+ </element>
1606
+ </element>
1607
+ </schema>`);
1608
+ var schema = newSchema(xml);
1609
+ var root = schema.root;
1610
+ var node = await root.findNode("@email");
1611
+ expect(node).toMatchObject({ name: "@email", label: "Email", description: "Email", type:"string", nodePath: "/@email" });
1612
+ });
1613
+
1614
+ it("Should have the right children names", async () => {
1615
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
1616
+ <element name='recipient' label='Recipients'>
1617
+ <attribute name='email' type='string' length='3'/>
1618
+ <element name="email"></element>
1619
+ <element name="country">
1620
+ <attribute name='name'/>
1621
+ </element>
1622
+ <attribute name='firstName'/>
1623
+ </element>
1624
+ </schema>`);
1625
+ var schema = newSchema(xml);
1626
+ const names = schema.root.children.map(e => e.name).join(',');
1627
+ expect(names).toBe("@email,email,country,@firstName");
1628
+ });
1629
+
1630
+ it("Should get compute string", async () => {
1631
+ const client = await Mock.makeClient();
1632
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1633
+ await client.NLWS.xtkSession.logon();
1634
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1635
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1636
+ <SOAP-ENV:Body>
1637
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1638
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1639
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
1640
+ <element name="profile">
1641
+ <compute-string expr="@lastName + ' ' + @firstName +' (' + @email + ')'"/>
1642
+ <attribute name="firstName"/>
1643
+ <attribute name="lastName"/>
1644
+ <attribute name="email"/>
1645
+ <attribute name="fullName" expr="@lastName + ' ' + @firstName"/>"
1646
+ </element>
1647
+ </schema>
1648
+ </pdomDoc>
1649
+ </GetEntityIfMoreRecentResponse>
1650
+ </SOAP-ENV:Body>
1651
+ </SOAP-ENV:Envelope>`));
1652
+ const schema = await client.application.getSchema("nms:profile");
1653
+
1654
+ let node = schema;
1655
+ let cs = await node.computeString();
1656
+ expect(cs).toBe("");
1657
+ expect(node.isCalculated).toBe(false);
1658
+
1659
+ node = schema.root;
1660
+ cs = await node.computeString();
1661
+ expect(cs).toBe("@lastName + ' ' + @firstName +' (' + @email + ')'");
1662
+ expect(node.isCalculated).toBe(false);
1663
+
1664
+ node = schema.root.children.get("@fullName");
1665
+ cs = await node.computeString();
1666
+ expect(cs).toBe("@lastName + ' ' + @firstName");
1667
+ expect(node.isCalculated).toBe(true);
1668
+ });
1669
+
1670
+ it("Should get compute string for ref nodes", async () => {
1671
+ const client = await Mock.makeClient();
1672
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1673
+ await client.NLWS.xtkSession.logon();
1674
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1675
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1676
+ <SOAP-ENV:Body>
1677
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1678
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1679
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
1680
+ <element name="profile" ref="alternate">
1681
+ </element>
1682
+ <element name="alternate" expr="@lastName + ' ' + @firstName +' (' + @email + ')'">
1683
+ <attribute name="firstName"/>
1684
+ <attribute name="lastName"/>
1685
+ <attribute name="email"/>
1686
+ </element>
1687
+ </schema>
1688
+ </pdomDoc>
1689
+ </GetEntityIfMoreRecentResponse>
1690
+ </SOAP-ENV:Body>
1691
+ </SOAP-ENV:Envelope>`));
1692
+ const schema = await client.application.getSchema("nms:profile");
1693
+ const node = schema.root;
1694
+ const cs = await node.computeString();
1695
+ expect(cs).toBe("@lastName + ' ' + @firstName +' (' + @email + ')'");
1696
+ expect(node.isCalculated).toBe(false);
1697
+ });
1698
+
1699
+ it("Should get compute string for ref nodes (missing target)", async () => {
1700
+ const client = await Mock.makeClient();
1701
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1702
+ await client.NLWS.xtkSession.logon();
1703
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1704
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1705
+ <SOAP-ENV:Body>
1706
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1707
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1708
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
1709
+ <element name="profile" ref="missing">
1710
+ </element>
1711
+ </schema>
1712
+ </pdomDoc>
1713
+ </GetEntityIfMoreRecentResponse>
1714
+ </SOAP-ENV:Body>
1715
+ </SOAP-ENV:Envelope>`));
1716
+ const schema = await client.application.getSchema("nms:profile");
1717
+ const node = schema.root;
1718
+ const cs = await node.computeString();
1719
+ expect(cs).toBe("");
1720
+ expect(node.isCalculated).toBe(false);
1721
+ });
1722
+
1723
+ it("Should get compute string (automatically computed))", async () => {
1724
+ const client = await Mock.makeClient();
1725
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1726
+ await client.NLWS.xtkSession.logon();
1727
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1728
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1729
+ <SOAP-ENV:Body>
1730
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1731
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1732
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
1733
+ <element name="profile">
1734
+ <key>
1735
+ <keyfield xpath="@email"/>
1736
+ <keyfield xpath="@lastName"/>
1737
+ </key>
1738
+ <attribute name="firstName"/>
1739
+ <attribute name="lastName"/>
1740
+ <attribute name="email"/>
1741
+ </element>
1742
+ </schema>
1743
+ </pdomDoc>
1744
+ </GetEntityIfMoreRecentResponse>
1745
+ </SOAP-ENV:Body>
1746
+ </SOAP-ENV:Envelope>`));
1747
+ const schema = await client.application.getSchema("nms:profile");
1748
+ const node = schema.root;
1749
+ const cs = await node.computeString();
1750
+ expect(cs).toBe("[/@email]");
1751
+ expect(node.isCalculated).toBe(false);
1752
+ });
1753
+
1754
+ it("Should get compute string (empty)", async () => {
1755
+ const client = await Mock.makeClient();
1756
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1757
+ await client.NLWS.xtkSession.logon();
1758
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1759
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1760
+ <SOAP-ENV:Body>
1761
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1762
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1763
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
1764
+ <element name="profile">
1765
+ <attribute name="firstName"/>
1766
+ <attribute name="lastName"/>
1767
+ <attribute name="email"/>
1768
+ </element>
1769
+ </schema>
1770
+ </pdomDoc>
1771
+ </GetEntityIfMoreRecentResponse>
1772
+ </SOAP-ENV:Body>
1773
+ </SOAP-ENV:Envelope>`));
1774
+ const schema = await client.application.getSchema("nms:profile");
1775
+ const node = schema.root;
1776
+ const cs = await node.computeString();
1777
+ expect(cs).toBe("");
1778
+ expect(node.isCalculated).toBe(false);
1779
+ });
1780
+
1781
+ it("Should get compute string (empty key)", async () => {
1782
+ const client = await Mock.makeClient();
1783
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1784
+ await client.NLWS.xtkSession.logon();
1785
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1786
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1787
+ <SOAP-ENV:Body>
1788
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1789
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1790
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
1791
+ <element name="profile">
1792
+ <key></key>
1793
+ <attribute name="firstName"/>
1794
+ <attribute name="lastName"/>
1795
+ <attribute name="email"/>
1796
+ </element>
1797
+ </schema>
1798
+ </pdomDoc>
1799
+ </GetEntityIfMoreRecentResponse>
1800
+ </SOAP-ENV:Body>
1801
+ </SOAP-ENV:Envelope>`));
1802
+ const schema = await client.application.getSchema("nms:profile");
1803
+ const node = schema.root;
1804
+ const cs = await node.computeString();
1805
+ expect(cs).toBe("");
1806
+ expect(node.isCalculated).toBe(false);
1807
+ });
1808
+
1809
+ it("Should get compute string (invalid key)", async () => {
1810
+ const client = await Mock.makeClient();
1811
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1812
+ await client.NLWS.xtkSession.logon();
1813
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1814
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1815
+ <SOAP-ENV:Body>
1816
+ <GetEntityIfMoreRecentResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1817
+ <pdomDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1818
+ <schema name="profile" namespace="nms" xtkschema="xtk:schema">
1819
+ <element name="profile">
1820
+ <key>
1821
+ <keyfield xpath="@notFound"/>
1822
+ </key>
1823
+ <attribute name="firstName"/>
1824
+ <attribute name="lastName"/>
1825
+ <attribute name="email"/>
1826
+ </element>
1827
+ </schema>
1828
+ </pdomDoc>
1829
+ </GetEntityIfMoreRecentResponse>
1830
+ </SOAP-ENV:Body>
1831
+ </SOAP-ENV:Envelope>`));
1832
+ const schema = await client.application.getSchema("nms:profile");
1833
+ const node = schema.root;
1834
+ const cs = await node.computeString();
1835
+ expect(cs).toBe("");
1836
+ expect(node.isCalculated).toBe(false);
1837
+ });
469
1838
  });
470
- });
471
1839
 
1840
+ describe("Type ANY", () => {
1841
+ it("Should find ANY node", async () => {
1842
+ var xml = DomUtil.parse(`<schema namespace='nms' name='group'>
1843
+ <element name='group'>
1844
+ <element name="extension" type="ANY" label="Extension data" xml="true" doesNotSupportDiff="true"/>
1845
+ </element>
1846
+ </schema>`);
1847
+ var schema = newSchema(xml);
1848
+ var root = schema.root;
1849
+ var node = await root.findNode("extension");
1850
+ expect(node).toMatchObject({ name: "extension", label: "Extension data", nodePath: "/extension", type: "ANY" });
1851
+
1852
+ // xpath inside ANY node are not supported
1853
+ node = await root.findNode("extension/group");
1854
+ expect(node).toBeFalsy();
1855
+ });
1856
+ });
472
1857
 
473
- describe("toString", () => {
474
- var xml = DomUtil.parse(`<schema namespace='nms' name='recipient'>
475
- <element name='recipient' label='Recipients'>
476
- <attribute name='email' type='string' length='3'/>
477
- <element name="country">
478
- <attribute name='name'/>
1858
+ describe("toString", () => {
1859
+ var xml = DomUtil.parse(`<schema namespace='nms' name='recipient' label="Recipients" labelSingular="Recipient">
1860
+ <element name='recipient'>
1861
+ <attribute name='email' type='string' length='3'/>
1862
+ <element name="country">
1863
+ <attribute name='name'/>
1864
+ </element>
479
1865
  </element>
480
- </element>
481
- </schema>`);
482
- var schema = newSchema(xml);
483
- var root = schema.root;
484
- var email = root.findNode("@email");
485
- var country = root.findNode("country");
486
- var name = country.findNode("@name");
487
-
488
- it("Should stringify schema or schema node", () => {
489
- expect(schema.toString()).toBe(`recipient
490
- - Recipients (recipient)
491
- - @email
492
- - country
493
- - @name
1866
+ </schema>`);
1867
+
1868
+ it("Should stringify schema or schema node", async () => {
1869
+ var schema = newSchema(xml);
1870
+ var root = schema.root;
1871
+ var email = await root.findNode("@email");
1872
+ var country = await root.findNode("country");
1873
+ var name = await country.findNode("@name");
1874
+
1875
+ expect(schema.toString()).toBe(`Recipients (recipient)
1876
+ - Recipient (recipient)
1877
+ - Email (@email)
1878
+ - Country (country)
1879
+ - Name (@name)
494
1880
  `);
495
- expect(root.toString()).toBe(`Recipients (recipient)
496
- @email
497
- country
498
- @name
1881
+ expect(root.toString()).toBe(`Recipient (recipient)
1882
+ Email (@email)
1883
+ Country (country)
1884
+ Name (@name)
499
1885
  `);
500
- expect(email.toString()).toBe("@email\n");
501
- expect(country.toString()).toBe("country\n @name\n");
502
- expect(name.toString()).toBe("@name\n");
503
- });
504
- })
505
-
506
- });
507
-
508
-
509
- describe("CurrentLogin", () => {
510
-
511
- it("Should create with SimpleJson", () => {
512
- var op = newCurrentLogin({
513
- login: "alex",
514
- loginId: "12",
515
- loginCS: "Alex",
516
- timezone: "Europe/Paris",
517
- "login-right": [
518
- ]
1886
+ expect(email.toString()).toBe("Email (@email)\n");
1887
+ expect(country.toString()).toBe("Country (country)\n Name (@name)\n");
1888
+ expect(name.toString()).toBe("Name (@name)\n");
1889
+ });
519
1890
  })
520
- expect(op.login).toBe("alex");
521
- expect(op.id).toBe(12);
522
- expect(op.computeString).toBe("Alex");
523
- expect(op.timezone).toBe("Europe/Paris");
524
- expect(op.rights).toEqual([]);
525
- })
526
-
527
- it("Should support missing 'login-right' node", () => {
528
- var op = newCurrentLogin({ login: "alex", loginId: "12", loginCS: "Alex" })
529
- expect(op.rights).toEqual([]);
530
- expect(op.hasRight("admin")).toBe(false);
531
- })
532
-
533
- it("Should support 'login-right' as an object", () => {
534
- var op = newCurrentLogin({ login: "alex", loginId: "12", loginCS: "Alex", "login-right": { "right": "admin" } });
535
- expect(op.rights).toEqual([ "admin" ]);
536
- expect(op.hasRight("admin")).toBe(true);
537
- })
538
-
539
- it("Should support 'login-right' as an object", () => {
540
- var op = newCurrentLogin({ login: "alex", loginId: "12", loginCS: "Alex", "login-right": [ { "right": "admin" }, { "right": "delivery" } ] });
541
- expect(op.rights).toEqual([ "admin", "delivery" ]);
542
- expect(op.hasRight("admin")).toBe(true);
543
- expect(op.hasRight("delivery")).toBe(true);
544
- })
545
-
546
-
547
- describe("application.getSchema", () => {
548
- it("Should return a XtkSchema object", async () => {
549
- const client = await Mock.makeClient();
550
- client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
551
- await client.NLWS.xtkSession.logon();
552
1891
 
553
- client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
554
- const schema = await client.application.getSchema("xtk:session");
555
- expect(schema.namespace).toBe("xtk");
556
- expect(schema.name).toBe("session");
557
- });
558
-
559
- it("Should handle non-existing schemas", async () => {
560
- const client = await Mock.makeClient();
561
- client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
562
- await client.NLWS.xtkSession.logon();
1892
+ describe("Node properties", () => {
1893
+ it("Should have isSQL" , async () => {
1894
+ const xml = DomUtil.parse(`<schema namespace='nms' name='recipient' label="Recipients" labelSingular="Recipient">
1895
+ <element name='recipient' sqltable="NmsRecipient">
1896
+ <attribute name='email' type='string' sqlname="semail"/>
1897
+ <attribute name='test' type='string' xml="true"/>
1898
+ </element>
1899
+ </schema>`);
1900
+ const schema = newSchema(xml);
1901
+ expect(schema.root.isSQL).toBe(true);
1902
+ let node = await schema.root.findNode("@email");
1903
+ expect(node.isSQL).toBe(true);
1904
+ node = await schema.root.findNode("@test");
1905
+ expect(node.isSQL).toBe(false);
1906
+ });
1907
+
1908
+ it("Should have isSQL for link" , async () => {
1909
+ let xml = DomUtil.parse(`<schema namespace='nms' name='recipient' mappingType="sql">
1910
+ <element name='recipient' sqltable="NmsRecipient">
1911
+ <element name='country' type='link'/>
1912
+ </element>
1913
+ </schema>`);
1914
+ let schema = newSchema(xml);
1915
+ let node = await schema.root.findNode("country");
1916
+ expect(node.isSQL).toBe(true);
1917
+
1918
+ // not a sql mapping type
1919
+ xml = DomUtil.parse(`<schema namespace='nms' name='recipient' mappingType="file">
1920
+ <element name='recipient' sqltable="NmsRecipient">
1921
+ <element name='country' type='link'/>
1922
+ </element>
1923
+ </schema>`);
1924
+ schema = newSchema(xml);
1925
+ node = await schema.root.findNode("country");
1926
+ expect(node.isSQL).toBe(false);
1927
+
1928
+ // xml link
1929
+ xml = DomUtil.parse(`<schema namespace='nms' name='recipient' mappingType="sql">
1930
+ <element name='recipient' sqltable="NmsRecipient">
1931
+ <element name='country' type='link' xml="true"/>
1932
+ </element>
1933
+ </schema>`);
1934
+ schema = newSchema(xml);
1935
+ node = await schema.root.findNode("country");
1936
+ expect(node.isSQL).toBe(false);
1937
+ });
1938
+
1939
+ it("Should be memo and memo data" , async () => {
1940
+ const xml = DomUtil.parse(`<schema namespace='nms' name='recipient' label="Recipients" labelSingular="Recipient">
1941
+ <element name='recipient' sqltable="NmsRecipient">
1942
+ <attribute name='email' type='string' sqlname="semail"/>
1943
+ <attribute name='test' type='string' xml="true"/>
1944
+ <attribute name='memo' type='memo'/>
1945
+ <element name='data' type='memo' xml="true"/>
1946
+ </element>
1947
+ </schema>`);
1948
+ const schema = newSchema(xml);
1949
+ let node = await schema.root.findNode("@email");
1950
+ expect(node.isMemo).toBe(false);
1951
+ expect(node.isMemoData).toBe(false);
1952
+ node = await schema.root.findNode("@test");
1953
+ expect(node.isMemo).toBe(false);
1954
+ expect(node.isMemoData).toBe(false);
1955
+ node = await schema.root.findNode("@memo");
1956
+ expect(node.isMemo).toBe(true);
1957
+ expect(node.isMemoData).toBe(false);
1958
+ node = await schema.root.findNode("data");
1959
+ expect(node.isMemo).toBe(true);
1960
+ expect(node.isMemoData).toBe(true);
1961
+ });
1962
+
1963
+ it("Should be test isNotNull" , async () => {
1964
+ const xml = DomUtil.parse(`<schema namespace='nms' name='recipient' label="Recipients" labelSingular="Recipient">
1965
+ <element name='recipient'>
1966
+ <attribute name='id' type='long'/>
1967
+ <attribute name='b' type='byte'/>
1968
+ <attribute name='s' type='short'/>
1969
+ <attribute name='f' type='float'/>
1970
+ <attribute name='d' type='double'/>
1971
+ <attribute name='i' type='int64'/>
1972
+ <attribute name='m' type='money'/>
1973
+ <attribute name='p' type='percent'/>
1974
+ <attribute name='t' type='time'/>
1975
+ <attribute name='b0' type='boolean'/>
1976
+ <attribute name='email' type='string'/>
1977
+
1978
+ <attribute name='snn' type='string'/>
1979
+ <attribute name='snnt' type='string' notNull='true'/>
1980
+ <attribute name='snnf' type='string' notNull='false'/>
1981
+
1982
+ <attribute name='lnn' type='long'/>
1983
+ <attribute name='lnnt' type='long' notNull='true'/>
1984
+ <attribute name='lnnf' type='long' notNull='false'/>
1985
+ </element>
1986
+ </schema>`);
1987
+ const schema = newSchema(xml);
1988
+ let node = await schema.root.findNode("@email"); expect(node.isNotNull).toBe(false);
1989
+ node = await schema.root.findNode("@id"); expect(node.isNotNull).toBe(true);
1990
+ node = await schema.root.findNode("@b"); expect(node.isNotNull).toBe(true);
1991
+ node = await schema.root.findNode("@s"); expect(node.isNotNull).toBe(true);
1992
+ node = await schema.root.findNode("@f"); expect(node.isNotNull).toBe(true);
1993
+ node = await schema.root.findNode("@d"); expect(node.isNotNull).toBe(true);
1994
+ node = await schema.root.findNode("@i"); expect(node.isNotNull).toBe(true);
1995
+ node = await schema.root.findNode("@m"); expect(node.isNotNull).toBe(true);
1996
+ node = await schema.root.findNode("@p"); expect(node.isNotNull).toBe(true);
1997
+ node = await schema.root.findNode("@t"); expect(node.isNotNull).toBe(true);
1998
+ node = await schema.root.findNode("@b0"); expect(node.isNotNull).toBe(true);
1999
+
2000
+ node = await schema.root.findNode("@snn"); expect(node.isNotNull).toBe(false);
2001
+ node = await schema.root.findNode("@snnt"); expect(node.isNotNull).toBe(true);
2002
+ node = await schema.root.findNode("@snnf"); expect(node.isNotNull).toBe(false);
2003
+
2004
+ node = await schema.root.findNode("@lnn"); expect(node.isNotNull).toBe(true);
2005
+ node = await schema.root.findNode("@lnnt"); expect(node.isNotNull).toBe(true);
2006
+ node = await schema.root.findNode("@lnnf"); expect(node.isNotNull).toBe(false);
2007
+ });
2008
+
2009
+ it("Should test user description" , async () => {
2010
+ let xml = DomUtil.parse(`<schema namespace='nms' name='recipient' label="Recipients" labelSingular="Recipient">
2011
+ <element name='recipient'>
2012
+ </element>
2013
+ </schema>`);
2014
+ let schema = newSchema(xml);
2015
+ expect(schema.userDescription).toBe("Recipients (recipient)");
563
2016
 
564
- client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
565
- const schema = await client.application.getSchema("xtk:dummy")
566
- expect(schema).toBeNull();
567
- })
2017
+ xml = DomUtil.parse(`<schema namespace='nms' name='recipient' label="recipient">
2018
+ <element name='recipient'>
2019
+ </element>
2020
+ </schema>`);
2021
+ schema = newSchema(xml);
2022
+ expect(schema.userDescription).toBe("recipient");
2023
+ });
2024
+ });
568
2025
  });
569
2026
 
570
- describe("application.hasPackage", () => {
571
- it("Should verify if a package is installed", async () => {
572
- const client = await Mock.makeClient();
573
- client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
574
- await client.NLWS.xtkSession.logon();
575
- expect(client.application.hasPackage("nms:core")).toBe(true);
576
- expect(client.application.hasPackage("nms:campaign")).toBe(true);
577
- expect(client.application.hasPackage("nms:dummy")).toBe(false);
578
- expect(client.application.hasPackage("")).toBe(false);
579
- expect(client.application.hasPackage(null)).toBe(false);
580
- expect(client.application.hasPackage(undefined)).toBe(false);
2027
+ describe("CurrentLogin", () => {
2028
+
2029
+ it("Should create with SimpleJson", () => {
2030
+ var op = newCurrentLogin({
2031
+ login: "alex",
2032
+ loginId: "12",
2033
+ loginCS: "Alex",
2034
+ timezone: "Europe/Paris",
2035
+ "login-right": [
2036
+ ]
2037
+ })
2038
+ expect(op.login).toBe("alex");
2039
+ expect(op.id).toBe(12);
2040
+ expect(op.computeString).toBe("Alex");
2041
+ expect(op.timezone).toBe("Europe/Paris");
2042
+ expect(op.rights).toEqual([]);
581
2043
  })
582
- })
583
-
584
2044
 
585
- describe("XPath", () => {
586
-
587
- it("Should create XPath", () => {
588
- expect(new XPath("").asString()).toBe("");
589
- expect(new XPath(" ").asString()).toBe("");
590
- expect(new XPath(null).asString()).toBe("");
591
- expect(new XPath(undefined).asString()).toBe("");
592
- expect(new XPath("@name").asString()).toBe("@name");
593
- expect(new XPath("country/@name").asString()).toBe("country/@name");
594
- expect(new XPath("..").asString()).toBe("..");
595
- expect(new XPath(".").asString()).toBe(".");
2045
+ it("Should support missing 'login-right' node", () => {
2046
+ var op = newCurrentLogin({ login: "alex", loginId: "12", loginCS: "Alex" })
2047
+ expect(op.rights).toEqual([]);
2048
+ expect(op.hasRight("admin")).toBe(false);
596
2049
  })
597
2050
 
598
- it("toString", () => {
599
- expect(new XPath("").toString()).toBe("");
600
- expect(new XPath(" ").toString()).toBe("");
601
- expect(new XPath(null).toString()).toBe("");
602
- expect(new XPath(undefined).toString()).toBe("");
603
- expect(new XPath("@name").toString()).toBe("@name");
604
- expect(new XPath("country/@name").toString()).toBe("country/@name");
605
- expect(new XPath("..").toString()).toBe("..");
606
- expect(new XPath(".").toString()).toBe(".");
2051
+ it("Should support 'login-right' as an object", () => {
2052
+ var op = newCurrentLogin({ login: "alex", loginId: "12", loginCS: "Alex", "login-right": { "right": "admin" } });
2053
+ expect(op.rights).toEqual([ "admin" ]);
2054
+ expect(op.hasRight("admin")).toBe(true);
607
2055
  })
608
2056
 
609
- it("Should test empty XPath", () => {
610
- expect(new XPath("").isEmpty()).toBe(true);
611
- expect(new XPath(" ").isEmpty()).toBe(true);
612
- expect(new XPath(null).isEmpty()).toBe(true);
613
- expect(new XPath(undefined).isEmpty()).toBe(true);
614
- expect(new XPath("@name").isEmpty()).toBe(false);
615
- expect(new XPath("country/@name").isEmpty()).toBe(false);
616
- expect(new XPath("..").isEmpty()).toBe(false);
617
- expect(new XPath(".").isEmpty()).toBe(false);
2057
+ it("Should support 'login-right' as an object", () => {
2058
+ var op = newCurrentLogin({ login: "alex", loginId: "12", loginCS: "Alex", "login-right": [ { "right": "admin" }, { "right": "delivery" } ] });
2059
+ expect(op.rights).toEqual([ "admin", "delivery" ]);
2060
+ expect(op.hasRight("admin")).toBe(true);
2061
+ expect(op.hasRight("delivery")).toBe(true);
618
2062
  })
619
2063
 
620
- it("Should test absolute XPath", () => {
621
- expect(new XPath("").isAbsolute()).toBe(false);
622
- expect(new XPath(" ").isAbsolute()).toBe(false);
623
- expect(new XPath(null).isAbsolute()).toBe(false);
624
- expect(new XPath(undefined).isAbsolute()).toBe(false);
625
- expect(new XPath("@name").isAbsolute()).toBe(false);
626
- expect(new XPath("country/@name").isAbsolute()).toBe(false);
627
- expect(new XPath("..").isAbsolute()).toBe(false);
628
- expect(new XPath(".").isAbsolute()).toBe(false);
629
- expect(new XPath("/").isAbsolute()).toBe(true);
630
- expect(new XPath("/country/@name").isAbsolute()).toBe(true);
631
- })
632
2064
 
633
- it("Should test self XPath", () => {
634
- expect(new XPath("").isSelf()).toBe(false);
635
- expect(new XPath(" ").isSelf()).toBe(false);
636
- expect(new XPath(null).isSelf()).toBe(false);
637
- expect(new XPath(undefined).isSelf()).toBe(false);
638
- expect(new XPath("@name").isSelf()).toBe(false);
639
- expect(new XPath("country/@name").isSelf()).toBe(false);
640
- expect(new XPath("..").isSelf()).toBe(false);
641
- expect(new XPath(".").isSelf()).toBe(true);
642
- expect(new XPath("/").isSelf()).toBe(false);
643
- expect(new XPath("/country/@name").isSelf()).toBe(false);
644
- })
2065
+ describe("application.getSchema", () => {
2066
+ it("Should return a XtkSchema object", async () => {
2067
+ const client = await Mock.makeClient();
2068
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2069
+ await client.NLWS.xtkSession.logon();
645
2070
 
646
- it("Should test root XPath", () => {
647
- expect(new XPath("").isRootPath()).toBe(false);
648
- expect(new XPath(" ").isRootPath()).toBe(false);
649
- expect(new XPath(null).isRootPath()).toBe(false);
650
- expect(new XPath(undefined).isRootPath()).toBe(false);
651
- expect(new XPath("@name").isRootPath()).toBe(false);
652
- expect(new XPath("country/@name").isRootPath()).toBe(false);
653
- expect(new XPath("..").isRootPath()).toBe(false);
654
- expect(new XPath(".").isRootPath()).toBe(false);
655
- expect(new XPath("/").isRootPath()).toBe(true);
656
- expect(new XPath("/country/@name").isRootPath()).toBe(false);
657
- })
2071
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
2072
+ const schema = await client.application.getSchema("xtk:session");
2073
+ expect(schema.namespace).toBe("xtk");
2074
+ expect(schema.name).toBe("session");
2075
+ });
658
2076
 
659
- it("Should return XPath elements", () => {
660
-
661
- function elements(xpath) {
662
- const result = [];
663
- const list = xpath.getElements();
664
- for (const e of list) {
665
- result.push(e._pathElement);
666
- }
667
- return result;
668
- }
669
-
670
- expect(elements(new XPath(""))).toEqual([ ]);
671
- expect(elements(new XPath(" "))).toEqual([ ]);
672
- expect(elements(new XPath(null))).toEqual([ ]);
673
- expect(elements(new XPath(undefined))).toEqual([ ]);
674
- expect(elements(new XPath("@name"))).toEqual([ "@name" ]);
675
- expect(elements(new XPath("country/@name"))).toEqual([ "country", "@name" ]);
676
- expect(elements(new XPath(".."))).toEqual([ ".." ]);
677
- expect(elements(new XPath("."))).toEqual([ "." ]);
678
- expect(elements(new XPath("/"))).toEqual([ ]);
679
- expect(elements(new XPath("/country/@name"))).toEqual([ "country", "@name" ]);
680
- })
2077
+ it("Should handle non-existing schemas", async () => {
2078
+ const client = await Mock.makeClient();
2079
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2080
+ await client.NLWS.xtkSession.logon();
2081
+
2082
+ client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
2083
+ const schema = await client.application.getSchema("xtk:dummy")
2084
+ expect(schema).toBeNull();
2085
+ })
2086
+ });
681
2087
 
682
- it("Should get relative path", () => {
683
- expect(new XPath("").getRelativePath().asString()).toBe("");
684
- expect(new XPath(" ").getRelativePath().asString()).toBe("");
685
- expect(new XPath(null).getRelativePath().asString()).toBe("");
686
- expect(new XPath(undefined).getRelativePath().asString()).toBe("");
687
- expect(new XPath("@name").getRelativePath().asString()).toBe("@name");
688
- expect(new XPath("country/@name").getRelativePath().asString()).toBe("country/@name");
689
- expect(new XPath("..").getRelativePath().asString()).toBe("..");
690
- expect(new XPath(".").getRelativePath().asString()).toBe(".");
691
- expect(new XPath("/").getRelativePath().asString()).toBe("");
692
- expect(new XPath("/country/@name").getRelativePath().asString()).toBe("country/@name");
2088
+ describe("application.hasPackage", () => {
2089
+ it("Should verify if a package is installed", async () => {
2090
+ const client = await Mock.makeClient();
2091
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2092
+ await client.NLWS.xtkSession.logon();
2093
+ expect(client.application.hasPackage("nms:core")).toBe(true);
2094
+ expect(client.application.hasPackage("nms:campaign")).toBe(true);
2095
+ expect(client.application.hasPackage("nms:dummy")).toBe(false);
2096
+ expect(client.application.hasPackage("")).toBe(false);
2097
+ expect(client.application.hasPackage(null)).toBe(false);
2098
+ expect(client.application.hasPackage(undefined)).toBe(false);
2099
+ })
693
2100
  })
694
2101
  });
695
2102
 
696
- describe("XPathElement", () => {
697
- it("Should create XPathElement", () => {
698
- expect(() => { new XPathElement(""); }).toThrow("Invalid empty xpath element");
699
- expect(() => { new XPathElement(" "); }).toThrow("Invalid empty xpath element");
700
- expect(() => { new XPathElement(null); }).toThrow("Invalid empty xpath element");
701
- expect(() => { new XPathElement(undefined); }).toThrow("Invalid empty xpath element");
702
- expect(new XPathElement("@name").asString()).toBe("@name");
703
- expect(new XPathElement("country").asString()).toBe("country");
704
- expect(new XPathElement("..").asString()).toBe("..");
705
- expect(new XPathElement(".").asString()).toBe(".");
2103
+ describe("Application for anonymous users", () => {
2104
+ it("Application objet should exist but will not have user/session info", async () => {
2105
+ const client = await Mock.makeAnonymousClient();
2106
+ expect(client.application).toBeNull();
2107
+ await client.logon();
2108
+ const application = client.application;
2109
+ expect(application).not.toBeNull();
2110
+ expect(application.buildNumber).toBeUndefined();
2111
+ expect(application.instanceName).toBeUndefined();
2112
+ expect(application.operator).toBeUndefined();
2113
+ expect(application.package).toBeUndefined();
706
2114
  })
2115
+ });
707
2116
 
708
- it("toString", () => {
709
- expect(new XPathElement("@name").toString()).toBe("@name");
710
- expect(new XPathElement("country").toString()).toBe("country");
711
- expect(new XPathElement("..").toString()).toBe("..");
712
- expect(new XPathElement(".").toString()).toBe(".");
713
- })
2117
+ describe("Schema Cache", () => {
2118
+ it("Should search in empty cache", async () => {
2119
+ const client = await Mock.makeClient();
2120
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2121
+ await client.NLWS.xtkSession.logon();
2122
+ const cache = new SchemaCache(client);
714
2123
 
715
- it("Should test if path element is self", () => {
716
- expect(new XPathElement("@name").isSelf()).toBe(false);
717
- expect(new XPathElement("country").isSelf()).toBe(false);
718
- expect(new XPathElement("..").isSelf()).toBe(false);
719
- expect(new XPathElement(".").isSelf()).toBe(true);
720
- })
2124
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
2125
+ const schema = await cache.getSchema("xtk:queryDef");
2126
+ expect(schema.id).toBe("xtk:queryDef");
721
2127
 
722
- it("Should test if path element is the parent path (..)", () => {
723
- expect(new XPathElement("@name").isParent()).toBe(false);
724
- expect(new XPathElement("country").isParent()).toBe(false);
725
- expect(new XPathElement("..").isParent()).toBe(true);
726
- expect(new XPathElement(".").isParent()).toBe(false);
727
- })
728
- })
729
- });
730
-
731
-
732
- describe("Application for anonymous users", () => {
733
- it("Application objet should exist but will not have user/session info", async () => {
734
- const client = await Mock.makeAnonymousClient();
735
- expect(client.application).toBeNull();
736
- await client.logon();
737
- const application = client.application;
738
- expect(application).not.toBeNull();
739
- expect(application.buildNumber).toBeUndefined();
740
- expect(application.instanceName).toBeUndefined();
741
- expect(application.operator).toBeUndefined();
742
- expect(application.package).toBeUndefined();
743
- })
2128
+ // Second call should not perform any API call
2129
+ const schema2 = await cache.getSchema("xtk:queryDef");
2130
+ expect(schema2.id).toBe("xtk:queryDef");
2131
+ });
2132
+
2133
+ it("Should support not found schemas", async () => {
2134
+ const client = await Mock.makeClient();
2135
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2136
+ await client.NLWS.xtkSession.logon();
2137
+ const cache = new SchemaCache(client);
2138
+
2139
+ client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
2140
+ const schema = await cache.getSchema("xtk:queryDef");
2141
+ expect(schema).toBeFalsy();
2142
+
2143
+ // Second call should not perform any API call
2144
+ const schema2 = await cache.getSchema("xtk:queryDef");
2145
+ expect(schema2).toBeNull();
2146
+ });
2147
+ });
744
2148
  });