@adobe/acc-js-sdk 1.1.5 → 1.1.6

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.
@@ -0,0 +1,338 @@
1
+ /*
2
+ Copyright 2022 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+
13
+
14
+ /**********************************************************************************
15
+ *
16
+ * Unit tests for the cache refresher
17
+ *
18
+ *********************************************************************************/
19
+
20
+
21
+ const sdk = require('../src/index.js');
22
+ const { Cache } = require('../src/cache.js');
23
+ const Mock = require('./mock.js').Mock;
24
+ const CacheRefresher = require('../src/cacheRefresher.js').CacheRefresher;
25
+
26
+
27
+ describe("CacheRefresher cache", function () {
28
+
29
+ it('Should call refresh', async () => {
30
+ const client = await Mock.makeClient();
31
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
32
+
33
+ await client.NLWS.xtkSession.logon();
34
+ const cache = new Cache();
35
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
36
+
37
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_CLEAR_RESPONSE);
38
+ await cacheRefresher._callAndRefresh();
39
+ expect(cacheRefresher._refresherStateCache.get("buildNumber")).toBe("9469");
40
+ expect(cacheRefresher._refresherStateCache.get("time")).toBe("2022-07-28T14:38:55.766Z");
41
+
42
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_CLEAR_RESPONSE);
43
+ await cacheRefresher._callAndRefresh();
44
+ expect(cacheRefresher._refresherStateCache.get("buildNumber")).toBe("9469");
45
+ expect(cacheRefresher._refresherStateCache.get("time")).toBe("2022-07-28T14:38:55.766Z");
46
+
47
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
48
+ await client.NLWS.xtkSession.logoff();
49
+ });
50
+
51
+ it('Should call refresh after 1 seconds', async () => {
52
+ const connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("http://acc-sdk:8080", "admin", "admin");
53
+ const client = await sdk.init(connectionParameters);
54
+ client._transport = jest.fn();
55
+
56
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
57
+
58
+ await client.NLWS.xtkSession.logon();
59
+ expect(client.isLogged()).toBeTruthy();
60
+ const cache = new Cache();
61
+
62
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
63
+
64
+ expect(cacheRefresher._refresherStateCache.get("buildNumber")).toBeUndefined();
65
+ expect(cacheRefresher._refresherStateCache.get("time")).toBeUndefined();
66
+ client._transport.mockReturnValue(Promise.resolve(Mock.GETMODIFIEDENTITIES_CLEAR_RESPONSE));
67
+ jest.useFakeTimers();
68
+ cacheRefresher.startAutoRefresh(5000);
69
+ jest.advanceTimersByTime(6000);
70
+ jest.useRealTimers();
71
+
72
+ // to allow soap call to finish
73
+ await new Promise(process.nextTick);
74
+
75
+ expect(cacheRefresher._refresherStateCache.get("buildNumber")).toBe("9469");
76
+ expect(cacheRefresher._refresherStateCache.get("time")).toBe("2022-07-28T14:38:55.766Z");
77
+
78
+ cacheRefresher.stopAutoRefresh();
79
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
80
+ await client.NLWS.xtkSession.logoff();
81
+ });
82
+
83
+ it('Should send buildNumber when call refresh', async () => {
84
+ const client = await Mock.makeClient();
85
+ const logs = await Mock.withMockConsole(async () => {
86
+ client.traceAPICalls(true);
87
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
88
+
89
+ await client.NLWS.xtkSession.logon();
90
+
91
+ const cache = new Cache();
92
+
93
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
94
+ cacheRefresher._refresherStateCache.put("buildNumber", "9469");
95
+ cacheRefresher._refresherStateCache.put("time", "2022-07-28T14:38:55.766Z");
96
+
97
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_CLEAR_RESPONSE);
98
+ await cacheRefresher._callAndRefresh();
99
+ expect(cacheRefresher._refresherStateCache.get("buildNumber")).toBe("9469");
100
+ expect(cacheRefresher._refresherStateCache.get("time")).toBe("2022-07-28T14:38:55.766Z");
101
+
102
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
103
+
104
+
105
+ await client.NLWS.xtkSession.logoff();
106
+
107
+ })
108
+ expect(logs.length).toBe(6);
109
+ expect(logs[0]).toMatch(/SOAP.*request.*Logon/is)
110
+ expect(logs[1]).toMatch(/SOAP.*response.*LogonResponse/is)
111
+ expect(logs[2]).toMatch(/SOAP.*request.*buildNumber.*9469.*2022-07-28T14:38:55.766Z.*GetModifiedEntities*/is)
112
+ expect(logs[3]).toMatch(/SOAP.*response.*GetModifiedEntitiesResponse/is)
113
+ expect(logs[4]).toMatch(/SOAP.*request.*Logoff/is)
114
+ expect(logs[5]).toMatch(/SOAP.*response.*LogoffResponse/is)
115
+ });
116
+
117
+ it('Should refresh cache', async () => {
118
+ const client = await Mock.makeClient();
119
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
120
+
121
+ await client.NLWS.xtkSession.logon();
122
+ const cache = new Cache();
123
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
124
+
125
+ cache.put("xtk:schema|nms:recipient", "<content recipient>");
126
+ cache.put("xtk:schema|nms:replicationStrategy", "<content xtk:schema|nms:replicationStrategy>");
127
+ cache.put("xtk:schema|nms:operation", "<content xtk:schema|nms:operation>");
128
+ expect(cache.get("xtk:schema|nms:recipient")).toBe("<content recipient>");
129
+ expect(cache.get("xtk:schema|nms:replicationStrategy")).toBe("<content xtk:schema|nms:replicationStrategy>");
130
+ expect(cache.get("xtk:schema|nms:operation")).toBe("<content xtk:schema|nms:operation>");
131
+
132
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_SCHEMA_RESPONSE);
133
+ await cacheRefresher._callAndRefresh();
134
+ expect(cacheRefresher._refresherStateCache.get("buildNumber")).toBe("9469");
135
+ expect(cacheRefresher._refresherStateCache.get("time")).toBe("2022-07-28T15:32:00.785Z");
136
+ expect(cache.get("xtk:schema|nms:recipient")).toBeUndefined();
137
+ expect(cache.get("xtk:schema|nms:replicationStrategy")).toBeUndefined();
138
+ expect(cache.get("xtk:schema|nms:operation")).toBe("<content xtk:schema|nms:operation>");
139
+
140
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
141
+ await client.NLWS.xtkSession.logoff();
142
+ });
143
+
144
+ it('Should stop refresh if method not exist', async () => {
145
+ const client = await Mock.makeClient();
146
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
147
+
148
+ await client.NLWS.xtkSession.logon();
149
+ const cache = new Cache();
150
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
151
+
152
+ cacheRefresher.startAutoRefresh();
153
+
154
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_UNDEFINED_RESPONSE);
155
+ await cacheRefresher._callAndRefresh();
156
+ expect(cacheRefresher._refresherStateCache.get("buildNumber")).toBeUndefined();
157
+ expect(cacheRefresher._refresherStateCache.get("time")).toBeUndefined();
158
+ expect(cacheRefresher._intervalId).toBeNull();
159
+
160
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
161
+ await client.NLWS.xtkSession.logoff();
162
+ });
163
+
164
+ it('Should not stop refresh if error different from undefined', async () => {
165
+ const client = await Mock.makeClient();
166
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
167
+
168
+ await client.NLWS.xtkSession.logon();
169
+ const cache = new Cache();
170
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
171
+
172
+ cacheRefresher.startAutoRefresh();
173
+
174
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_ERROR_RESPONSE);
175
+ try {
176
+ await cacheRefresher._callAndRefresh();
177
+ fail('exception is expected');
178
+ } catch (e) {
179
+ expect(e).not.toBeNull();
180
+ }
181
+ expect(cacheRefresher._refresherStateCache.get("buildNumber")).toBeUndefined();
182
+ expect(cacheRefresher._refresherStateCache.get("time")).toBeUndefined();
183
+ expect(cacheRefresher._intervalId).not.toBeNull();
184
+
185
+ cacheRefresher.stopAutoRefresh();
186
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
187
+ await client.NLWS.xtkSession.logoff();
188
+ });
189
+
190
+ it('Should be able to call start refresh twice', async () => {
191
+ const client = await Mock.makeClient();
192
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
193
+
194
+ await client.NLWS.xtkSession.logon();
195
+ const cache = new Cache();
196
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
197
+
198
+ jest.useFakeTimers();
199
+ cacheRefresher.startAutoRefresh(100000);
200
+ expect(cacheRefresher._intervalId).not.toBeNull();
201
+ const firstIntervalId = cacheRefresher._intervalId;
202
+ cacheRefresher.startAutoRefresh(5000);
203
+ expect(cacheRefresher._intervalId).not.toBeNull();
204
+ expect(cacheRefresher._intervalId != firstIntervalId);
205
+
206
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_CLEAR_RESPONSE);
207
+
208
+ jest.advanceTimersByTime(6000);
209
+ jest.useRealTimers();
210
+
211
+ // to allow soap call to finish
212
+ await new Promise(process.nextTick);
213
+
214
+ expect(cacheRefresher._refresherStateCache.get("buildNumber")).toBe("9469");
215
+ expect(cacheRefresher._refresherStateCache.get("time")).toBe("2022-07-28T14:38:55.766Z");
216
+
217
+ cacheRefresher.stopAutoRefresh();
218
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
219
+ await client.NLWS.xtkSession.logoff();
220
+ });
221
+
222
+ it('Should notify when refresh cache', async () => {
223
+ const client = await Mock.makeClient();
224
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
225
+
226
+
227
+ class Listener {
228
+ constructor() {
229
+ this._schemas = {};
230
+ }
231
+ add(schemaId) {
232
+ this._schemas[schemaId] = "1";
233
+ }
234
+
235
+ invalidateCacheItem(schemaId) {
236
+ this._schemas[schemaId] = undefined;
237
+ }
238
+ getSchema(schemaId) {
239
+ return this._schemas[schemaId];
240
+ }
241
+ }
242
+
243
+ let listener = new Listener();
244
+ client._registerCacheChangeListener(listener);
245
+
246
+ await client.NLWS.xtkSession.logon();
247
+ const cache = new Cache();
248
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
249
+
250
+ cache.put("xtk:schema|nms:recipient", "<content recipient>");
251
+ cache.put("xtk:schema|nms:replicationStrategy", "<content xtk:schema|nms:replicationStrategy>");
252
+ cache.put("xtk:schema|nms:operation", "<content xtk:schema|nms:operation>");
253
+
254
+ listener.add("nms:recipient");
255
+
256
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_SCHEMA_RESPONSE);
257
+ await cacheRefresher._callAndRefresh();
258
+
259
+ expect(listener.getSchema("nms:recipient")).toBeUndefined();
260
+
261
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
262
+ await client.NLWS.xtkSession.logoff();
263
+ client._unregisterCacheChangeListener(listener);
264
+ });
265
+
266
+ it('Should protect callAndRefresh from re-entrance', async () => {
267
+ const client = await Mock.makeClient();
268
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
269
+ await client.NLWS.xtkSession.logon();
270
+ const cache = new Cache();
271
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
272
+ let count = 0;
273
+ cacheRefresher._callAndRefresh = jest.fn(() => { count = count + 1 });
274
+ expect(cacheRefresher._running).toBe(false);
275
+ await cacheRefresher._callAndRefresh();
276
+ expect(count).toBe(1);
277
+ expect(cacheRefresher._running).toBe(false);
278
+ await cacheRefresher._safeCallAndRefresh();
279
+ expect(count).toBe(2);
280
+ expect(cacheRefresher._running).toBe(false);
281
+
282
+ cacheRefresher._running = true;
283
+ await cacheRefresher._safeCallAndRefresh();
284
+ expect(count).toBe(2); // should not have been called since already executing
285
+ })
286
+
287
+ it('Throw CampaignException when calling _callAndRefresh without logon', async () => {
288
+ const client = await Mock.makeClient();
289
+ const cache = new Cache();
290
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
291
+
292
+ try {
293
+ await cacheRefresher._callAndRefresh();
294
+ fail('exception is expected');
295
+ } catch (e) {
296
+ expect(e.name).toBe("CampaignException");
297
+ expect(e.errorCode).toBe("SDK-000010");
298
+ }
299
+ });
300
+
301
+ it('Ignore error when calling _safeCallAndRefresh without logon', async () => {
302
+ const client = await Mock.makeClient();
303
+ const cache = new Cache();
304
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
305
+
306
+ try {
307
+ await cacheRefresher._safeCallAndRefresh();
308
+ } catch (e) {
309
+ fail('exception is not expected');
310
+ }
311
+ });
312
+
313
+ it('Catch error in soap call GetModifiedEntities and display a warning', async () => {
314
+ const client = await Mock.makeClient();
315
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
316
+
317
+ await client.NLWS.xtkSession.logon();
318
+ const cache = new Cache();
319
+ const cacheRefresher = new CacheRefresher(cache, client, "xtk:schema", "rootkey");
320
+
321
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_ERROR_RESPONSE);
322
+ try {
323
+ jest.useFakeTimers();
324
+ cacheRefresher.startAutoRefresh(5000);
325
+ jest.advanceTimersByTime(6000);
326
+ jest.useRealTimers();
327
+
328
+ // to allow soap call to finish
329
+ await new Promise(process.nextTick);
330
+ } catch (e) {
331
+ fail('exception is not expected');
332
+ }
333
+
334
+ cacheRefresher.stopAutoRefresh();
335
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
336
+ await client.NLWS.xtkSession.logoff();
337
+ });
338
+ });
@@ -54,7 +54,22 @@ describe('Caches', function() {
54
54
  cache.clear();
55
55
  expect(cache.get("Hello")).toBeUndefined();
56
56
  })
57
- })
57
+
58
+ it("Should remove key in cache", () => {
59
+ const cache = new Cache();
60
+ cache.put("Hello", "World");
61
+ cache.put("Hi", "A");
62
+ expect(cache.get("Hello")).toBe("World");
63
+ expect(cache.get("Hi")).toBe("A");
64
+ cache.remove("Hello");
65
+ expect(cache.get("Hello")).toBeUndefined();
66
+ expect(cache.get("Hi")).toBe("A");
67
+ // should support removing a key which has already been removed
68
+ cache.remove("Hello");
69
+ expect(cache.get("Hello")).toBeUndefined();
70
+ expect(cache.get("Hi")).toBe("A");
71
+ })
72
+ });
58
73
 
59
74
  describe("Entity cache", function() {
60
75
  it("Should cache value", function() {
@@ -64,10 +64,10 @@ describe('ACC Client', function () {
64
64
 
65
65
  it('Should logon and logoff with traces', async () => {
66
66
  const client = await Mock.makeClient();
67
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
68
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
67
69
  const logs = await Mock.withMockConsole(async () => {
68
70
  client.traceAPICalls(true);
69
- client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
70
- client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
71
71
  await client.NLWS.xtkSession.logon();
72
72
  expect(client.isLogged()).toBe(true);
73
73
  var sessionInfoXml = client.getSessionInfo("xml");
@@ -2242,6 +2242,8 @@ describe('ACC Client', function () {
2242
2242
  }
2243
2243
  const client = await Mock.makeClient({ storage: storage });
2244
2244
  client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2245
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_RESPONSE);
2246
+ client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_RESPONSE);
2245
2247
  client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
2246
2248
  await client.NLWS.xtkSession.logon();
2247
2249
  storage.getItem.mockReturnValueOnce(JSON.stringify({value: { value: "Hello", type: 6 }, cachedAt: 1633715996021 }));
@@ -2351,6 +2353,140 @@ describe('ACC Client', function () {
2351
2353
  expect(schema["namespace"]).toBe("nms");
2352
2354
  expect(schema["name"]).toBe("extAccount");
2353
2355
  });
2356
+
2357
+ it("Should get schema from the cache", async () => {
2358
+ const client = await Mock.makeClient();
2359
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2360
+ await client.NLWS.xtkSession.logon();
2361
+
2362
+ client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
2363
+ var schema = await client.getSchema("nms:extAccount");
2364
+ expect(schema["namespace"]).toBe("nms");
2365
+ expect(schema["name"]).toBe("extAccount");
2366
+
2367
+ client._transport.mockReturnValue(Promise.resolve(Mock.GETMODIFIEDENTITIES_RESPONSE));
2368
+
2369
+ jest.useFakeTimers();
2370
+ client.startRefreshCaches(5000); // autorefresh every 5000 ms
2371
+ jest.advanceTimersByTime(6000);
2372
+ jest.useRealTimers();
2373
+
2374
+ schema = await client.getSchema("nms:extAccount");
2375
+ expect(schema["namespace"]).toBe("nms");
2376
+ expect(schema["name"]).toBe("extAccount");
2377
+
2378
+ client.stopRefreshCaches();
2379
+ });
2380
+
2381
+ it("Should get schema from server when removed from cache", async () => {
2382
+ const client = await Mock.makeClient();
2383
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2384
+ await client.NLWS.xtkSession.logon();
2385
+
2386
+ client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
2387
+ var schema = await client.getSchema("nms:extAccount");
2388
+ expect(schema["namespace"]).toBe("nms");
2389
+ expect(schema["name"]).toBe("extAccount");
2390
+
2391
+ client._transport.mockReturnValueOnce(Promise.resolve(Mock.GETMODIFIEDENTITIES_SCHEMA_RESPONSE));
2392
+ client._transport.mockReturnValueOnce(Promise.resolve(Mock.GETMODIFIEDENTITIES_SCHEMA_RESPONSE));
2393
+
2394
+ client._transport.mockReturnValue(Promise.resolve(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE));
2395
+ jest.useFakeTimers();
2396
+ client.startRefreshCaches(5000); // autorefresh every 5000 ms
2397
+ jest.advanceTimersByTime(6000);
2398
+ jest.useRealTimers();
2399
+
2400
+ schema = await client.getSchema("nms:extAccount");
2401
+ expect(schema["namespace"]).toBe("nms");
2402
+ expect(schema["name"]).toBe("extAccount");
2403
+ client.stopRefreshCaches();
2404
+ });
2405
+
2406
+ it("Should stop refresh", async () => {
2407
+ const client = await Mock.makeClient();
2408
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2409
+ await client.NLWS.xtkSession.logon();
2410
+ jest.useFakeTimers();
2411
+ client.startRefreshCaches();
2412
+ jest.advanceTimersByTime(6000); // autorefresh for xtk:schema should be started after 5000 ms
2413
+ jest.useRealTimers();
2414
+ expect(client._optionCacheRefresher._intervalId).not.toBeNull();
2415
+ expect(client._entityCacheRefresher._intervalId).not.toBeNull();
2416
+ client.stopRefreshCaches();
2417
+ expect(client._optionCacheRefresher._intervalId).toBeNull();
2418
+ expect(client._entityCacheRefresher._intervalId).toBeNull();
2419
+ });
2420
+
2421
+ it("Should stop refresh when logoff", async () => {
2422
+ const client = await Mock.makeClient();
2423
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2424
+ await client.NLWS.xtkSession.logon();
2425
+ jest.useFakeTimers();
2426
+ client.startRefreshCaches();
2427
+ jest.advanceTimersByTime(6000); // autorefresh for xtk:schema should be started after 5000 ms
2428
+ jest.useRealTimers();
2429
+ expect(client._optionCacheRefresher._intervalId).not.toBeNull();
2430
+ expect(client._entityCacheRefresher._intervalId).not.toBeNull();
2431
+ client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
2432
+ await client.logoff();
2433
+ expect(client._optionCacheRefresher._intervalId).toBeNull();
2434
+ expect(client._entityCacheRefresher._intervalId).toBeNull();
2435
+ });
2436
+
2437
+ it("Expired session and refresh cache", async () => {
2438
+ let refreshClient = async () => {
2439
+ const connectionParameters = sdk.ConnectionParameters.ofSecurityToken("http://acc-sdk:8080",
2440
+ "$security_token$", {refreshClient: refreshClient});
2441
+ const newClient = await sdk.init(connectionParameters);
2442
+ newClient._transport = jest.fn();
2443
+ newClient._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
2444
+ await newClient.logon();
2445
+ return newClient;
2446
+ }
2447
+ const connectionParameters = sdk.ConnectionParameters.ofBearerToken("http://acc-sdk:8080",
2448
+ "$token$", {refreshClient: refreshClient});
2449
+ const client = await sdk.init(connectionParameters);
2450
+ jest.useFakeTimers();
2451
+ client.startRefreshCaches();
2452
+ client._entityCacheRefresher._safeCallAndRefresh = jest.fn();
2453
+ client._optionCacheRefresher._safeCallAndRefresh = jest.fn();
2454
+ jest.advanceTimersByTime(18000);
2455
+ expect(client._entityCacheRefresher._safeCallAndRefresh.mock.calls.length).toBe(1);
2456
+ expect(client._optionCacheRefresher._safeCallAndRefresh.mock.calls.length).toBe(1);
2457
+ client.traceAPICalls(true);
2458
+ client._transport = jest.fn();
2459
+ client._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
2460
+ client._transport.mockReturnValueOnce(Promise.resolve(`XSV-350008 Session has expired or is invalid. Please reconnect.`));
2461
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
2462
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
2463
+ <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/'>
2464
+ <SOAP-ENV:Body>
2465
+ <ExecuteQueryResponse xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
2466
+ <pdomOutput xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
2467
+ <extAccount-collection/>
2468
+ </pdomOutput></ExecuteQueryResponse>
2469
+ </SOAP-ENV:Body>
2470
+ </SOAP-ENV:Envelope>`));
2471
+ await client.logon();
2472
+ var queryDef = {
2473
+ "schema": "nms:extAccount",
2474
+ "operation": "select",
2475
+ "select": {
2476
+ "node": [
2477
+ { "expr": "@id" },
2478
+ { "expr": "@name" }
2479
+ ]
2480
+ }
2481
+ };
2482
+ var query = client.NLWS.xtkQueryDef.create(queryDef);
2483
+ var extAccount = await query.executeQuery();
2484
+ expect(extAccount).toEqual({ extAccount: [] });
2485
+ jest.advanceTimersByTime(10000);
2486
+ expect(client._entityCacheRefresher._safeCallAndRefresh.mock.calls.length).toBe(2);
2487
+ expect(client._optionCacheRefresher._safeCallAndRefresh.mock.calls.length).toBe(2);
2488
+ jest.useRealTimers();
2489
+ });
2354
2490
  });
2355
2491
 
2356
2492
  describe("Calling SOAP method with parameters as a function", () => {
@@ -2826,7 +2962,7 @@ describe('ACC Client', function () {
2826
2962
  const query = client.NLWS.pushDown({'foo': 'bar'}).xtkQueryDef.create(queryDef);
2827
2963
  await query.executeQuery();
2828
2964
  const lastCall = client._transport.mock.calls[client._transport.mock.calls.length-1];
2829
- expect(lastCall[0].url).toBe("http://acc-sdk:8080/nl/jsp/soaprouter.jsp?xtk:queryDef#ExecuteQuery");
2965
+ expect(lastCall[0].url).toBe("http://acc-sdk:8080/nl/jsp/soaprouter.jsp?xtk:queryDef:ExecuteQuery");
2830
2966
  expect(lastCall[1].charset).toBe("UTF-8");
2831
2967
  expect(lastCall[1].foo).toBe("bar");
2832
2968
  });
@@ -2851,7 +2987,7 @@ describe('ACC Client', function () {
2851
2987
  const query = client.NLWS.pushDown({'foo': 'bar'}).xtkQueryDef.create(queryDef);
2852
2988
  await query.executeQuery();
2853
2989
  const lastCall = client._transport.mock.calls[client._transport.mock.calls.length-1];
2854
- expect(lastCall[0].url).toBe("http://acc-sdk:8080/nl/jsp/soaprouter.jsp?xtk:queryDef#ExecuteQuery");
2990
+ expect(lastCall[0].url).toBe("http://acc-sdk:8080/nl/jsp/soaprouter.jsp?xtk:queryDef:ExecuteQuery");
2855
2991
  expect(lastCall[1].charset).toBe("UTF-8");
2856
2992
  expect(lastCall[1].foo).toBe("bar");
2857
2993
  expect(lastCall[1].cnxDefault).toBe(3);
@@ -2878,11 +3014,101 @@ describe('ACC Client', function () {
2878
3014
  const query = client.NLWS.pushDown({'foo': 'bar'}).pushDown().pushDown({'foo': 'fu', x: 2 }).xtkQueryDef.create(queryDef);
2879
3015
  await query.executeQuery();
2880
3016
  const lastCall = client._transport.mock.calls[client._transport.mock.calls.length-1];
2881
- expect(lastCall[0].url).toBe("http://acc-sdk:8080/nl/jsp/soaprouter.jsp?xtk:queryDef#ExecuteQuery");
3017
+ expect(lastCall[0].url).toBe("http://acc-sdk:8080/nl/jsp/soaprouter.jsp?xtk:queryDef:ExecuteQuery");
2882
3018
  expect(lastCall[1].charset).toBe("UTF-8");
2883
3019
  expect(lastCall[1].foo).toBe("fu");
2884
3020
  expect(lastCall[1].cnxDefault).toBe(3);
2885
3021
  expect(lastCall[1].x).toBe(2);
2886
3022
  });
2887
3023
  });
3024
+ describe("Schema cache refresh", () => {
3025
+ it("Should unregister listener", async () => {
3026
+ const client = await Mock.makeClient();
3027
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
3028
+ await client.NLWS.xtkSession.logon();
3029
+
3030
+ class Listener {
3031
+ constructor() {
3032
+ this._schemas = {};
3033
+ }
3034
+
3035
+ invalidateCacheItem(schemaId) {
3036
+ this._schemas[schemaId] = undefined;
3037
+ }
3038
+ }
3039
+
3040
+ client._unregisterAllCacheChangeListeners();
3041
+ expect(client._cacheChangeListeners.length).toBe(0);
3042
+ const listener = new Listener();
3043
+
3044
+ client._registerCacheChangeListener(listener);
3045
+ expect(client._cacheChangeListeners.length).toBe(1);
3046
+ client._unregisterCacheChangeListener(listener);
3047
+ expect(client._cacheChangeListeners.length).toBe(0);
3048
+ });
3049
+
3050
+ it("Should not unregister unknown listener", async () => {
3051
+ const client = await Mock.makeClient();
3052
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
3053
+ await client.NLWS.xtkSession.logon();
3054
+
3055
+ class Listener {
3056
+ constructor() {
3057
+ this._schemas = {};
3058
+ }
3059
+
3060
+ invalidateCacheItem(schemaId) {
3061
+ this._schemas[schemaId] = undefined;
3062
+ }
3063
+ }
3064
+
3065
+ client._unregisterAllCacheChangeListeners();
3066
+ expect(client._cacheChangeListeners.length).toBe(0);
3067
+ const listener = new Listener();
3068
+
3069
+ client._registerCacheChangeListener(listener);
3070
+ expect(client._cacheChangeListeners.length).toBe(1);
3071
+
3072
+ const listener2 = new Listener();
3073
+
3074
+ client._unregisterCacheChangeListener(listener2);
3075
+ expect(client._cacheChangeListeners.length).toBe(1);
3076
+ client._unregisterAllCacheChangeListeners();
3077
+ });
3078
+
3079
+ it("Should be notify when register", async () => {
3080
+ const client = await Mock.makeClient();
3081
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
3082
+ await client.NLWS.xtkSession.logon();
3083
+
3084
+ class Listener {
3085
+ constructor() {
3086
+ this._schemas = {};
3087
+ }
3088
+ add(schemaId) {
3089
+ this._schemas[schemaId] = "1";
3090
+ }
3091
+
3092
+ invalidateCacheItem(schemaId) {
3093
+ this._schemas[schemaId] = undefined;
3094
+ }
3095
+ getSchema(schemaId) {
3096
+ return this._schemas[schemaId];
3097
+ }
3098
+ }
3099
+
3100
+ client._unregisterAllCacheChangeListeners();
3101
+
3102
+ const listener = new Listener();
3103
+ listener.add("nms:recipient");
3104
+ listener.add("xtk:operator");
3105
+
3106
+ client._registerCacheChangeListener(listener);
3107
+ client._notifyCacheChangeListeners("nms:recipient");
3108
+ expect(listener.getSchema("nms:recipient")).toBeUndefined();
3109
+ expect(listener.getSchema("xtk:operator")).toBe("1");
3110
+
3111
+ client._unregisterCacheChangeListener(listener);
3112
+ });
3113
+ });
2888
3114
  });