@adobe/acc-js-sdk 1.0.5 → 1.0.8
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.
- package/.github/workflows/codeql-analysis.yml +70 -0
- package/.vscode/launch.json +0 -1
- package/CHANGELOG.md +40 -0
- package/README.md +199 -63
- package/compile.js +3 -0
- package/package-lock.json +2175 -3383
- package/package.json +6 -7
- package/samples/002 - basics - schemas.js +3 -3
- package/samples/020 - encryption.js +5 -5
- package/src/application.js +427 -77
- package/src/cache.js +275 -0
- package/src/campaign.js +4 -0
- package/src/client.js +108 -30
- package/src/domUtil.js +6 -3
- package/src/entityAccessor.js +5 -5
- package/src/index.js +58 -2
- package/src/methodCache.js +21 -2
- package/src/optionCache.js +5 -1
- package/src/soap.js +46 -19
- package/src/testUtil.js +47 -0
- package/src/util.js +0 -229
- package/src/xtkCaster.js +80 -6
- package/src/xtkEntityCache.js +19 -3
- package/test/application.test.js +684 -616
- package/test/caches.test.js +148 -2
- package/test/client.test.js +341 -14
- package/test/crypto.test.js +16 -12
- package/test/domUtil.test.js +150 -2
- package/test/escape.test.js +79 -47
- package/test/index.test.js +69 -1
- package/test/mock.js +59 -9
- package/test/soap.test.js +0 -6
- package/test/testUtil.test.js +64 -0
- package/test/util.test.js +2 -1
- package/test/xtkCaster.test.js +219 -1
package/test/caches.test.js
CHANGED
|
@@ -18,7 +18,7 @@ governing permissions and limitations under the License.
|
|
|
18
18
|
*********************************************************************************/
|
|
19
19
|
|
|
20
20
|
const assert = require('assert');
|
|
21
|
-
const { Cache } = require('../src/
|
|
21
|
+
const { Cache, SafeStorage } = require('../src/cache.js');
|
|
22
22
|
const OptionCache = require('../src/optionCache.js').OptionCache;
|
|
23
23
|
const MethodCache = require('../src/methodCache.js').MethodCache;
|
|
24
24
|
const XtkEntityCache = require('../src/xtkEntityCache.js').XtkEntityCache;
|
|
@@ -205,7 +205,17 @@ describe('Caches', function() {
|
|
|
205
205
|
assert.equal(found.nodeName, "method");
|
|
206
206
|
assert.equal(found.getAttribute("name"), "Create");
|
|
207
207
|
})
|
|
208
|
-
|
|
208
|
+
|
|
209
|
+
it("Deserialized method should be a DOM element", () => {
|
|
210
|
+
const cache = new MethodCache();
|
|
211
|
+
const serDeser = cache._storage._serDeser;
|
|
212
|
+
const cached = {value: { x:3, method:DomUtil.parse("<hello/>")} };
|
|
213
|
+
const serialized = serDeser(cached, true);
|
|
214
|
+
const deserialized = serDeser(serialized, false);
|
|
215
|
+
const method = deserialized.value.method;
|
|
216
|
+
// should be a DOM element, not a DOM document
|
|
217
|
+
expect(method.nodeType).toBe(1);
|
|
218
|
+
})
|
|
209
219
|
});
|
|
210
220
|
|
|
211
221
|
describe("Method cache for interfaces", function() {
|
|
@@ -280,4 +290,140 @@ describe('Caches', function() {
|
|
|
280
290
|
assert.strictEqual(urn, "xtk:session");
|
|
281
291
|
});
|
|
282
292
|
});
|
|
293
|
+
|
|
294
|
+
describe("SafeStorage", () => {
|
|
295
|
+
|
|
296
|
+
describe("JSON safe storage", () => {
|
|
297
|
+
|
|
298
|
+
it("Should find mock json from the cache", () => {
|
|
299
|
+
const map = {};
|
|
300
|
+
const delegate = {
|
|
301
|
+
getItem: jest.fn((key) => map[key]),
|
|
302
|
+
setItem: jest.fn((key, value) => map[key] = value)
|
|
303
|
+
}
|
|
304
|
+
const storage = new SafeStorage(delegate, "");
|
|
305
|
+
expect(storage.getItem("not_found")).toBeUndefined();
|
|
306
|
+
map["k1"] = `{ "hello": "world" }`;
|
|
307
|
+
expect(storage.getItem("k1")).toMatchObject({ hello: "world" });
|
|
308
|
+
map["k2"] = `{ "value": { "hello": "world" } }`;
|
|
309
|
+
expect(storage.getItem("k2")).toMatchObject({ value: { hello: "world" } });
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
describe("XML safe storage", () => {
|
|
314
|
+
|
|
315
|
+
const xmlSerDeser = (item, serDeser) => {
|
|
316
|
+
if (serDeser) {
|
|
317
|
+
const xml = DomUtil.toXMLString(item.value);
|
|
318
|
+
const value = {...item, value: xml };
|
|
319
|
+
return JSON.stringify(value);
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
const json = JSON.parse(item);
|
|
323
|
+
const dom = DomUtil.parse(json.value);
|
|
324
|
+
return {...json, value:dom.documentElement};
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
it("Should find mock xml from the cache", () => {
|
|
329
|
+
const map = {};
|
|
330
|
+
const delegate = {
|
|
331
|
+
getItem: jest.fn((key) => map[key]),
|
|
332
|
+
setItem: jest.fn((key, value) => map[key] = value)
|
|
333
|
+
}
|
|
334
|
+
const storage = new SafeStorage(delegate, "", xmlSerDeser);
|
|
335
|
+
expect(storage.getItem("not_found")).toBeUndefined();
|
|
336
|
+
map["k1"] = `{ "hello": "world" }`;
|
|
337
|
+
expect(storage.getItem("k1")).toBeUndefined(); // k1 cached object does not have "value" attribute containing serialized XML
|
|
338
|
+
map["k1"] = `{ "hello": "world", "value": "" }`;
|
|
339
|
+
expect(storage.getItem("k1")).toBeUndefined(); // k1 cached object does not have "value" attribute containing serialized XML
|
|
340
|
+
map["k1"] = `{ "value": { "hello": "world" } }`;
|
|
341
|
+
expect(storage.getItem("k2")).toBeUndefined(); // k1 cached object does not have "value" attribute but it's not valid XML
|
|
342
|
+
map["k1"] = `{ "value": "" } }`;
|
|
343
|
+
expect(storage.getItem("k1")).toBeUndefined(); // k1 cached object does not have "value" attribute but it's not valid XML
|
|
344
|
+
map["k1"] = `{ "value": "bad" } }`;
|
|
345
|
+
expect(storage.getItem("k1")).toBeUndefined(); // k1 cached object does not have "value" attribute but it's not valid XML
|
|
346
|
+
map["k2"] = `{ "value": "<hello/>" }`;
|
|
347
|
+
expect(storage.getItem("k2").value.tagName).toBe("hello");
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
describe("Cache seralizers", () => {
|
|
353
|
+
it("Should serialize json", () => {
|
|
354
|
+
const cache = new OptionCache();
|
|
355
|
+
const serDeser = cache._storage._serDeser;
|
|
356
|
+
expect(serDeser({ hello: "World" }, true)).toBe('{"hello":"World"}');
|
|
357
|
+
expect(serDeser({ }, true)).toBe('{}');
|
|
358
|
+
expect(() => {serDeser(null, true)}).toThrow("Cannot serialize");
|
|
359
|
+
expect(() => {serDeser(undefined, true)}).toThrow("Cannot serialize");
|
|
360
|
+
expect(() => {serDeser("", true)}).toThrow("Cannot serialize");
|
|
361
|
+
expect(() => {serDeser("Hello", true)}).toThrow("Cannot serialize");
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
it("Should deserialize json", () => {
|
|
365
|
+
const cache = new OptionCache();
|
|
366
|
+
const serDeser = cache._storage._serDeser;
|
|
367
|
+
expect(serDeser('{"hello":"World"}', false)).toMatchObject({ hello: "World" });
|
|
368
|
+
expect(serDeser('{}', false)).toMatchObject({ });
|
|
369
|
+
expect(() => {serDeser(null, false)}).toThrow("Cannot deserialize");
|
|
370
|
+
expect(() => {serDeser(undefined, false)}).toThrow("Cannot deserialize");
|
|
371
|
+
expect(() => {serDeser("", false)}).toThrow("Cannot deserialize");
|
|
372
|
+
expect(() => {serDeser("Hello", false)}).toThrow("Unexpected token");
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
it("Should serialize XML entity", () => {
|
|
376
|
+
const cache = new XtkEntityCache();
|
|
377
|
+
const serDeser = cache._storage._serDeser;
|
|
378
|
+
expect(serDeser({value: DomUtil.parse("<hello/>")}, true)).toBe('{"value":"<hello/>"}')
|
|
379
|
+
expect(() => { serDeser({}, true); }).toThrow();
|
|
380
|
+
expect(() => { serDeser(null, true); }).toThrow();
|
|
381
|
+
expect(() => { serDeser(undefined, true); }).toThrow();
|
|
382
|
+
expect(() => { serDeser("", true); }).toThrow();
|
|
383
|
+
expect(() => { serDeser("Hello", true); }).toThrow();
|
|
384
|
+
})
|
|
385
|
+
|
|
386
|
+
it("Should deserialize XML entity", () => {
|
|
387
|
+
const cache = new XtkEntityCache();
|
|
388
|
+
const serDeser = cache._storage._serDeser;
|
|
389
|
+
expect(DomUtil.toXMLString(serDeser(`{"value":"<hello/>"}`, false).value)).toBe("<hello/>");
|
|
390
|
+
expect(() => {serDeser(null, false)}).toThrow();
|
|
391
|
+
expect(() => {serDeser(undefined, false)}).toThrow();
|
|
392
|
+
expect(() => {serDeser("", false)}).toThrow();
|
|
393
|
+
expect(() => {serDeser("Hello", false)}).toThrow();
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
it("Should serialize methods", () => {
|
|
397
|
+
const cache = new MethodCache();
|
|
398
|
+
const serDeser = cache._storage._serDeser;
|
|
399
|
+
expect(serDeser({value: { x:3, method:DomUtil.parse("<hello/>")} }, true)).toBe('{"value":{"x":3,"method":"<hello/>"}}')
|
|
400
|
+
expect(() => { serDeser({value: { x:3 }}, true); }).toThrow();
|
|
401
|
+
expect(() => { serDeser({}, true); }).toThrow();
|
|
402
|
+
expect(() => { serDeser(null, true); }).toThrow();
|
|
403
|
+
expect(() => { serDeser(undefined, true); }).toThrow();
|
|
404
|
+
expect(() => { serDeser("", true); }).toThrow();
|
|
405
|
+
expect(() => { serDeser("Hello", true); }).toThrow();
|
|
406
|
+
})
|
|
407
|
+
|
|
408
|
+
it("Should deserialize methods", () => {
|
|
409
|
+
const cache = new MethodCache();
|
|
410
|
+
const serDeser = cache._storage._serDeser;
|
|
411
|
+
expect(DomUtil.toXMLString(serDeser('{"value":{"x":3,"method":"<hello/>"}}', false).value.method)).toBe("<hello/>");
|
|
412
|
+
expect(() => { serDeser('{"value":{"x":3}}', false); }).toThrow();
|
|
413
|
+
expect(() => { serDeser({}, false); }).toThrow();
|
|
414
|
+
expect(() => { serDeser(null, false); }).toThrow();
|
|
415
|
+
expect(() => { serDeser(undefined, false); }).toThrow();
|
|
416
|
+
expect(() => { serDeser("", false); }).toThrow();
|
|
417
|
+
expect(() => { serDeser("Hello", false); }).toThrow();
|
|
418
|
+
})
|
|
419
|
+
|
|
420
|
+
it("Method serialization should not change initial object", () => {
|
|
421
|
+
const cache = new MethodCache();
|
|
422
|
+
const serDeser = cache._storage._serDeser;
|
|
423
|
+
const cached = {value: { x:3, method:DomUtil.parse("<hello/>")} };
|
|
424
|
+
serDeser(cached, true); // make sure this call does not change the input parameter "cached"
|
|
425
|
+
expect(cached.value.x).toBe(3);
|
|
426
|
+
expect(cached.value.method.documentElement.tagName).toBe("hello");
|
|
427
|
+
})
|
|
428
|
+
})
|
|
283
429
|
});
|
package/test/client.test.js
CHANGED
|
@@ -22,12 +22,13 @@ const { Client, ConnectionParameters } = require('../src/client.js');
|
|
|
22
22
|
const DomUtil = require('../src/domUtil.js').DomUtil;
|
|
23
23
|
const Mock = require('./mock.js').Mock;
|
|
24
24
|
const { HttpError } = require('../src/transport.js');
|
|
25
|
+
const { Cipher } = require('../src/crypto.js');
|
|
26
|
+
const { EntityAccessor } = require('../src/entityAccessor.js');
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
describe('ACC Client', function () {
|
|
28
30
|
|
|
29
31
|
describe('Init', function () {
|
|
30
|
-
|
|
31
32
|
it('Should create client', async function () {
|
|
32
33
|
const client = await Mock.makeClient();
|
|
33
34
|
const NLWS = client.NLWS;
|
|
@@ -605,11 +606,13 @@ describe('ACC Client', function () {
|
|
|
605
606
|
const client = await Mock.makeClient();
|
|
606
607
|
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
607
608
|
await client.NLWS.xtkSession.logon();
|
|
609
|
+
const key = Mock.makeKey();
|
|
610
|
+
const encrypted = new Cipher(key).encryptPassword("mid");
|
|
608
611
|
|
|
609
612
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
|
|
610
|
-
client._transport.mockReturnValueOnce(Mock.GET_MID_EXT_ACCOUNT_RESPONSE);
|
|
613
|
+
client._transport.mockReturnValueOnce(Mock.GET_MID_EXT_ACCOUNT_RESPONSE(encrypted));
|
|
611
614
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
612
|
-
client._transport.mockReturnValueOnce(Mock.GET_SECRET_KEY_OPTION_RESPONSE);
|
|
615
|
+
client._transport.mockReturnValueOnce(Mock.GET_SECRET_KEY_OPTION_RESPONSE(key));
|
|
613
616
|
var connectionParameters = await sdk.ConnectionParameters.ofExternalAccount(client, "defaultEmailMid");
|
|
614
617
|
var midClient = await sdk.init(connectionParameters);
|
|
615
618
|
midClient._transport = jest.fn();
|
|
@@ -631,11 +634,13 @@ describe('ACC Client', function () {
|
|
|
631
634
|
const client = await Mock.makeClient();
|
|
632
635
|
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
633
636
|
await client.NLWS.xtkSession.logon();
|
|
637
|
+
const key = Mock.makeKey();
|
|
638
|
+
const encrypted = new Cipher(key).encryptPassword("mid");
|
|
634
639
|
|
|
635
640
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
|
|
636
|
-
client._transport.mockReturnValueOnce(Mock.GET_BAD_EXT_ACCOUNT_RESPONSE);
|
|
641
|
+
client._transport.mockReturnValueOnce(Mock.GET_BAD_EXT_ACCOUNT_RESPONSE(encrypted));
|
|
637
642
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
638
|
-
client._transport.mockReturnValueOnce(Mock.GET_SECRET_KEY_OPTION_RESPONSE);
|
|
643
|
+
client._transport.mockReturnValueOnce(Mock.GET_SECRET_KEY_OPTION_RESPONSE(key));
|
|
639
644
|
await expect(async () => {
|
|
640
645
|
return sdk.ConnectionParameters.ofExternalAccount(client, "bad");
|
|
641
646
|
}).rejects.toMatchObject({ errorCode: "SDK-000005" });
|
|
@@ -643,14 +648,16 @@ describe('ACC Client', function () {
|
|
|
643
648
|
|
|
644
649
|
it("Should fail if invalid representation", async () => {
|
|
645
650
|
const client = await Mock.makeClient();
|
|
651
|
+
const key = Mock.makeKey();
|
|
652
|
+
const encrypted = new Cipher(key).encryptPassword("mid");
|
|
646
653
|
|
|
647
654
|
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
648
655
|
await client.NLWS.xtkSession.logon();
|
|
649
656
|
|
|
650
657
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
|
|
651
|
-
client._transport.mockReturnValueOnce(Mock.GET_MID_EXT_ACCOUNT_RESPONSE);
|
|
658
|
+
client._transport.mockReturnValueOnce(Mock.GET_MID_EXT_ACCOUNT_RESPONSE(encrypted));
|
|
652
659
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
653
|
-
client._transport.mockReturnValueOnce(Mock.GET_SECRET_KEY_OPTION_RESPONSE);
|
|
660
|
+
client._transport.mockReturnValueOnce(Mock.GET_SECRET_KEY_OPTION_RESPONSE(key));
|
|
654
661
|
|
|
655
662
|
await expect(async () => {
|
|
656
663
|
client._representation = "Dummy";
|
|
@@ -664,14 +671,16 @@ describe('ACC Client', function () {
|
|
|
664
671
|
it("Should fail not fail with SimpleJson representation", async () => {
|
|
665
672
|
const client = await Mock.makeClient();
|
|
666
673
|
client._representation = "SimpleJson";
|
|
674
|
+
const key = Mock.makeKey();
|
|
675
|
+
const encrypted = new Cipher(key).encryptPassword("mid");
|
|
667
676
|
|
|
668
677
|
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
669
678
|
await client.NLWS.xtkSession.logon();
|
|
670
679
|
|
|
671
680
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
|
|
672
|
-
client._transport.mockReturnValueOnce(Mock.GET_MID_EXT_ACCOUNT_RESPONSE);
|
|
681
|
+
client._transport.mockReturnValueOnce(Mock.GET_MID_EXT_ACCOUNT_RESPONSE(encrypted));
|
|
673
682
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
674
|
-
client._transport.mockReturnValueOnce(Mock.GET_SECRET_KEY_OPTION_RESPONSE);
|
|
683
|
+
client._transport.mockReturnValueOnce(Mock.GET_SECRET_KEY_OPTION_RESPONSE(key));
|
|
675
684
|
|
|
676
685
|
var connectionParameters = await sdk.ConnectionParameters.ofExternalAccount(client, "defaultEmailMid");
|
|
677
686
|
await sdk.init(connectionParameters);
|
|
@@ -681,9 +690,10 @@ describe('ACC Client', function () {
|
|
|
681
690
|
const client = await Mock.makeClient();
|
|
682
691
|
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
683
692
|
await client.NLWS.xtkSession.logon();
|
|
684
|
-
|
|
693
|
+
const key = Mock.makeKey();
|
|
694
|
+
|
|
685
695
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
686
|
-
client._transport.mockReturnValueOnce(Mock.GET_SECRET_KEY_OPTION_RESPONSE);
|
|
696
|
+
client._transport.mockReturnValueOnce(Mock.GET_SECRET_KEY_OPTION_RESPONSE(key));
|
|
687
697
|
var cipher = await client._getSecretKeyCipher();
|
|
688
698
|
expect(cipher).not.toBeNull();
|
|
689
699
|
expect(cipher.key).not.toBeNull();
|
|
@@ -1897,6 +1907,200 @@ describe('ACC Client', function () {
|
|
|
1897
1907
|
})
|
|
1898
1908
|
})
|
|
1899
1909
|
|
|
1910
|
+
describe("Bearer token authentication", () => {
|
|
1911
|
+
// Bearer token authentication is used when embedding IMS for authentication
|
|
1912
|
+
it("Should create logged client", async() => {
|
|
1913
|
+
const connectionParameters = sdk.ConnectionParameters.ofBearerToken("http://acc-sdk:8080");
|
|
1914
|
+
const client = await sdk.init(connectionParameters);
|
|
1915
|
+
client._transport = jest.fn();
|
|
1916
|
+
client._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
|
|
1917
|
+
expect(client.isLogged()).toBeFalsy();
|
|
1918
|
+
await client.logon();
|
|
1919
|
+
expect(client.isLogged()).toBeTruthy();
|
|
1920
|
+
const transport = client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
|
|
1921
|
+
await client.logoff();
|
|
1922
|
+
expect(client.isLogged()).toBeFalsy();
|
|
1923
|
+
// Ensure logoff has been called
|
|
1924
|
+
expect(transport.mock.calls.length).toBe(2);
|
|
1925
|
+
})
|
|
1926
|
+
|
|
1927
|
+
it("Call SAOP method", async () => {
|
|
1928
|
+
const connectionParameters = sdk.ConnectionParameters.ofBearerToken("http://acc-sdk:8080", "$token$");
|
|
1929
|
+
const client = await sdk.init(connectionParameters);
|
|
1930
|
+
client._transport = jest.fn();
|
|
1931
|
+
client._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
|
|
1932
|
+
await client.logon();
|
|
1933
|
+
client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
|
|
1934
|
+
var queryDef = {
|
|
1935
|
+
"schema": "nms:extAccount",
|
|
1936
|
+
"operation": "select",
|
|
1937
|
+
"select": {
|
|
1938
|
+
"node": [
|
|
1939
|
+
{ "expr": "@id" },
|
|
1940
|
+
{ "expr": "@name" }
|
|
1941
|
+
]
|
|
1942
|
+
}
|
|
1943
|
+
};
|
|
1944
|
+
|
|
1945
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
|
|
1946
|
+
<SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:queryDef' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
|
|
1947
|
+
<SOAP-ENV:Body>
|
|
1948
|
+
<ExecuteQueryResponse xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
|
|
1949
|
+
<pdomOutput xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
|
|
1950
|
+
<extAccount-collection/>
|
|
1951
|
+
</pdomOutput></ExecuteQueryResponse>
|
|
1952
|
+
</SOAP-ENV:Body>
|
|
1953
|
+
</SOAP-ENV:Envelope>`));
|
|
1954
|
+
|
|
1955
|
+
// Select should return empty array
|
|
1956
|
+
var query = client.NLWS.xtkQueryDef.create(queryDef);
|
|
1957
|
+
var extAccount = await query.executeQuery();
|
|
1958
|
+
expect(extAccount).toEqual({ extAccount: [] });
|
|
1959
|
+
});
|
|
1960
|
+
|
|
1961
|
+
it("Expired session refresh client callback", async () => {
|
|
1962
|
+
let refreshClient = async () => {
|
|
1963
|
+
const connectionParameters = sdk.ConnectionParameters.ofSecurityToken("http://acc-sdk:8080",
|
|
1964
|
+
"$security_token$", {refreshClient: refreshClient});
|
|
1965
|
+
const newClient = await sdk.init(connectionParameters);
|
|
1966
|
+
newClient._transport = jest.fn();
|
|
1967
|
+
newClient._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
|
|
1968
|
+
await newClient.logon();
|
|
1969
|
+
return newClient;
|
|
1970
|
+
}
|
|
1971
|
+
const connectionParameters = sdk.ConnectionParameters.ofBearerToken("http://acc-sdk:8080",
|
|
1972
|
+
"$token$", {refreshClient: refreshClient});
|
|
1973
|
+
const client = await sdk.init(connectionParameters);
|
|
1974
|
+
client.traceAPICalls(true);
|
|
1975
|
+
client._transport = jest.fn();
|
|
1976
|
+
client._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
|
|
1977
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`XSV-350008 Session has expired or is invalid. Please reconnect.`));
|
|
1978
|
+
client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
|
|
1979
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
|
|
1980
|
+
<SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:queryDef' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
|
|
1981
|
+
<SOAP-ENV:Body>
|
|
1982
|
+
<ExecuteQueryResponse xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
|
|
1983
|
+
<pdomOutput xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
|
|
1984
|
+
<extAccount-collection/>
|
|
1985
|
+
</pdomOutput></ExecuteQueryResponse>
|
|
1986
|
+
</SOAP-ENV:Body>
|
|
1987
|
+
</SOAP-ENV:Envelope>`));
|
|
1988
|
+
await client.logon();
|
|
1989
|
+
var queryDef = {
|
|
1990
|
+
"schema": "nms:extAccount",
|
|
1991
|
+
"operation": "select",
|
|
1992
|
+
"select": {
|
|
1993
|
+
"node": [
|
|
1994
|
+
{ "expr": "@id" },
|
|
1995
|
+
{ "expr": "@name" }
|
|
1996
|
+
]
|
|
1997
|
+
}
|
|
1998
|
+
};
|
|
1999
|
+
var query = client.NLWS.xtkQueryDef.create(queryDef);
|
|
2000
|
+
var extAccount = await query.executeQuery();
|
|
2001
|
+
expect(extAccount).toEqual({ extAccount: [] });
|
|
2002
|
+
// Same test as before traceAPICalls = false for code coverage
|
|
2003
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`XSV-350008 Session has expired or is invalid. Please reconnect.`));
|
|
2004
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
|
|
2005
|
+
<SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:queryDef' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
|
|
2006
|
+
<SOAP-ENV:Body>
|
|
2007
|
+
<ExecuteQueryResponse xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
|
|
2008
|
+
<pdomOutput xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
|
|
2009
|
+
<extAccount-collection/>
|
|
2010
|
+
</pdomOutput></ExecuteQueryResponse>
|
|
2011
|
+
</SOAP-ENV:Body>
|
|
2012
|
+
</SOAP-ENV:Envelope>`));
|
|
2013
|
+
client.traceAPICalls(false);
|
|
2014
|
+
var query1 = client.NLWS.xtkQueryDef.create(queryDef);
|
|
2015
|
+
const extAccount1 = await query1.executeQuery();
|
|
2016
|
+
expect(extAccount1).toEqual({ extAccount: [] });
|
|
2017
|
+
});
|
|
2018
|
+
|
|
2019
|
+
it("Expired session refresh client callback for code coverage", async () => {
|
|
2020
|
+
let refreshClient = async () => {
|
|
2021
|
+
const connectionParameters = sdk.ConnectionParameters.ofSessionToken("http://acc-sdk:8080", "$session_token$");
|
|
2022
|
+
const newClient = await sdk.init(connectionParameters);
|
|
2023
|
+
newClient._transport = jest.fn();
|
|
2024
|
+
newClient._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
|
|
2025
|
+
await newClient.logon();
|
|
2026
|
+
return newClient;
|
|
2027
|
+
}
|
|
2028
|
+
const connectionParameters = sdk.ConnectionParameters.ofBearerToken("http://acc-sdk:8080",
|
|
2029
|
+
"$token$", {refreshClient: refreshClient});
|
|
2030
|
+
const client = await sdk.init(connectionParameters);
|
|
2031
|
+
client.traceAPICalls(true);
|
|
2032
|
+
client._transport = jest.fn();
|
|
2033
|
+
client._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
|
|
2034
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`XSV-350008 Session has expired or is invalid. Please reconnect.`));
|
|
2035
|
+
client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
|
|
2036
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
|
|
2037
|
+
<SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:queryDef' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
|
|
2038
|
+
<SOAP-ENV:Body>
|
|
2039
|
+
<ExecuteQueryResponse xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
|
|
2040
|
+
<pdomOutput xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
|
|
2041
|
+
<extAccount-collection/>
|
|
2042
|
+
</pdomOutput></ExecuteQueryResponse>
|
|
2043
|
+
</SOAP-ENV:Body>
|
|
2044
|
+
</SOAP-ENV:Envelope>`));
|
|
2045
|
+
await client.logon();
|
|
2046
|
+
var queryDef = {
|
|
2047
|
+
"schema": "nms:extAccount",
|
|
2048
|
+
"operation": "select",
|
|
2049
|
+
"select": {
|
|
2050
|
+
"node": [
|
|
2051
|
+
{ "expr": "@id" },
|
|
2052
|
+
{ "expr": "@name" }
|
|
2053
|
+
]
|
|
2054
|
+
}
|
|
2055
|
+
};
|
|
2056
|
+
var query = client.NLWS.xtkQueryDef.create(queryDef);
|
|
2057
|
+
var extAccount = await query.executeQuery();
|
|
2058
|
+
expect(extAccount).toEqual({ extAccount: [] });
|
|
2059
|
+
});
|
|
2060
|
+
|
|
2061
|
+
it("Expired session refresh client callback retry failure", async () => {
|
|
2062
|
+
let refreshClient = async () => {
|
|
2063
|
+
const connectionParameters = sdk.ConnectionParameters.ofBearerToken("http://acc-sdk:8080",
|
|
2064
|
+
"$token$", {refreshClient: refreshClient});
|
|
2065
|
+
const newClient = await sdk.init(connectionParameters);
|
|
2066
|
+
newClient._transport = jest.fn();
|
|
2067
|
+
newClient._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
|
|
2068
|
+
await newClient.logon();
|
|
2069
|
+
return newClient;
|
|
2070
|
+
}
|
|
2071
|
+
const connectionParameters = sdk.ConnectionParameters.ofSecurityToken("http://acc-sdk:8080",
|
|
2072
|
+
"$security_token$", {refreshClient: refreshClient});
|
|
2073
|
+
const client = await sdk.init(connectionParameters);
|
|
2074
|
+
client._transport = jest.fn();
|
|
2075
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`XSV-350008 Session has expired or is invalid. Please reconnect.`));
|
|
2076
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`XSV-350008 Session has expired or is invalid. Please reconnect.`));
|
|
2077
|
+
client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
|
|
2078
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
|
|
2079
|
+
<SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:queryDef' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
|
|
2080
|
+
<SOAP-ENV:Body>
|
|
2081
|
+
<ExecuteQueryResponse xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
|
|
2082
|
+
<pdomOutput xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
|
|
2083
|
+
<extAccount-collection/>
|
|
2084
|
+
</pdomOutput></ExecuteQueryResponse>
|
|
2085
|
+
</SOAP-ENV:Body>
|
|
2086
|
+
</SOAP-ENV:Envelope>`));
|
|
2087
|
+
await client.logon();
|
|
2088
|
+
var queryDef = {
|
|
2089
|
+
"schema": "nms:extAccount",
|
|
2090
|
+
"operation": "select",
|
|
2091
|
+
"select": {
|
|
2092
|
+
"node": [
|
|
2093
|
+
{ "expr": "@id" },
|
|
2094
|
+
{ "expr": "@name" }
|
|
2095
|
+
]
|
|
2096
|
+
}
|
|
2097
|
+
};
|
|
2098
|
+
var query = client.NLWS.xtkQueryDef.create(queryDef);
|
|
2099
|
+
await expect(query.executeQuery()).rejects.toMatchObject({ errorCode: "SDK-000012" });
|
|
2100
|
+
expect(client._transport.mock.calls.length).toBe(2);
|
|
2101
|
+
});
|
|
2102
|
+
})
|
|
2103
|
+
|
|
1900
2104
|
describe("Logon should always return a promise", () => {
|
|
1901
2105
|
|
|
1902
2106
|
it("Should return a promise with UserPassword", async () => {
|
|
@@ -1909,6 +2113,16 @@ describe('ACC Client', function () {
|
|
|
1909
2113
|
await result;
|
|
1910
2114
|
})
|
|
1911
2115
|
|
|
2116
|
+
it("Should return a promise with bearer token", async () => {
|
|
2117
|
+
const connectionParameters = sdk.ConnectionParameters.ofBearerToken("http://acc-sdk:8080", "$token$");
|
|
2118
|
+
const client = await sdk.init(connectionParameters);
|
|
2119
|
+
client._transport = jest.fn();
|
|
2120
|
+
client._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
|
|
2121
|
+
const result = client.logon();
|
|
2122
|
+
expect(result instanceof Promise).toBe(true);
|
|
2123
|
+
await result;
|
|
2124
|
+
})
|
|
2125
|
+
|
|
1912
2126
|
it("Should return a promise with UserAndServiceToken", async () => {
|
|
1913
2127
|
const connectionParameters = sdk.ConnectionParameters.ofUserAndServiceToken("http://acc-sdk:8080", "$user$", "$service_token$");
|
|
1914
2128
|
const client = await sdk.init(connectionParameters);
|
|
@@ -2069,15 +2283,15 @@ describe('ACC Client', function () {
|
|
|
2069
2283
|
it("Should ignore protocol for local storage root key", async () => {
|
|
2070
2284
|
var connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("http://acc-sdk:8080", "admin", "admin", {});
|
|
2071
2285
|
var client = await sdk.init(connectionParameters);
|
|
2072
|
-
expect(client._optionCache._storage._rootKey).toBe("acc.js.sdk.1.0.
|
|
2286
|
+
expect(client._optionCache._storage._rootKey).toBe("acc.js.sdk.1.0.7.acc-sdk:8080.cache.OptionCache$");
|
|
2073
2287
|
|
|
2074
2288
|
connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("https://acc-sdk:8080", "admin", "admin", {});
|
|
2075
2289
|
client = await sdk.init(connectionParameters);
|
|
2076
|
-
expect(client._optionCache._storage._rootKey).toBe("acc.js.sdk.1.0.
|
|
2290
|
+
expect(client._optionCache._storage._rootKey).toBe("acc.js.sdk.1.0.7.acc-sdk:8080.cache.OptionCache$");
|
|
2077
2291
|
|
|
2078
2292
|
connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("acc-sdk:8080", "admin", "admin", {});
|
|
2079
2293
|
client = await sdk.init(connectionParameters);
|
|
2080
|
-
expect(client._optionCache._storage._rootKey).toBe("acc.js.sdk.1.0.
|
|
2294
|
+
expect(client._optionCache._storage._rootKey).toBe("acc.js.sdk.1.0.7.acc-sdk:8080.cache.OptionCache$");
|
|
2081
2295
|
})
|
|
2082
2296
|
|
|
2083
2297
|
it("Should support no storage", async () => {
|
|
@@ -2094,5 +2308,118 @@ describe('ACC Client', function () {
|
|
|
2094
2308
|
expect(value).toBe('uFE80000000000000F1FA913DD7CC7C480041161C');
|
|
2095
2309
|
expect(storage.getItem.mock.calls.length).toBe(0); // storage is disabled and should not have been called
|
|
2096
2310
|
})
|
|
2311
|
+
|
|
2312
|
+
it("Should cache XML in storage", async () => {
|
|
2313
|
+
const map = {};
|
|
2314
|
+
const storage = {
|
|
2315
|
+
getItem: jest.fn((key) => map[key]),
|
|
2316
|
+
setItem: jest.fn((key, value) => map[key] = value)
|
|
2317
|
+
}
|
|
2318
|
+
let client = await Mock.makeClient({ storage: storage });
|
|
2319
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
2320
|
+
await client.NLWS.xtkSession.logon();
|
|
2321
|
+
client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
|
|
2322
|
+
await client.getSchema("nms:extAccount");
|
|
2323
|
+
// Schema should have been cached to local storage
|
|
2324
|
+
expect(storage.setItem.mock.calls.length).toBe(1);
|
|
2325
|
+
expect(storage.setItem.mock.calls[0][0]).toMatch("cache.XtkEntityCache$xtk:schema|nms:extAccount");
|
|
2326
|
+
// Value is the cached object, it should not be an empty object
|
|
2327
|
+
const cached = JSON.parse(storage.setItem.mock.calls[0][1]);
|
|
2328
|
+
expect(Object.keys(cached.value).length).toBeGreaterThan(0);
|
|
2329
|
+
expect(cached.value).toMatch("<schema");
|
|
2330
|
+
|
|
2331
|
+
// Now simulate reusing the local storage. We need a new client to make sure we do not reuse
|
|
2332
|
+
// the in-memory cache of the client.
|
|
2333
|
+
client = await Mock.makeClient({ storage: storage });
|
|
2334
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
2335
|
+
await client.NLWS.xtkSession.logon();
|
|
2336
|
+
client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
|
|
2337
|
+
await client.getSchema("nms:extAccount");
|
|
2338
|
+
})
|
|
2097
2339
|
})
|
|
2340
|
+
|
|
2341
|
+
describe("Get Schema, cache and representations", () => {
|
|
2342
|
+
it("Should get schema with no cache", async () => {
|
|
2343
|
+
const client = await Mock.makeClient();
|
|
2344
|
+
client.clearAllCaches();
|
|
2345
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
2346
|
+
await client.NLWS.xtkSession.logon();
|
|
2347
|
+
|
|
2348
|
+
client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
|
|
2349
|
+
var schema = await client.getSchema("nms:extAccount");
|
|
2350
|
+
expect(schema["namespace"]).toBe("nms");
|
|
2351
|
+
expect(schema["name"]).toBe("extAccount");
|
|
2352
|
+
});
|
|
2353
|
+
});
|
|
2354
|
+
|
|
2355
|
+
describe("Calling SOAP method with parameters as a function", () => {
|
|
2356
|
+
it("Should make SOAP call", async () => {
|
|
2357
|
+
const client = await Mock.makeClient();
|
|
2358
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
2359
|
+
await client.NLWS.xtkSession.logon();
|
|
2360
|
+
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
2361
|
+
client._transport.mockReturnValueOnce(Mock.GET_DATABASEID_RESPONSE);
|
|
2362
|
+
const scope = client.NLWS["xtkSession"];
|
|
2363
|
+
const fn = scope["getOption"];
|
|
2364
|
+
const result = await fn.call(scope, "XtkDatabaseId");
|
|
2365
|
+
expect(result).toMatchObject([ "uFE80000000000000F1FA913DD7CC7C480041161C", 6 ]);
|
|
2366
|
+
});
|
|
2367
|
+
|
|
2368
|
+
it("Should make static SOAP call with functional parameters", async () => {
|
|
2369
|
+
const client = await Mock.makeClient();
|
|
2370
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
2371
|
+
await client.NLWS.xtkSession.logon();
|
|
2372
|
+
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
2373
|
+
const scope = client.NLWS["xtkSession"];
|
|
2374
|
+
const method = scope["staticP1"]; // SOAP method to call
|
|
2375
|
+
const paramsFn = jest.fn(); // function returning SOAP call parameters
|
|
2376
|
+
paramsFn.mockReturnValueOnce(["XtkDatabaseId"]);
|
|
2377
|
+
|
|
2378
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
|
|
2379
|
+
<SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:session' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
|
|
2380
|
+
<SOAP-ENV:Body>
|
|
2381
|
+
<StaticP1Response xmlns='urn:xtk:session' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
|
|
2382
|
+
</StaticP1Response>
|
|
2383
|
+
</SOAP-ENV:Body>
|
|
2384
|
+
</SOAP-ENV:Envelope>`));
|
|
2385
|
+
|
|
2386
|
+
const result = await method.call(scope, paramsFn);
|
|
2387
|
+
expect(result).toBeNull();
|
|
2388
|
+
expect(paramsFn.mock.calls.length).toBe(1);
|
|
2389
|
+
// first parameter is the XML method
|
|
2390
|
+
const xmlMethod = paramsFn.mock.calls[0][0];
|
|
2391
|
+
expect(EntityAccessor.getAttributeAsString(xmlMethod, "name")).toBe("StaticP1");
|
|
2392
|
+
// second parameter is the call context
|
|
2393
|
+
expect(paramsFn.mock.calls[0][1]).toMatchObject({ schemaId: "xtk:session", namespace: "xtkSession" });
|
|
2394
|
+
});
|
|
2395
|
+
|
|
2396
|
+
it("Should make non static SOAP call with functional parameters", async () => {
|
|
2397
|
+
const client = await Mock.makeClient();
|
|
2398
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
2399
|
+
await client.NLWS.xtkSession.logon();
|
|
2400
|
+
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
2401
|
+
const scope = client.NLWS["xtkSession"];
|
|
2402
|
+
const method = scope["nonStaticP1"]; // SOAP method to call
|
|
2403
|
+
const paramsFn = jest.fn(); // function returning SOAP call parameters
|
|
2404
|
+
paramsFn.mockReturnValueOnce(["XtkDatabaseId"]);
|
|
2405
|
+
|
|
2406
|
+
client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
|
|
2407
|
+
<SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:session' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
|
|
2408
|
+
<SOAP-ENV:Body>
|
|
2409
|
+
<StaticP1Response xmlns='urn:xtk:session' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
|
|
2410
|
+
</StaticP1Response>
|
|
2411
|
+
</SOAP-ENV:Body>
|
|
2412
|
+
</SOAP-ENV:Envelope>`));
|
|
2413
|
+
|
|
2414
|
+
const object = scope.create({ dummy: true }); // "this" object for the non-static SOAP call
|
|
2415
|
+
const result = await method.call(object, paramsFn);
|
|
2416
|
+
expect(result).toBeNull();
|
|
2417
|
+
expect(paramsFn.mock.calls.length).toBe(1);
|
|
2418
|
+
// first parameter is the XML method
|
|
2419
|
+
const xmlMethod = paramsFn.mock.calls[0][0];
|
|
2420
|
+
expect(EntityAccessor.getAttributeAsString(xmlMethod, "name")).toBe("NonStaticP1");
|
|
2421
|
+
// second parameter is the call context
|
|
2422
|
+
expect(paramsFn.mock.calls[0][1]).toMatchObject({ schemaId: "xtk:session", namespace: "xtkSession" });
|
|
2423
|
+
});
|
|
2424
|
+
});
|
|
2098
2425
|
});
|