@adobe/acc-js-sdk 1.1.19 → 1.1.21
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/docs/application.html +3 -2
- package/docs/caches.html +26 -1
- package/docs/changeLog.html +30 -2
- package/package-lock.json +4 -4
- package/package.json +1 -1
- package/src/application.js +6 -0
- package/src/cache.js +41 -30
- package/src/cacheRefresher.js +31 -31
- package/src/client.js +42 -33
- package/src/methodCache.js +9 -9
- package/src/optionCache.js +7 -7
- package/src/util.js +17 -0
- package/src/xtkEntityCache.js +5 -5
- package/test/application.test.js +19 -0
- package/test/cacheRefresher.test.js +29 -29
- package/test/caches.test.js +151 -123
- package/test/client.test.js +55 -8
- package/test/observability.test.js +2 -2
- package/test/util.test.js +58 -37
package/test/caches.test.js
CHANGED
|
@@ -27,75 +27,75 @@ const { DomUtil } = require('../src/domUtil.js');
|
|
|
27
27
|
describe('Caches', function() {
|
|
28
28
|
|
|
29
29
|
describe("Generic cache", () => {
|
|
30
|
-
it("Should cache with default TTL and default key function", () => {
|
|
30
|
+
it("Should cache with default TTL and default key function", async () => {
|
|
31
31
|
const cache = new Cache();
|
|
32
|
-
cache.put("Hello", "World");
|
|
32
|
+
await cache.put("Hello", "World");
|
|
33
33
|
expect(cache._stats).toMatchObject({ reads: 0, writes: 1 });
|
|
34
|
-
expect(cache.get("Hello")).toBe("World");
|
|
34
|
+
await expect(cache.get("Hello")).resolves.toBe("World");
|
|
35
35
|
expect(cache._stats).toMatchObject({ reads: 1, writes: 1, memoryHits: 1, storageHits: 0 });
|
|
36
36
|
})
|
|
37
37
|
|
|
38
|
-
it("Should expires after TTL", () => {
|
|
38
|
+
it("Should expires after TTL", async () => {
|
|
39
39
|
const cache = new Cache(undefined, undefined, -1); // negative TTL => will immediately expire
|
|
40
|
-
cache.put("Hello", "World");
|
|
41
|
-
expect(cache.get("Hello")).toBeUndefined();
|
|
40
|
+
await cache.put("Hello", "World");
|
|
41
|
+
await expect(cache.get("Hello")).resolves.toBeUndefined();
|
|
42
42
|
expect(cache._stats).toMatchObject({ reads: 1, writes: 1, memoryHits: 0, storageHits: 0 });
|
|
43
43
|
})
|
|
44
44
|
|
|
45
|
-
it("Should support custom key function", () => {
|
|
45
|
+
it("Should support custom key function", async () => {
|
|
46
46
|
const cache = new Cache(undefined, undefined, 300000, ((a, b) => a + "||" + b));
|
|
47
|
-
cache.put("key-part-1", "key-part-2", "value");
|
|
48
|
-
expect(cache.get("key-part-1")).toBeUndefined();
|
|
49
|
-
expect(cache.get("key-part-2")).toBeUndefined();
|
|
50
|
-
expect(cache.get("key-part-1", "key-part-2")).toBe("value");
|
|
47
|
+
await cache.put("key-part-1", "key-part-2", "value");
|
|
48
|
+
await expect(cache.get("key-part-1")).resolves.toBeUndefined();
|
|
49
|
+
await expect(cache.get("key-part-2")).resolves.toBeUndefined();
|
|
50
|
+
await expect(cache.get("key-part-1", "key-part-2")).resolves.toBe("value");
|
|
51
51
|
})
|
|
52
52
|
|
|
53
|
-
it("Should clear cache", () => {
|
|
53
|
+
it("Should clear cache", async () => {
|
|
54
54
|
const cache = new Cache();
|
|
55
|
-
cache.put("Hello", "World");
|
|
56
|
-
expect(cache.get("Hello")).toBe("World");
|
|
57
|
-
cache.clear();
|
|
58
|
-
expect(cache.get("Hello")).toBeUndefined();
|
|
55
|
+
await cache.put("Hello", "World");
|
|
56
|
+
await expect(cache.get("Hello")).resolves.toBe("World");
|
|
57
|
+
await cache.clear();
|
|
58
|
+
await expect(cache.get("Hello")).resolves.toBeUndefined();
|
|
59
59
|
expect(cache._stats).toMatchObject({ reads: 2, writes: 1, memoryHits: 1, storageHits: 0, clears: 1 });
|
|
60
60
|
})
|
|
61
61
|
|
|
62
|
-
it("Should remove key in cache", () => {
|
|
62
|
+
it("Should remove key in cache", async () => {
|
|
63
63
|
const cache = new Cache();
|
|
64
|
-
cache.put("Hello", "World");
|
|
65
|
-
cache.put("Hi", "A");
|
|
66
|
-
expect(cache.get("Hello")).toBe("World");
|
|
67
|
-
expect(cache.get("Hi")).toBe("A");
|
|
64
|
+
await cache.put("Hello", "World");
|
|
65
|
+
await cache.put("Hi", "A");
|
|
66
|
+
await expect(cache.get("Hello")).resolves.toBe("World");
|
|
67
|
+
await expect(cache.get("Hi")).resolves.toBe("A");
|
|
68
68
|
expect(cache._stats).toMatchObject({ reads: 2, writes: 2, memoryHits: 2 });
|
|
69
|
-
cache.remove("Hello");
|
|
70
|
-
expect(cache.get("Hello")).toBeUndefined();
|
|
71
|
-
expect(cache.get("Hi")).toBe("A");
|
|
69
|
+
await cache.remove("Hello");
|
|
70
|
+
await expect(cache.get("Hello")).resolves.toBeUndefined();
|
|
71
|
+
await expect(cache.get("Hi")).resolves.toBe("A");
|
|
72
72
|
expect(cache._stats).toMatchObject({ reads: 4, writes: 2, memoryHits: 3, removals: 1 });
|
|
73
73
|
// should support removing a key which has already been removed
|
|
74
|
-
cache.remove("Hello");
|
|
75
|
-
expect(cache.get("Hello")).toBeUndefined();
|
|
76
|
-
expect(cache.get("Hi")).toBe("A");
|
|
74
|
+
await cache.remove("Hello");
|
|
75
|
+
await expect(cache.get("Hello")).resolves.toBeUndefined();
|
|
76
|
+
await expect(cache.get("Hi")).resolves.toBe("A");
|
|
77
77
|
})
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
describe("Entity cache", function() {
|
|
81
|
-
it("Should cache value",
|
|
81
|
+
it("Should cache value", async () => {
|
|
82
82
|
const cache = new XtkEntityCache();
|
|
83
|
-
|
|
84
|
-
cache.put("xtk:srcSchema", "nms:recipient", "$$entity$$");
|
|
85
|
-
|
|
83
|
+
await expect(cache.get("xtk:srcSchema", "nms:recipient")).resolves.toBeUndefined();
|
|
84
|
+
await cache.put("xtk:srcSchema", "nms:recipient", "$$entity$$");
|
|
85
|
+
await expect(cache.get("xtk:srcSchema", "nms:recipient")).resolves.toBe("$$entity$$");
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
it("Should cache interfaces",
|
|
88
|
+
it("Should cache interfaces", async () => {
|
|
89
89
|
const cache = new XtkEntityCache();
|
|
90
90
|
const schema = DomUtil.parse(`<schema namespace="xtk" name="session" implements="xtk:persist">
|
|
91
91
|
<interface name="persist"/>
|
|
92
92
|
<element name="session"/>
|
|
93
93
|
</schema>`);
|
|
94
|
-
cache.put("xtk:schema", "xtk:session", schema.documentElement);
|
|
95
|
-
const session = cache.get("xtk:schema", "xtk:session");
|
|
94
|
+
await cache.put("xtk:schema", "xtk:session", schema.documentElement);
|
|
95
|
+
const session = await cache.get("xtk:schema", "xtk:session");
|
|
96
96
|
expect(session).not.toBeNull();
|
|
97
97
|
expect(session.getAttribute("name")).toBe("session");
|
|
98
|
-
const persist = cache.get("xtk:schema", "xtk:persist");
|
|
98
|
+
const persist = await cache.get("xtk:schema", "xtk:persist");
|
|
99
99
|
expect(persist).not.toBeNull();
|
|
100
100
|
expect(persist.getAttribute("name")).toBe("persist");
|
|
101
101
|
});
|
|
@@ -104,124 +104,124 @@ describe('Caches', function() {
|
|
|
104
104
|
|
|
105
105
|
describe("Option cache", function() {
|
|
106
106
|
|
|
107
|
-
it("Should cache value",
|
|
107
|
+
it("Should cache value", async () => {
|
|
108
108
|
const cache = new OptionCache();
|
|
109
|
-
expect(cache.get("hello")).toBeUndefined();
|
|
110
|
-
cache.put("hello", ["world", 6]);
|
|
111
|
-
expect(cache.get("hello")).toBe("world");
|
|
112
|
-
expect(cache.getOption("hello")).toEqual({"rawValue": "world", "type": 6, "value": "world"});
|
|
109
|
+
await expect(cache.get("hello")).resolves.toBeUndefined();
|
|
110
|
+
await cache.put("hello", ["world", 6]);
|
|
111
|
+
await expect(cache.get("hello")).resolves.toBe("world");
|
|
112
|
+
await expect(cache.getOption("hello")).resolves.toEqual({"rawValue": "world", "type": 6, "value": "world"});
|
|
113
113
|
});
|
|
114
114
|
|
|
115
|
-
it("Should cache multiple value",
|
|
115
|
+
it("Should cache multiple value", async () => {
|
|
116
116
|
const cache = new OptionCache();
|
|
117
|
-
cache.put("hello", ["world", 6]);
|
|
118
|
-
cache.put("foo", ["bar", 6]);
|
|
119
|
-
expect(cache.get("hello")).toBe("world");
|
|
120
|
-
expect(cache.getOption("hello")).toEqual({"rawValue": "world", "type": 6, "value": "world"});
|
|
121
|
-
expect(cache.get("foo")).toBe("bar");
|
|
122
|
-
expect(cache.getOption("foo")).toEqual({"rawValue": "bar", "type": 6, "value": "bar"});
|
|
117
|
+
await cache.put("hello", ["world", 6]);
|
|
118
|
+
await cache.put("foo", ["bar", 6]);
|
|
119
|
+
await expect(cache.get("hello")).resolves.toBe("world");
|
|
120
|
+
await expect(cache.getOption("hello")).resolves.toEqual({"rawValue": "world", "type": 6, "value": "world"});
|
|
121
|
+
await expect(cache.get("foo")).resolves.toBe("bar");
|
|
122
|
+
await expect(cache.getOption("foo")).resolves.toEqual({"rawValue": "bar", "type": 6, "value": "bar"});
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
it("Should overwrite cached value",
|
|
125
|
+
it("Should overwrite cached value", async () => {
|
|
126
126
|
const cache = new OptionCache();
|
|
127
|
-
cache.put("hello", ["world", 6]);
|
|
128
|
-
expect(cache.get("hello")).toBe( "world");
|
|
129
|
-
expect(cache.getOption("hello")).toEqual({"rawValue": "world", "type": 6, "value": "world"});
|
|
130
|
-
cache.put("hello", ["cruel world", 6]);
|
|
131
|
-
expect(cache.get("hello")).toBe("cruel world");
|
|
132
|
-
expect(cache.getOption("hello")).toEqual({"rawValue": "cruel world", "type": 6, "value": "cruel world"});
|
|
127
|
+
await cache.put("hello", ["world", 6]);
|
|
128
|
+
await expect(cache.get("hello")).resolves.toBe( "world");
|
|
129
|
+
await expect(cache.getOption("hello")).resolves.toEqual({"rawValue": "world", "type": 6, "value": "world"});
|
|
130
|
+
await cache.put("hello", ["cruel world", 6]);
|
|
131
|
+
await expect(cache.get("hello")).resolves.toBe("cruel world");
|
|
132
|
+
await expect(cache.getOption("hello")).resolves.toEqual({"rawValue": "cruel world", "type": 6, "value": "cruel world"});
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
-
it("Should clear cache",
|
|
135
|
+
it("Should clear cache", async () => {
|
|
136
136
|
const cache = new OptionCache();
|
|
137
|
-
cache.put("hello", ["world", 6]);
|
|
138
|
-
expect(cache.get("hello")).toBe("world");
|
|
139
|
-
expect(cache.getOption("hello")).toEqual({"rawValue": "world", "type": 6, "value": "world"});
|
|
140
|
-
cache.clear();
|
|
141
|
-
expect(cache.get("hello")).toBeUndefined();
|
|
142
|
-
expect(cache.getOption("hello")).toBeUndefined();
|
|
137
|
+
await cache.put("hello", ["world", 6]);
|
|
138
|
+
await expect(cache.get("hello")).resolves.toBe("world");
|
|
139
|
+
await expect(cache.getOption("hello")).resolves.toEqual({"rawValue": "world", "type": 6, "value": "world"});
|
|
140
|
+
await cache.clear();
|
|
141
|
+
await expect(cache.get("hello")).resolves.toBeUndefined();
|
|
142
|
+
await expect(cache.getOption("hello")).resolves.toBeUndefined();
|
|
143
143
|
});
|
|
144
144
|
|
|
145
|
-
it("Should not find",
|
|
145
|
+
it("Should not find", async () => {
|
|
146
146
|
const cache = new OptionCache();
|
|
147
|
-
expect(cache.get("hello")).toBeUndefined();
|
|
148
|
-
expect(cache.getOption("hello")).toBeUndefined();
|
|
147
|
+
await expect(cache.get("hello")).resolves.toBeUndefined();
|
|
148
|
+
await expect(cache.getOption("hello")).resolves.toBeUndefined();
|
|
149
149
|
});
|
|
150
150
|
|
|
151
|
-
it("Deprecated cache methods should now replaced with put", () => {
|
|
151
|
+
it("Deprecated cache methods should now replaced with put", async () => {
|
|
152
152
|
const cache = new OptionCache();
|
|
153
|
-
cache.cache("hello", ["world", 6]);
|
|
154
|
-
expect(cache.get("hello")).toBe("world");
|
|
155
|
-
expect(cache.getOption("hello")).toEqual({"rawValue": "world", "type": 6, "value": "world"});
|
|
153
|
+
await cache.cache("hello", ["world", 6]);
|
|
154
|
+
await expect(cache.get("hello")).resolves.toBe("world");
|
|
155
|
+
await expect(cache.getOption("hello")).resolves.toEqual({"rawValue": "world", "type": 6, "value": "world"});
|
|
156
156
|
});
|
|
157
157
|
});
|
|
158
158
|
|
|
159
159
|
describe("Method cache", function() {
|
|
160
|
-
it("Should cache methods",
|
|
160
|
+
it("Should cache methods", async () => {
|
|
161
161
|
const cache = new MethodCache();
|
|
162
162
|
var schema = DomUtil.parse("<schema namespace='nms' name='recipient'><methods><method name='Delete'/><method name='Create'/></methods></schema>");
|
|
163
|
-
cache.put(schema.documentElement);
|
|
163
|
+
await cache.put(schema.documentElement);
|
|
164
164
|
|
|
165
|
-
var found = cache.get("nms:recipient", "Delete");
|
|
165
|
+
var found = await cache.get("nms:recipient", "Delete");
|
|
166
166
|
assert.ok(found !== null && found !== undefined);
|
|
167
167
|
assert.equal(found.nodeName, "method");
|
|
168
168
|
assert.equal(found.getAttribute("name"), "Delete");
|
|
169
169
|
|
|
170
|
-
found = cache.get("nms:recipient", "Create");
|
|
170
|
+
found = await cache.get("nms:recipient", "Create");
|
|
171
171
|
assert.ok(found !== null && found !== undefined);
|
|
172
172
|
assert.equal(found.nodeName, "method");
|
|
173
173
|
assert.equal(found.getAttribute("name"), "Create");
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
-
it("Should cache interface methods",
|
|
176
|
+
it("Should cache interface methods", async () => {
|
|
177
177
|
const cache = new MethodCache();
|
|
178
178
|
var schema = DomUtil.parse("<schema namespace='nms' name='recipient' implements='nms:i'><interface name='i'><method name='Update'/></interface><element name='recipient'/><methods><method name='Delete'/><method name='Create'/></methods></schema>");
|
|
179
|
-
cache.put(schema.documentElement);
|
|
179
|
+
await cache.put(schema.documentElement);
|
|
180
180
|
// interface method should be on schema
|
|
181
|
-
var found = cache.get("nms:recipient", "Update");
|
|
181
|
+
var found = await cache.get("nms:recipient", "Update");
|
|
182
182
|
assert.ok(found !== null && found !== undefined);
|
|
183
183
|
// and on interface as well
|
|
184
|
-
found = cache.get("nms:i", "Update");
|
|
184
|
+
found = await cache.get("nms:i", "Update");
|
|
185
185
|
assert.ok(found !== null && found !== undefined);
|
|
186
186
|
});
|
|
187
187
|
|
|
188
|
-
it("Should clear the cache",
|
|
188
|
+
it("Should clear the cache", async () => {
|
|
189
189
|
const cache = new MethodCache();
|
|
190
190
|
var schema = DomUtil.parse("<schema namespace='nms' name='recipient'><methods><method name='Delete'/><method name='Create'/></methods></schema>");
|
|
191
|
-
cache.put(schema.documentElement);
|
|
191
|
+
await cache.put(schema.documentElement);
|
|
192
192
|
|
|
193
|
-
var found = cache.get("nms:recipient", "Delete");
|
|
193
|
+
var found = await cache.get("nms:recipient", "Delete");
|
|
194
194
|
assert.ok(found !== null && found !== undefined);
|
|
195
195
|
|
|
196
|
-
cache.clear();
|
|
197
|
-
found = cache.get("nms:recipient", "Delete");
|
|
196
|
+
await cache.clear();
|
|
197
|
+
found = await cache.get("nms:recipient", "Delete");
|
|
198
198
|
assert.ok(found === undefined);
|
|
199
199
|
});
|
|
200
200
|
|
|
201
|
-
it("Should ignore non-method nodes",
|
|
201
|
+
it("Should ignore non-method nodes", async () => {
|
|
202
202
|
const cache = new MethodCache();
|
|
203
203
|
var schema = DomUtil.parse("<schema namespace='nms' name='recipient'><methods><method name='Delete'/><dummy name='Update'/><method name='Create'/></methods></schema>");
|
|
204
|
-
cache.put(schema.documentElement);
|
|
204
|
+
await cache.put(schema.documentElement);
|
|
205
205
|
|
|
206
|
-
var found = cache.get("nms:recipient", "Delete");
|
|
206
|
+
var found = await cache.get("nms:recipient", "Delete");
|
|
207
207
|
assert.ok(found !== null && found !== undefined);
|
|
208
|
-
found = cache.get("nms:recipient", "Update");
|
|
208
|
+
found = await cache.get("nms:recipient", "Update");
|
|
209
209
|
assert.ok(found === undefined);
|
|
210
|
-
found = cache.get("nms:recipient", "Create");
|
|
210
|
+
found = await cache.get("nms:recipient", "Create");
|
|
211
211
|
assert.ok(found !== null && found !== undefined);
|
|
212
212
|
});
|
|
213
213
|
|
|
214
|
-
it("Deprecated cache methods should now replaced with put", () => {
|
|
214
|
+
it("Deprecated cache methods should now replaced with put", async () => {
|
|
215
215
|
const cache = new MethodCache();
|
|
216
216
|
var schema = DomUtil.parse("<schema namespace='nms' name='recipient'><methods><method name='Delete'/><method name='Create'/></methods></schema>");
|
|
217
|
-
cache.cache(schema.documentElement);
|
|
217
|
+
await cache.cache(schema.documentElement);
|
|
218
218
|
|
|
219
|
-
var found = cache.get("nms:recipient", "Delete");
|
|
219
|
+
var found = await cache.get("nms:recipient", "Delete");
|
|
220
220
|
assert.ok(found !== null && found !== undefined);
|
|
221
221
|
assert.equal(found.nodeName, "method");
|
|
222
222
|
assert.equal(found.getAttribute("name"), "Delete");
|
|
223
223
|
|
|
224
|
-
found = cache.get("nms:recipient", "Create");
|
|
224
|
+
found = await cache.get("nms:recipient", "Create");
|
|
225
225
|
assert.ok(found !== null && found !== undefined);
|
|
226
226
|
assert.equal(found.nodeName, "method");
|
|
227
227
|
assert.equal(found.getAttribute("name"), "Create");
|
|
@@ -240,71 +240,71 @@ describe('Caches', function() {
|
|
|
240
240
|
});
|
|
241
241
|
|
|
242
242
|
describe("Method cache for interfaces", function() {
|
|
243
|
-
it("Should cache methods",
|
|
243
|
+
it("Should cache methods", async () => {
|
|
244
244
|
const cache = new MethodCache();
|
|
245
245
|
// Test for fix in verion 0.1.23. The xtk:session schema has a direct method "Logon" but also implements the
|
|
246
246
|
// xtk:persist interface.
|
|
247
247
|
var schema = DomUtil.parse("<schema namespace='xtk' name='session' implements='xtk:persist'><interface name='persist'><method name='Write' static='true'/></interface><methods><method name='Logon'/></methods></schema>");
|
|
248
|
-
cache.put(schema.documentElement);
|
|
248
|
+
await cache.put(schema.documentElement);
|
|
249
249
|
|
|
250
250
|
// Logon method should be found in xtk:session and have the xtk:session URN (for SOAP action)
|
|
251
|
-
var found = cache.get("xtk:session", "Logon");
|
|
252
|
-
var urn = cache.getSoapUrn("xtk:session", "Logon");
|
|
251
|
+
var found = await cache.get("xtk:session", "Logon");
|
|
252
|
+
var urn = await cache.getSoapUrn("xtk:session", "Logon");
|
|
253
253
|
assert.ok(found !== null && found !== undefined);
|
|
254
254
|
assert.strictEqual(found.nodeName, "method");
|
|
255
255
|
assert.strictEqual(found.getAttribute("name"), "Logon");
|
|
256
256
|
assert.strictEqual(urn, "xtk:session");
|
|
257
257
|
|
|
258
258
|
// Logon method should not exist on the xtk:persist interface
|
|
259
|
-
found = cache.get("xtk:persist", "Logon");
|
|
260
|
-
urn = cache.getSoapUrn("xtk:persist", "Logon");
|
|
259
|
+
found = await cache.get("xtk:persist", "Logon");
|
|
260
|
+
urn = await cache.getSoapUrn("xtk:persist", "Logon");
|
|
261
261
|
assert.ok(found === undefined);
|
|
262
262
|
assert.ok(urn === undefined);
|
|
263
263
|
|
|
264
264
|
// The Write method should also be on xtk:session but use xtk:persist as a URN
|
|
265
|
-
found = cache.get("xtk:session", "Write");
|
|
266
|
-
urn = cache.getSoapUrn("xtk:session", "Write");
|
|
265
|
+
found = await cache.get("xtk:session", "Write");
|
|
266
|
+
urn = await cache.getSoapUrn("xtk:session", "Write");
|
|
267
267
|
assert.ok(found !== null && found !== undefined);
|
|
268
268
|
assert.strictEqual(found.nodeName, "method");
|
|
269
269
|
assert.strictEqual(found.getAttribute("name"), "Write");
|
|
270
270
|
assert.strictEqual(urn, "xtk:persist|xtk:session");
|
|
271
271
|
|
|
272
272
|
// For compatibility reasons (SDK versions earlier than 0.1.23), keep the Write method on the interface too
|
|
273
|
-
found = cache.get("xtk:persist", "Write");
|
|
274
|
-
urn = cache.getSoapUrn("xtk:persist", "Write");
|
|
273
|
+
found = await cache.get("xtk:persist", "Write");
|
|
274
|
+
urn = await cache.getSoapUrn("xtk:persist", "Write");
|
|
275
275
|
assert.ok(found !== null && found !== undefined);
|
|
276
276
|
assert.strictEqual(found.nodeName, "method");
|
|
277
277
|
assert.strictEqual(found.getAttribute("name"), "Write");
|
|
278
278
|
assert.strictEqual(urn, "xtk:persist");
|
|
279
279
|
});
|
|
280
280
|
|
|
281
|
-
it("Edge cases for getSoapUrn", () => {
|
|
281
|
+
it("Edge cases for getSoapUrn", async () => {
|
|
282
282
|
const cache = new MethodCache();
|
|
283
283
|
var schema = DomUtil.parse("<schema namespace='xtk' name='session' implements='xtk:persist'><interface name='persist'><method name='Write' static='true'/></interface><methods><method name='Logon'/></methods></schema>");
|
|
284
|
-
cache.put(schema.documentElement);
|
|
284
|
+
await cache.put(schema.documentElement);
|
|
285
285
|
|
|
286
286
|
// Schema and method exist
|
|
287
|
-
var urn = cache.getSoapUrn("xtk:session", "Logon");
|
|
287
|
+
var urn = await cache.getSoapUrn("xtk:session", "Logon");
|
|
288
288
|
expect(urn).toBe("xtk:session");
|
|
289
289
|
|
|
290
290
|
// Schema exists but method doesn't
|
|
291
|
-
urn = cache.getSoapUrn("xtk:session", "Dummy");
|
|
291
|
+
urn = await cache.getSoapUrn("xtk:session", "Dummy");
|
|
292
292
|
expect(urn).toBeUndefined();
|
|
293
293
|
|
|
294
294
|
// Neither schema nor method exist
|
|
295
|
-
urn = cache.getSoapUrn("xtk:dummy", "Dummy");
|
|
295
|
+
urn = await cache.getSoapUrn("xtk:dummy", "Dummy");
|
|
296
296
|
expect(urn).toBeUndefined();
|
|
297
297
|
});
|
|
298
298
|
|
|
299
|
-
it("Schema has interfaces that do not match what schema implements", () => {
|
|
299
|
+
it("Schema has interfaces that do not match what schema implements", async () => {
|
|
300
300
|
const cache = new MethodCache();
|
|
301
301
|
// Schema has xtk:persist interface but does not implement it
|
|
302
302
|
var schema = DomUtil.parse("<schema namespace='xtk' name='session'><interface name='persist'><method name='Write' static='true'/></interface><methods><method name='Logon'/></methods></schema>");
|
|
303
|
-
cache.put(schema.documentElement);
|
|
303
|
+
await cache.put(schema.documentElement);
|
|
304
304
|
|
|
305
305
|
// Logon method should be found in xtk:session and have the xtk:session URN (for SOAP action)
|
|
306
|
-
var found = cache.get("xtk:session", "Logon");
|
|
307
|
-
var urn = cache.getSoapUrn("xtk:session", "Logon");
|
|
306
|
+
var found = await cache.get("xtk:session", "Logon");
|
|
307
|
+
var urn = await cache.getSoapUrn("xtk:session", "Logon");
|
|
308
308
|
assert.ok(found !== null && found !== undefined);
|
|
309
309
|
assert.strictEqual(found.nodeName, "method");
|
|
310
310
|
assert.strictEqual(found.getAttribute("name"), "Logon");
|
|
@@ -316,18 +316,18 @@ describe('Caches', function() {
|
|
|
316
316
|
|
|
317
317
|
describe("JSON safe storage", () => {
|
|
318
318
|
|
|
319
|
-
it("Should find mock json from the cache", () => {
|
|
319
|
+
it("Should find mock json from the cache", async () => {
|
|
320
320
|
const map = {};
|
|
321
321
|
const delegate = {
|
|
322
322
|
getItem: jest.fn((key) => map[key]),
|
|
323
323
|
setItem: jest.fn((key, value) => map[key] = value)
|
|
324
324
|
}
|
|
325
325
|
const storage = new SafeStorage(delegate, "");
|
|
326
|
-
expect(storage.getItem("not_found")).toBeUndefined();
|
|
326
|
+
await expect(storage.getItem("not_found")).resolves.toBeUndefined();
|
|
327
327
|
map["k1"] = `{ "hello": "world" }`;
|
|
328
|
-
expect(storage.getItem("k1")).toMatchObject({ hello: "world" });
|
|
328
|
+
await expect(storage.getItem("k1")).resolves.toMatchObject({ hello: "world" });
|
|
329
329
|
map["k2"] = `{ "value": { "hello": "world" } }`;
|
|
330
|
-
expect(storage.getItem("k2")).toMatchObject({ value: { hello: "world" } });
|
|
330
|
+
await expect(storage.getItem("k2")).resolves.toMatchObject({ value: { hello: "world" } });
|
|
331
331
|
});
|
|
332
332
|
});
|
|
333
333
|
|
|
@@ -346,32 +346,32 @@ describe('Caches', function() {
|
|
|
346
346
|
}
|
|
347
347
|
};
|
|
348
348
|
|
|
349
|
-
it("Should find mock xml from the cache", () => {
|
|
349
|
+
it("Should find mock xml from the cache", async () => {
|
|
350
350
|
const map = {};
|
|
351
351
|
const delegate = {
|
|
352
352
|
getItem: jest.fn((key) => map[key]),
|
|
353
353
|
setItem: jest.fn((key, value) => map[key] = value)
|
|
354
354
|
}
|
|
355
355
|
const storage = new SafeStorage(delegate, "", xmlSerDeser);
|
|
356
|
-
expect(storage.getItem("not_found")).toBeUndefined();
|
|
356
|
+
await expect(storage.getItem("not_found")).resolves.toBeUndefined();
|
|
357
357
|
map["k1"] = `{ "hello": "world" }`;
|
|
358
|
-
expect(storage.getItem("k1")).toBeUndefined(); // k1 cached object does not have "value" attribute containing serialized XML
|
|
358
|
+
await expect(storage.getItem("k1")).resolves.toBeUndefined(); // k1 cached object does not have "value" attribute containing serialized XML
|
|
359
359
|
map["k1"] = `{ "hello": "world", "value": "" }`;
|
|
360
|
-
expect(storage.getItem("k1")).toBeUndefined(); // k1 cached object does not have "value" attribute containing serialized XML
|
|
360
|
+
await expect(storage.getItem("k1")).resolves.toBeUndefined(); // k1 cached object does not have "value" attribute containing serialized XML
|
|
361
361
|
map["k1"] = `{ "value": { "hello": "world" } }`;
|
|
362
|
-
expect(storage.getItem("k2")).toBeUndefined(); // k1 cached object does not have "value" attribute but it's not valid XML
|
|
362
|
+
await expect(storage.getItem("k2")).resolves.toBeUndefined(); // k1 cached object does not have "value" attribute but it's not valid XML
|
|
363
363
|
map["k1"] = `{ "value": "" } }`;
|
|
364
|
-
expect(storage.getItem("k1")).toBeUndefined(); // k1 cached object does not have "value" attribute but it's not valid XML
|
|
364
|
+
await expect(storage.getItem("k1")).resolves.toBeUndefined(); // k1 cached object does not have "value" attribute but it's not valid XML
|
|
365
365
|
map["k1"] = `{ "value": "bad" } }`;
|
|
366
|
-
expect(storage.getItem("k1")).toBeUndefined(); // k1 cached object does not have "value" attribute but it's not valid XML
|
|
366
|
+
await expect(storage.getItem("k1")).resolves.toBeUndefined(); // k1 cached object does not have "value" attribute but it's not valid XML
|
|
367
367
|
map["k2"] = `{ "value": "<hello/>" }`;
|
|
368
|
-
expect(storage.getItem("k2").value
|
|
368
|
+
await expect(storage.getItem("k2")).resolves.toMatchObject({ value: {tagName: "hello"}});
|
|
369
369
|
});
|
|
370
370
|
});
|
|
371
371
|
});
|
|
372
372
|
|
|
373
373
|
describe("Cache seralizers", () => {
|
|
374
|
-
it("Should serialize json", () => {
|
|
374
|
+
it("Should serialize json", async () => {
|
|
375
375
|
const cache = new OptionCache();
|
|
376
376
|
const serDeser = cache._storage._serDeser;
|
|
377
377
|
expect(serDeser({ hello: "World" }, true)).toBe('{"hello":"World"}');
|
|
@@ -446,5 +446,33 @@ describe('Caches', function() {
|
|
|
446
446
|
expect(cached.value.x).toBe(3);
|
|
447
447
|
expect(cached.value.method.documentElement.tagName).toBe("hello");
|
|
448
448
|
})
|
|
449
|
-
})
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
describe("Sync and Async delegates", () => {
|
|
452
|
+
it("Should support synchronous delegates", async () => {
|
|
453
|
+
const map = {};
|
|
454
|
+
const delegate = {
|
|
455
|
+
getItem: jest.fn((key) => map[key]),
|
|
456
|
+
setItem: jest.fn((key, value) => map[key] = value)
|
|
457
|
+
}
|
|
458
|
+
const storage = new SafeStorage(delegate, "");
|
|
459
|
+
await storage.setItem("Hello", { cruel: "World" });
|
|
460
|
+
await expect(storage.getItem("Hello")).resolves.toMatchObject({ cruel: "World" });
|
|
461
|
+
});
|
|
462
|
+
it("Should support asynchronous delegates", async () => {
|
|
463
|
+
const map = {};
|
|
464
|
+
const delegate = {
|
|
465
|
+
getItem: jest.fn(async (key) => Promise.resolve(map[key]) ),
|
|
466
|
+
setItem: jest.fn(async (key, value) => {
|
|
467
|
+
return new Promise((resolve, reject) => {
|
|
468
|
+
map[key] = value;
|
|
469
|
+
resolve(value);
|
|
470
|
+
});
|
|
471
|
+
})
|
|
472
|
+
}
|
|
473
|
+
const storage = new SafeStorage(delegate, "");
|
|
474
|
+
await storage.setItem("Hello", { cruel: "World" });
|
|
475
|
+
await expect(storage.getItem("Hello")).resolves.toMatchObject({ cruel: "World" });
|
|
476
|
+
});
|
|
477
|
+
});
|
|
450
478
|
});
|
package/test/client.test.js
CHANGED
|
@@ -247,7 +247,7 @@ describe('ACC Client', function () {
|
|
|
247
247
|
databaseId = await client.getOption("XtkDatabaseId", false);
|
|
248
248
|
expect(databaseId).toBe("uFE80000000000000F1FA913DD7CC7C480041161C");
|
|
249
249
|
// Clear cache
|
|
250
|
-
client.clearOptionCache();
|
|
250
|
+
await client.clearOptionCache();
|
|
251
251
|
client._transport.mockReturnValueOnce(Mock.GET_DATABASEID_RESPONSE);
|
|
252
252
|
databaseId = await client.getOption("XtkDatabaseId");
|
|
253
253
|
expect(databaseId).toBe("uFE80000000000000F1FA913DD7CC7C480041161C");
|
|
@@ -401,7 +401,7 @@ describe('ACC Client', function () {
|
|
|
401
401
|
expect(schema["name"]).toBe("extAccount");
|
|
402
402
|
|
|
403
403
|
// Clear cache and ask again
|
|
404
|
-
client.clearEntityCache();
|
|
404
|
+
await client.clearEntityCache();
|
|
405
405
|
client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
|
|
406
406
|
schema = await client.getSchema("nms:extAccount");
|
|
407
407
|
expect(schema["namespace"]).toBe("nms");
|
|
@@ -421,11 +421,11 @@ describe('ACC Client', function () {
|
|
|
421
421
|
await expect(client.getSchema("nms:extAccount", "invalid")).rejects.toMatchObject({ errorCode: 'SDK-000004' });
|
|
422
422
|
|
|
423
423
|
// Get missing schema
|
|
424
|
-
client.clearAllCaches();
|
|
424
|
+
await client.clearAllCaches();
|
|
425
425
|
client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
|
|
426
426
|
schema = await client.getSchema("nms:dummy", "BadgerFish");
|
|
427
427
|
expect(schema).toBeNull();
|
|
428
|
-
client.clearAllCaches();
|
|
428
|
+
await client.clearAllCaches();
|
|
429
429
|
client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
|
|
430
430
|
schema = await client.getSchema("nms:dummy", "xml");
|
|
431
431
|
expect(schema).toBeNull();
|
|
@@ -477,13 +477,13 @@ describe('ACC Client', function () {
|
|
|
477
477
|
client._representation = "xml";
|
|
478
478
|
|
|
479
479
|
// Get non-cached XML representation
|
|
480
|
-
client.clearAllCaches();
|
|
480
|
+
await client.clearAllCaches();
|
|
481
481
|
client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
|
|
482
482
|
sysEnum = await client.getSysEnum("nms:extAccount:encryptionType");
|
|
483
483
|
expect(sysEnum.getAttribute("basetype")).toBe("byte");
|
|
484
484
|
|
|
485
485
|
// Schema does not exist
|
|
486
|
-
client.clearAllCaches();
|
|
486
|
+
await client.clearAllCaches();
|
|
487
487
|
client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
|
|
488
488
|
await expect(client.getSysEnum("nms:dummy:encryptionType")).rejects.toMatchObject({ errorCode: "SDK-000006" });
|
|
489
489
|
|
|
@@ -701,7 +701,7 @@ describe('ACC Client', function () {
|
|
|
701
701
|
expect(cipher.iv).not.toBeNull();
|
|
702
702
|
|
|
703
703
|
// Ask again, should be cached (no mock methods)
|
|
704
|
-
client.clearAllCaches();
|
|
704
|
+
await client.clearAllCaches();
|
|
705
705
|
cipher = await client._getSecretKeyCipher();
|
|
706
706
|
expect(cipher).not.toBeNull();
|
|
707
707
|
expect(cipher.key).not.toBeNull();
|
|
@@ -2283,6 +2283,7 @@ describe('ACC Client', function () {
|
|
|
2283
2283
|
client._transport.mockReturnValueOnce(Mock.GETMODIFIEDENTITIES_RESPONSE);
|
|
2284
2284
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
2285
2285
|
await client.NLWS.xtkSession.logon();
|
|
2286
|
+
storage.getItem.mockReturnValueOnce(undefined); // lastCleared
|
|
2286
2287
|
storage.getItem.mockReturnValueOnce(JSON.stringify({value: { value: "Hello", type: 6 }, cachedAt: 1633715996021 }));
|
|
2287
2288
|
const value = await client.getOption("XtkDatabaseId");
|
|
2288
2289
|
expect(value).toBe("Hello");
|
|
@@ -2297,6 +2298,7 @@ describe('ACC Client', function () {
|
|
|
2297
2298
|
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
2298
2299
|
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
2299
2300
|
await client.NLWS.xtkSession.logon();
|
|
2301
|
+
storage.getItem.mockReturnValueOnce(undefined); // lastCleared
|
|
2300
2302
|
storage.getItem.mockReturnValueOnce(JSON.stringify({value: { value: "Hello", type: 6 }, cachedAt: 1633715996021 }));
|
|
2301
2303
|
client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
|
|
2302
2304
|
<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/'>
|
|
@@ -2443,12 +2445,57 @@ describe('ACC Client', function () {
|
|
|
2443
2445
|
expect(NLWS).toBeTruthy();
|
|
2444
2446
|
expect(client.isLogged()).toBe(false);
|
|
2445
2447
|
})
|
|
2448
|
+
|
|
2449
|
+
it("Should support storage key type without version information", async () => {
|
|
2450
|
+
// Default has version & instance name
|
|
2451
|
+
const version = sdk.getSDKVersion().version; // "${version}" or similar
|
|
2452
|
+
connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("http://acc-sdk:8080", "admin", "admin");
|
|
2453
|
+
var client = await sdk.init(connectionParameters);
|
|
2454
|
+
expect(client._optionCache._storage._rootKey).toBe(`acc.js.sdk.${version}.acc-sdk:8080.cache.OptionCache$`);
|
|
2455
|
+
|
|
2456
|
+
// Default has version & instance name
|
|
2457
|
+
connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("http://acc-sdk:8080", "admin", "admin", { cacheRootKey: "default" });
|
|
2458
|
+
var client = await sdk.init(connectionParameters);
|
|
2459
|
+
expect(client._optionCache._storage._rootKey).toBe(`acc.js.sdk.${version}.acc-sdk:8080.cache.OptionCache$`);
|
|
2460
|
+
|
|
2461
|
+
// No prefix
|
|
2462
|
+
connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("http://acc-sdk:8080", "admin", "admin", { cacheRootKey: "none" });
|
|
2463
|
+
var client = await sdk.init(connectionParameters);
|
|
2464
|
+
expect(client._optionCache._storage._rootKey).toBe(`OptionCache$`);
|
|
2465
|
+
});
|
|
2466
|
+
|
|
2467
|
+
describe("Should simulate the Shell Cache API", () => {
|
|
2468
|
+
// See https://github.com/AdobeDocs/exc-app/blob/master/docs/modules/cache.md#sample-code
|
|
2469
|
+
it("Sould get cached option", async () => {
|
|
2470
|
+
const storage = {
|
|
2471
|
+
getItem: jest.fn(),
|
|
2472
|
+
setItem: jest.fn(),
|
|
2473
|
+
}
|
|
2474
|
+
const client = await Mock.makeClient({ storage: storage, cacheRootKey: "instance" });
|
|
2475
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
2476
|
+
await client.NLWS.xtkSession.logon();
|
|
2477
|
+
storage.getItem.mockReturnValueOnce(Promise.resolve(undefined)); // lastCleared
|
|
2478
|
+
storage.getItem.mockReturnValueOnce(Promise.resolve(JSON.stringify({value: { value: "Hello", type: 6 }, cachedAt: 1633715996021 })));
|
|
2479
|
+
const value = await client.getOption("Test");
|
|
2480
|
+
expect(value).toBe("Hello");
|
|
2481
|
+
expect(storage.setItem.mock.calls.length).toBe(0);
|
|
2482
|
+
|
|
2483
|
+
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
2484
|
+
client._transport.mockReturnValueOnce(Mock.GET_DATABASEID_RESPONSE);
|
|
2485
|
+
var databaseId = await client.getOption("XtkDatabaseId");
|
|
2486
|
+
expect(databaseId).toBe("uFE80000000000000F1FA913DD7CC7C480041161C");
|
|
2487
|
+
const lastCall = storage.setItem.mock.calls[storage.setItem.mock.calls.length-1];
|
|
2488
|
+
expect(lastCall[0]).toMatch("OptionCache$XtkDatabaseId");
|
|
2489
|
+
expect(lastCall[0]).not.toMatch("acc.js.sdk");
|
|
2490
|
+
expect(lastCall[1]).toMatch("uFE80000000000000F1FA913DD7CC7C480041161C");
|
|
2491
|
+
});
|
|
2492
|
+
});
|
|
2446
2493
|
})
|
|
2447
2494
|
|
|
2448
2495
|
describe("Get Schema, cache and representations", () => {
|
|
2449
2496
|
it("Should get schema with no cache", async () => {
|
|
2450
2497
|
const client = await Mock.makeClient();
|
|
2451
|
-
client.clearAllCaches();
|
|
2498
|
+
await client.clearAllCaches();
|
|
2452
2499
|
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
2453
2500
|
await client.NLWS.xtkSession.logon();
|
|
2454
2501
|
|
|
@@ -336,7 +336,7 @@ describe('ACC Client Observability', function () {
|
|
|
336
336
|
</SOAP-ENV:Envelope>`);
|
|
337
337
|
};
|
|
338
338
|
client._transport.mockImplementationOnce(getOption);
|
|
339
|
-
client.clearOptionCache();
|
|
339
|
+
await client.clearOptionCache();
|
|
340
340
|
var value = await client.getOption("Dummy");
|
|
341
341
|
expect(value).toBe("DummyZZ");
|
|
342
342
|
|
|
@@ -345,7 +345,7 @@ describe('ACC Client Observability', function () {
|
|
|
345
345
|
if (inputParameters[0].value === "Dummy") inputParameters[0].value = "XtkDatabaseId";
|
|
346
346
|
});
|
|
347
347
|
client._transport.mockImplementationOnce(getOption);
|
|
348
|
-
client.clearOptionCache();
|
|
348
|
+
await client.clearOptionCache();
|
|
349
349
|
var value = await client.getOption("Dummy");
|
|
350
350
|
expect(value).toBe("XtkDatabaseIdZZ");
|
|
351
351
|
|