@egen-civitas/esm-platform 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +64 -2
- package/dist/adapters/web/index.d.ts +7 -5
- package/dist/adapters/web/index.js +7 -22
- package/dist/bridge/client.d.ts +48 -0
- package/dist/bridge/client.js +212 -0
- package/dist/bridge/client.test.js +1264 -0
- package/dist/bridge/index.d.ts +4 -0
- package/dist/bridge/index.js +2 -0
- package/dist/bridge/protocol.d.ts +72 -0
- package/dist/bridge/protocol.js +66 -0
- package/dist/bridge/protocol.test.js +215 -0
- package/dist/capabilities.d.ts +15 -7
- package/dist/capabilities.js +15 -39
- package/dist/detect.d.ts +9 -2
- package/dist/detect.js +15 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/native-platform.test.js +329 -0
- package/dist/native.d.ts +24 -0
- package/dist/native.js +46 -0
- package/dist/platform.d.ts +6 -3
- package/dist/platform.js +27 -18
- package/dist/platform.test.js +3 -6
- package/dist/registry.d.ts +52 -0
- package/dist/registry.js +101 -0
- package/dist/registry.test.js +681 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +1 -0
- package/dist/testing/mock-host.d.ts +49 -0
- package/dist/testing/mock-host.js +86 -0
- package/dist/types.d.ts +34 -12
- package/package.json +3 -3
|
@@ -0,0 +1,1264 @@
|
|
|
1
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
2
|
+
try {
|
|
3
|
+
var info = gen[key](arg);
|
|
4
|
+
var value = info.value;
|
|
5
|
+
} catch (error) {
|
|
6
|
+
reject(error);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (info.done) {
|
|
10
|
+
resolve(value);
|
|
11
|
+
} else {
|
|
12
|
+
Promise.resolve(value).then(_next, _throw);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function _async_to_generator(fn) {
|
|
16
|
+
return function() {
|
|
17
|
+
var self = this, args = arguments;
|
|
18
|
+
return new Promise(function(resolve, reject) {
|
|
19
|
+
var gen = fn.apply(self, args);
|
|
20
|
+
function _next(value) {
|
|
21
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
22
|
+
}
|
|
23
|
+
function _throw(err) {
|
|
24
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
25
|
+
}
|
|
26
|
+
_next(undefined);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function _define_property(obj, key, value) {
|
|
31
|
+
if (key in obj) {
|
|
32
|
+
Object.defineProperty(obj, key, {
|
|
33
|
+
value: value,
|
|
34
|
+
enumerable: true,
|
|
35
|
+
configurable: true,
|
|
36
|
+
writable: true
|
|
37
|
+
});
|
|
38
|
+
} else {
|
|
39
|
+
obj[key] = value;
|
|
40
|
+
}
|
|
41
|
+
return obj;
|
|
42
|
+
}
|
|
43
|
+
function _object_spread(target) {
|
|
44
|
+
for(var i = 1; i < arguments.length; i++){
|
|
45
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
46
|
+
var ownKeys = Object.keys(source);
|
|
47
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
48
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
49
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
ownKeys.forEach(function(key) {
|
|
53
|
+
_define_property(target, key, source[key]);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return target;
|
|
57
|
+
}
|
|
58
|
+
function _ts_generator(thisArg, body) {
|
|
59
|
+
var f, y, t, _ = {
|
|
60
|
+
label: 0,
|
|
61
|
+
sent: function() {
|
|
62
|
+
if (t[0] & 1) throw t[1];
|
|
63
|
+
return t[1];
|
|
64
|
+
},
|
|
65
|
+
trys: [],
|
|
66
|
+
ops: []
|
|
67
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
68
|
+
return d(g, "next", {
|
|
69
|
+
value: verb(0)
|
|
70
|
+
}), d(g, "throw", {
|
|
71
|
+
value: verb(1)
|
|
72
|
+
}), d(g, "return", {
|
|
73
|
+
value: verb(2)
|
|
74
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
75
|
+
value: function() {
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
}), g;
|
|
79
|
+
function verb(n) {
|
|
80
|
+
return function(v) {
|
|
81
|
+
return step([
|
|
82
|
+
n,
|
|
83
|
+
v
|
|
84
|
+
]);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function step(op) {
|
|
88
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
89
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
90
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
91
|
+
if (y = 0, t) op = [
|
|
92
|
+
op[0] & 2,
|
|
93
|
+
t.value
|
|
94
|
+
];
|
|
95
|
+
switch(op[0]){
|
|
96
|
+
case 0:
|
|
97
|
+
case 1:
|
|
98
|
+
t = op;
|
|
99
|
+
break;
|
|
100
|
+
case 4:
|
|
101
|
+
_.label++;
|
|
102
|
+
return {
|
|
103
|
+
value: op[1],
|
|
104
|
+
done: false
|
|
105
|
+
};
|
|
106
|
+
case 5:
|
|
107
|
+
_.label++;
|
|
108
|
+
y = op[1];
|
|
109
|
+
op = [
|
|
110
|
+
0
|
|
111
|
+
];
|
|
112
|
+
continue;
|
|
113
|
+
case 7:
|
|
114
|
+
op = _.ops.pop();
|
|
115
|
+
_.trys.pop();
|
|
116
|
+
continue;
|
|
117
|
+
default:
|
|
118
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
119
|
+
_ = 0;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
123
|
+
_.label = op[1];
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
127
|
+
_.label = t[1];
|
|
128
|
+
t = op;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
if (t && _.label < t[2]) {
|
|
132
|
+
_.label = t[2];
|
|
133
|
+
_.ops.push(op);
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
if (t[2]) _.ops.pop();
|
|
137
|
+
_.trys.pop();
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
op = body.call(thisArg, _);
|
|
141
|
+
} catch (e) {
|
|
142
|
+
op = [
|
|
143
|
+
6,
|
|
144
|
+
e
|
|
145
|
+
];
|
|
146
|
+
y = 0;
|
|
147
|
+
} finally{
|
|
148
|
+
f = t = 0;
|
|
149
|
+
}
|
|
150
|
+
if (op[0] & 5) throw op[1];
|
|
151
|
+
return {
|
|
152
|
+
value: op[0] ? op[1] : void 0,
|
|
153
|
+
done: true
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
158
|
+
import { PlatformError } from '../errors';
|
|
159
|
+
import { createMockHost } from '../testing';
|
|
160
|
+
import { createBridgeClient } from './client';
|
|
161
|
+
import { MAX_MESSAGE_LENGTH } from './protocol';
|
|
162
|
+
var CAPS = {
|
|
163
|
+
secureStorage: {
|
|
164
|
+
v: 1
|
|
165
|
+
},
|
|
166
|
+
lifecycle: {
|
|
167
|
+
v: 1
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
function setup() {
|
|
171
|
+
var hostOptions = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}, clientOptions = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
172
|
+
var host = createMockHost(_object_spread({
|
|
173
|
+
capabilities: CAPS
|
|
174
|
+
}, hostOptions));
|
|
175
|
+
var client = createBridgeClient(_object_spread({
|
|
176
|
+
bridge: host.bridge,
|
|
177
|
+
environment: 'android',
|
|
178
|
+
framework: '3.2.0'
|
|
179
|
+
}, clientOptions));
|
|
180
|
+
return {
|
|
181
|
+
host: host,
|
|
182
|
+
client: client
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function rejection(promise) {
|
|
186
|
+
return _async_to_generator(function() {
|
|
187
|
+
var error;
|
|
188
|
+
return _ts_generator(this, function(_state) {
|
|
189
|
+
switch(_state.label){
|
|
190
|
+
case 0:
|
|
191
|
+
return [
|
|
192
|
+
4,
|
|
193
|
+
promise.then(function() {
|
|
194
|
+
return null;
|
|
195
|
+
}, function(e) {
|
|
196
|
+
return e;
|
|
197
|
+
})
|
|
198
|
+
];
|
|
199
|
+
case 1:
|
|
200
|
+
error = _state.sent();
|
|
201
|
+
expect(error).toBeInstanceOf(PlatformError);
|
|
202
|
+
return [
|
|
203
|
+
2,
|
|
204
|
+
error
|
|
205
|
+
];
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
})();
|
|
209
|
+
}
|
|
210
|
+
describe('handshake', function() {
|
|
211
|
+
it('négocie la version et expose ce que le Host annonce (capacités inconnues ou invalides ignorées)', function() {
|
|
212
|
+
return _async_to_generator(function() {
|
|
213
|
+
var _setup, host, client, info;
|
|
214
|
+
return _ts_generator(this, function(_state) {
|
|
215
|
+
switch(_state.label){
|
|
216
|
+
case 0:
|
|
217
|
+
_setup = setup({
|
|
218
|
+
host: '2.1.0',
|
|
219
|
+
capabilities: {
|
|
220
|
+
secureStorage: {
|
|
221
|
+
v: 1
|
|
222
|
+
},
|
|
223
|
+
lifecycle: {
|
|
224
|
+
v: 3
|
|
225
|
+
},
|
|
226
|
+
futur: {
|
|
227
|
+
v: 1
|
|
228
|
+
},
|
|
229
|
+
files: {
|
|
230
|
+
v: 0
|
|
231
|
+
},
|
|
232
|
+
camera: 'x'
|
|
233
|
+
}
|
|
234
|
+
}), host = _setup.host, client = _setup.client;
|
|
235
|
+
return [
|
|
236
|
+
4,
|
|
237
|
+
client.hello()
|
|
238
|
+
];
|
|
239
|
+
case 1:
|
|
240
|
+
info = _state.sent();
|
|
241
|
+
expect(info).toEqual({
|
|
242
|
+
protocol: 1,
|
|
243
|
+
host: '2.1.0',
|
|
244
|
+
platform: 'android',
|
|
245
|
+
capabilities: {
|
|
246
|
+
secureStorage: {
|
|
247
|
+
v: 1
|
|
248
|
+
},
|
|
249
|
+
lifecycle: {
|
|
250
|
+
v: 3
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
expect(client.hostInfo).toBe(info);
|
|
255
|
+
expect(host.sent[0]).toMatchObject({
|
|
256
|
+
p: 'egen-host',
|
|
257
|
+
v: 1,
|
|
258
|
+
ns: 'host',
|
|
259
|
+
m: 'hello',
|
|
260
|
+
a: {
|
|
261
|
+
protocol: {
|
|
262
|
+
min: 1,
|
|
263
|
+
max: 1
|
|
264
|
+
},
|
|
265
|
+
framework: '3.2.0'
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
return [
|
|
269
|
+
2
|
|
270
|
+
];
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
})();
|
|
274
|
+
});
|
|
275
|
+
it('est mémorisé : un seul message envoyé même si hello() est appelé plusieurs fois', function() {
|
|
276
|
+
return _async_to_generator(function() {
|
|
277
|
+
var _setup, host, client;
|
|
278
|
+
return _ts_generator(this, function(_state) {
|
|
279
|
+
switch(_state.label){
|
|
280
|
+
case 0:
|
|
281
|
+
_setup = setup(), host = _setup.host, client = _setup.client;
|
|
282
|
+
return [
|
|
283
|
+
4,
|
|
284
|
+
Promise.all([
|
|
285
|
+
client.hello(),
|
|
286
|
+
client.hello(),
|
|
287
|
+
client.hello()
|
|
288
|
+
])
|
|
289
|
+
];
|
|
290
|
+
case 1:
|
|
291
|
+
_state.sent();
|
|
292
|
+
return [
|
|
293
|
+
4,
|
|
294
|
+
client.hello()
|
|
295
|
+
];
|
|
296
|
+
case 2:
|
|
297
|
+
_state.sent();
|
|
298
|
+
expect(host.sent.filter(function(r) {
|
|
299
|
+
return r.m === 'hello';
|
|
300
|
+
})).toHaveLength(1);
|
|
301
|
+
expect(host.subscribeCount).toBe(1);
|
|
302
|
+
return [
|
|
303
|
+
2
|
|
304
|
+
];
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
})();
|
|
308
|
+
});
|
|
309
|
+
it('protocole du Host non supporté ⇒ INCOMPATIBLE', function() {
|
|
310
|
+
return _async_to_generator(function() {
|
|
311
|
+
var client;
|
|
312
|
+
return _ts_generator(this, function(_state) {
|
|
313
|
+
switch(_state.label){
|
|
314
|
+
case 0:
|
|
315
|
+
client = setup({
|
|
316
|
+
protocol: 2,
|
|
317
|
+
replyVersion: 1
|
|
318
|
+
}).client;
|
|
319
|
+
return [
|
|
320
|
+
4,
|
|
321
|
+
rejection(client.hello())
|
|
322
|
+
];
|
|
323
|
+
case 1:
|
|
324
|
+
expect.apply(void 0, [
|
|
325
|
+
_state.sent().code
|
|
326
|
+
]).toBe('INCOMPATIBLE');
|
|
327
|
+
return [
|
|
328
|
+
2
|
|
329
|
+
];
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
})();
|
|
333
|
+
});
|
|
334
|
+
it('Host qui répond dans une version de message inconnue ⇒ INCOMPATIBLE immédiat (pas de timeout)', function() {
|
|
335
|
+
return _async_to_generator(function() {
|
|
336
|
+
var client;
|
|
337
|
+
return _ts_generator(this, function(_state) {
|
|
338
|
+
switch(_state.label){
|
|
339
|
+
case 0:
|
|
340
|
+
client = setup({
|
|
341
|
+
protocol: 1,
|
|
342
|
+
replyVersion: 7
|
|
343
|
+
}).client;
|
|
344
|
+
return [
|
|
345
|
+
4,
|
|
346
|
+
rejection(client.hello())
|
|
347
|
+
];
|
|
348
|
+
case 1:
|
|
349
|
+
expect.apply(void 0, [
|
|
350
|
+
_state.sent().code
|
|
351
|
+
]).toBe('INCOMPATIBLE');
|
|
352
|
+
return [
|
|
353
|
+
2
|
|
354
|
+
];
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
})();
|
|
358
|
+
});
|
|
359
|
+
it('plateforme annoncée différente de la cible du build ⇒ INCOMPATIBLE', function() {
|
|
360
|
+
return _async_to_generator(function() {
|
|
361
|
+
var client, error;
|
|
362
|
+
return _ts_generator(this, function(_state) {
|
|
363
|
+
switch(_state.label){
|
|
364
|
+
case 0:
|
|
365
|
+
client = setup({
|
|
366
|
+
platform: 'ios'
|
|
367
|
+
}).client;
|
|
368
|
+
return [
|
|
369
|
+
4,
|
|
370
|
+
rejection(client.hello())
|
|
371
|
+
];
|
|
372
|
+
case 1:
|
|
373
|
+
error = _state.sent();
|
|
374
|
+
expect(error.code).toBe('INCOMPATIBLE');
|
|
375
|
+
expect(error.message).toContain('ios');
|
|
376
|
+
return [
|
|
377
|
+
2
|
|
378
|
+
];
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
})();
|
|
382
|
+
});
|
|
383
|
+
it.each([
|
|
384
|
+
[
|
|
385
|
+
'null',
|
|
386
|
+
null
|
|
387
|
+
],
|
|
388
|
+
[
|
|
389
|
+
'tableau',
|
|
390
|
+
[]
|
|
391
|
+
],
|
|
392
|
+
[
|
|
393
|
+
'sans version de Host',
|
|
394
|
+
{
|
|
395
|
+
protocol: 1,
|
|
396
|
+
platform: 'android',
|
|
397
|
+
capabilities: {}
|
|
398
|
+
}
|
|
399
|
+
],
|
|
400
|
+
[
|
|
401
|
+
'Host trop long',
|
|
402
|
+
{
|
|
403
|
+
protocol: 1,
|
|
404
|
+
platform: 'android',
|
|
405
|
+
host: 'x'.repeat(65),
|
|
406
|
+
capabilities: {}
|
|
407
|
+
}
|
|
408
|
+
]
|
|
409
|
+
])('réponse hello invalide (%s) ⇒ INCOMPATIBLE', function(_label, helloResult) {
|
|
410
|
+
return _async_to_generator(function() {
|
|
411
|
+
var client;
|
|
412
|
+
return _ts_generator(this, function(_state) {
|
|
413
|
+
switch(_state.label){
|
|
414
|
+
case 0:
|
|
415
|
+
client = setup({
|
|
416
|
+
helloResult: helloResult
|
|
417
|
+
}).client;
|
|
418
|
+
return [
|
|
419
|
+
4,
|
|
420
|
+
rejection(client.hello())
|
|
421
|
+
];
|
|
422
|
+
case 1:
|
|
423
|
+
expect.apply(void 0, [
|
|
424
|
+
_state.sent().code
|
|
425
|
+
]).toBe('INCOMPATIBLE');
|
|
426
|
+
return [
|
|
427
|
+
2
|
|
428
|
+
];
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
})();
|
|
432
|
+
});
|
|
433
|
+
it('une incompatibilité est définitive : pas de nouvel envoi', function() {
|
|
434
|
+
return _async_to_generator(function() {
|
|
435
|
+
var _setup, host, client;
|
|
436
|
+
return _ts_generator(this, function(_state) {
|
|
437
|
+
switch(_state.label){
|
|
438
|
+
case 0:
|
|
439
|
+
_setup = setup({
|
|
440
|
+
protocol: 2
|
|
441
|
+
}), host = _setup.host, client = _setup.client;
|
|
442
|
+
return [
|
|
443
|
+
4,
|
|
444
|
+
rejection(client.hello())
|
|
445
|
+
];
|
|
446
|
+
case 1:
|
|
447
|
+
_state.sent();
|
|
448
|
+
return [
|
|
449
|
+
4,
|
|
450
|
+
rejection(client.hello())
|
|
451
|
+
];
|
|
452
|
+
case 2:
|
|
453
|
+
_state.sent();
|
|
454
|
+
expect(host.sent.filter(function(r) {
|
|
455
|
+
return r.m === 'hello';
|
|
456
|
+
})).toHaveLength(1);
|
|
457
|
+
return [
|
|
458
|
+
2
|
|
459
|
+
];
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
})();
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
describe('appels de capacités', function() {
|
|
466
|
+
it('exige un handshake réussi (règle 1)', function() {
|
|
467
|
+
return _async_to_generator(function() {
|
|
468
|
+
var _setup, host, client, error;
|
|
469
|
+
return _ts_generator(this, function(_state) {
|
|
470
|
+
switch(_state.label){
|
|
471
|
+
case 0:
|
|
472
|
+
_setup = setup(), host = _setup.host, client = _setup.client;
|
|
473
|
+
return [
|
|
474
|
+
4,
|
|
475
|
+
rejection(client.call('secureStorage', 'get', {
|
|
476
|
+
key: 'k'
|
|
477
|
+
}))
|
|
478
|
+
];
|
|
479
|
+
case 1:
|
|
480
|
+
error = _state.sent();
|
|
481
|
+
expect(error.code).toBe('INCOMPATIBLE');
|
|
482
|
+
expect(host.sent).toHaveLength(0);
|
|
483
|
+
return [
|
|
484
|
+
2
|
|
485
|
+
];
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
})();
|
|
489
|
+
});
|
|
490
|
+
it("refuse une capacité que le Host n'annonce pas, sans rien envoyer", function() {
|
|
491
|
+
return _async_to_generator(function() {
|
|
492
|
+
var _setup, host, client, error;
|
|
493
|
+
return _ts_generator(this, function(_state) {
|
|
494
|
+
switch(_state.label){
|
|
495
|
+
case 0:
|
|
496
|
+
_setup = setup(), host = _setup.host, client = _setup.client;
|
|
497
|
+
return [
|
|
498
|
+
4,
|
|
499
|
+
client.hello()
|
|
500
|
+
];
|
|
501
|
+
case 1:
|
|
502
|
+
_state.sent();
|
|
503
|
+
return [
|
|
504
|
+
4,
|
|
505
|
+
rejection(client.call('camera', 'capture'))
|
|
506
|
+
];
|
|
507
|
+
case 2:
|
|
508
|
+
error = _state.sent();
|
|
509
|
+
expect(error.code).toBe('UNAVAILABLE');
|
|
510
|
+
expect(host.sent).toHaveLength(1); // le hello seul
|
|
511
|
+
return [
|
|
512
|
+
2
|
|
513
|
+
];
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
})();
|
|
517
|
+
});
|
|
518
|
+
it('réserve le namespace "host" au handshake', function() {
|
|
519
|
+
return _async_to_generator(function() {
|
|
520
|
+
var client;
|
|
521
|
+
return _ts_generator(this, function(_state) {
|
|
522
|
+
switch(_state.label){
|
|
523
|
+
case 0:
|
|
524
|
+
client = setup().client;
|
|
525
|
+
return [
|
|
526
|
+
4,
|
|
527
|
+
client.hello()
|
|
528
|
+
];
|
|
529
|
+
case 1:
|
|
530
|
+
_state.sent();
|
|
531
|
+
return [
|
|
532
|
+
4,
|
|
533
|
+
rejection(client.call('host', 'hello'))
|
|
534
|
+
];
|
|
535
|
+
case 2:
|
|
536
|
+
expect.apply(void 0, [
|
|
537
|
+
_state.sent().code
|
|
538
|
+
]).toBe('INVALID_ARGS');
|
|
539
|
+
return [
|
|
540
|
+
2
|
|
541
|
+
];
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
})();
|
|
545
|
+
});
|
|
546
|
+
it('transmet les arguments et retourne le résultat', function() {
|
|
547
|
+
return _async_to_generator(function() {
|
|
548
|
+
var _setup, host, client;
|
|
549
|
+
return _ts_generator(this, function(_state) {
|
|
550
|
+
switch(_state.label){
|
|
551
|
+
case 0:
|
|
552
|
+
_setup = setup({
|
|
553
|
+
handlers: {
|
|
554
|
+
'secureStorage.get': function(a) {
|
|
555
|
+
return "valeur-de-".concat(a.key);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}), host = _setup.host, client = _setup.client;
|
|
559
|
+
return [
|
|
560
|
+
4,
|
|
561
|
+
client.hello()
|
|
562
|
+
];
|
|
563
|
+
case 1:
|
|
564
|
+
_state.sent();
|
|
565
|
+
return [
|
|
566
|
+
4,
|
|
567
|
+
expect(client.call('secureStorage', 'get', {
|
|
568
|
+
key: 'jeton'
|
|
569
|
+
})).resolves.toBe('valeur-de-jeton')
|
|
570
|
+
];
|
|
571
|
+
case 2:
|
|
572
|
+
_state.sent();
|
|
573
|
+
expect(host.sent[1]).toMatchObject({
|
|
574
|
+
ns: 'secureStorage',
|
|
575
|
+
m: 'get',
|
|
576
|
+
a: {
|
|
577
|
+
key: 'jeton'
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
return [
|
|
581
|
+
2
|
|
582
|
+
];
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
})();
|
|
586
|
+
});
|
|
587
|
+
it('un appel sans argument n’envoie pas de champ `a`', function() {
|
|
588
|
+
return _async_to_generator(function() {
|
|
589
|
+
var _setup, host, client;
|
|
590
|
+
return _ts_generator(this, function(_state) {
|
|
591
|
+
switch(_state.label){
|
|
592
|
+
case 0:
|
|
593
|
+
_setup = setup({
|
|
594
|
+
handlers: {
|
|
595
|
+
'secureStorage.get': function() {
|
|
596
|
+
return null;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}), host = _setup.host, client = _setup.client;
|
|
600
|
+
return [
|
|
601
|
+
4,
|
|
602
|
+
client.hello()
|
|
603
|
+
];
|
|
604
|
+
case 1:
|
|
605
|
+
_state.sent();
|
|
606
|
+
return [
|
|
607
|
+
4,
|
|
608
|
+
client.call('secureStorage', 'get')
|
|
609
|
+
];
|
|
610
|
+
case 2:
|
|
611
|
+
_state.sent();
|
|
612
|
+
expect(host.sent[1]).not.toHaveProperty('a');
|
|
613
|
+
return [
|
|
614
|
+
2
|
|
615
|
+
];
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
})();
|
|
619
|
+
});
|
|
620
|
+
it('convertit une erreur du Host en PlatformError (code connu conservé, retryable repris)', function() {
|
|
621
|
+
return _async_to_generator(function() {
|
|
622
|
+
var client, error;
|
|
623
|
+
return _ts_generator(this, function(_state) {
|
|
624
|
+
switch(_state.label){
|
|
625
|
+
case 0:
|
|
626
|
+
client = setup({
|
|
627
|
+
handlers: {
|
|
628
|
+
'secureStorage.get': function() {
|
|
629
|
+
throw Object.assign(new Error('refusé par l’utilisateur'), {
|
|
630
|
+
code: 'DENIED'
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}).client;
|
|
635
|
+
return [
|
|
636
|
+
4,
|
|
637
|
+
client.hello()
|
|
638
|
+
];
|
|
639
|
+
case 1:
|
|
640
|
+
_state.sent();
|
|
641
|
+
return [
|
|
642
|
+
4,
|
|
643
|
+
rejection(client.call('secureStorage', 'get', {}))
|
|
644
|
+
];
|
|
645
|
+
case 2:
|
|
646
|
+
error = _state.sent();
|
|
647
|
+
expect(error).toMatchObject({
|
|
648
|
+
code: 'DENIED',
|
|
649
|
+
message: 'refusé par l’utilisateur',
|
|
650
|
+
capability: 'secureStorage',
|
|
651
|
+
method: 'get',
|
|
652
|
+
retryable: false
|
|
653
|
+
});
|
|
654
|
+
return [
|
|
655
|
+
2
|
|
656
|
+
];
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
})();
|
|
660
|
+
});
|
|
661
|
+
it('code d’erreur inconnu ⇒ HOST_ERROR ; message tronqué ; contenu non fiable jamais propagé tel quel', function() {
|
|
662
|
+
return _async_to_generator(function() {
|
|
663
|
+
var client, error;
|
|
664
|
+
return _ts_generator(this, function(_state) {
|
|
665
|
+
switch(_state.label){
|
|
666
|
+
case 0:
|
|
667
|
+
client = setup({
|
|
668
|
+
handlers: {
|
|
669
|
+
'secureStorage.get': function() {
|
|
670
|
+
throw Object.assign(new Error('x'.repeat(2000)), {
|
|
671
|
+
code: 'PIRATE'
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}).client;
|
|
676
|
+
return [
|
|
677
|
+
4,
|
|
678
|
+
client.hello()
|
|
679
|
+
];
|
|
680
|
+
case 1:
|
|
681
|
+
_state.sent();
|
|
682
|
+
return [
|
|
683
|
+
4,
|
|
684
|
+
rejection(client.call('secureStorage', 'get', {}))
|
|
685
|
+
];
|
|
686
|
+
case 2:
|
|
687
|
+
error = _state.sent();
|
|
688
|
+
expect(error.code).toBe('HOST_ERROR');
|
|
689
|
+
expect(error.message.length).toBeLessThanOrEqual(500);
|
|
690
|
+
return [
|
|
691
|
+
2
|
|
692
|
+
];
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
})();
|
|
696
|
+
});
|
|
697
|
+
it('les réponses arrivant dans le désordre sont associées au bon appel', function() {
|
|
698
|
+
return _async_to_generator(function() {
|
|
699
|
+
var releases, gate, client, first, second;
|
|
700
|
+
return _ts_generator(this, function(_state) {
|
|
701
|
+
switch(_state.label){
|
|
702
|
+
case 0:
|
|
703
|
+
releases = {};
|
|
704
|
+
gate = function gate(name) {
|
|
705
|
+
return new Promise(function(resolve) {
|
|
706
|
+
releases[name] = function() {
|
|
707
|
+
return resolve(name);
|
|
708
|
+
};
|
|
709
|
+
});
|
|
710
|
+
};
|
|
711
|
+
client = setup({
|
|
712
|
+
handlers: {
|
|
713
|
+
'secureStorage.get': function(a) {
|
|
714
|
+
return gate(a.key);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}).client;
|
|
718
|
+
return [
|
|
719
|
+
4,
|
|
720
|
+
client.hello()
|
|
721
|
+
];
|
|
722
|
+
case 1:
|
|
723
|
+
_state.sent();
|
|
724
|
+
first = client.call('secureStorage', 'get', {
|
|
725
|
+
key: 'premier'
|
|
726
|
+
});
|
|
727
|
+
second = client.call('secureStorage', 'get', {
|
|
728
|
+
key: 'second'
|
|
729
|
+
});
|
|
730
|
+
return [
|
|
731
|
+
4,
|
|
732
|
+
vi.waitFor(function() {
|
|
733
|
+
return expect(Object.keys(releases)).toHaveLength(2);
|
|
734
|
+
})
|
|
735
|
+
];
|
|
736
|
+
case 2:
|
|
737
|
+
_state.sent();
|
|
738
|
+
releases.second();
|
|
739
|
+
releases.premier();
|
|
740
|
+
return [
|
|
741
|
+
4,
|
|
742
|
+
expect(Promise.all([
|
|
743
|
+
first,
|
|
744
|
+
second
|
|
745
|
+
])).resolves.toEqual([
|
|
746
|
+
'premier',
|
|
747
|
+
'second'
|
|
748
|
+
])
|
|
749
|
+
];
|
|
750
|
+
case 3:
|
|
751
|
+
_state.sent();
|
|
752
|
+
return [
|
|
753
|
+
2
|
|
754
|
+
];
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
})();
|
|
758
|
+
});
|
|
759
|
+
it('64 appels simultanés : chacun reçoit SA réponse, plus rien en vol', function() {
|
|
760
|
+
return _async_to_generator(function() {
|
|
761
|
+
var client, results;
|
|
762
|
+
return _ts_generator(this, function(_state) {
|
|
763
|
+
switch(_state.label){
|
|
764
|
+
case 0:
|
|
765
|
+
client = setup({
|
|
766
|
+
handlers: {
|
|
767
|
+
'secureStorage.get': function(a) {
|
|
768
|
+
return a.n * 2;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}).client;
|
|
772
|
+
return [
|
|
773
|
+
4,
|
|
774
|
+
client.hello()
|
|
775
|
+
];
|
|
776
|
+
case 1:
|
|
777
|
+
_state.sent();
|
|
778
|
+
return [
|
|
779
|
+
4,
|
|
780
|
+
Promise.all(Array.from({
|
|
781
|
+
length: 64
|
|
782
|
+
}, function(_, n) {
|
|
783
|
+
return client.call('secureStorage', 'get', {
|
|
784
|
+
n: n
|
|
785
|
+
});
|
|
786
|
+
}))
|
|
787
|
+
];
|
|
788
|
+
case 2:
|
|
789
|
+
results = _state.sent();
|
|
790
|
+
expect(results).toEqual(Array.from({
|
|
791
|
+
length: 64
|
|
792
|
+
}, function(_, n) {
|
|
793
|
+
return n * 2;
|
|
794
|
+
}));
|
|
795
|
+
expect(client.stats().inFlight).toBe(0);
|
|
796
|
+
return [
|
|
797
|
+
2
|
|
798
|
+
];
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
})();
|
|
802
|
+
});
|
|
803
|
+
it('les identifiants de requête sont uniques', function() {
|
|
804
|
+
return _async_to_generator(function() {
|
|
805
|
+
var _setup, host, client, ids;
|
|
806
|
+
return _ts_generator(this, function(_state) {
|
|
807
|
+
switch(_state.label){
|
|
808
|
+
case 0:
|
|
809
|
+
_setup = setup({
|
|
810
|
+
handlers: {
|
|
811
|
+
'secureStorage.get': function() {
|
|
812
|
+
return 1;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}), host = _setup.host, client = _setup.client;
|
|
816
|
+
return [
|
|
817
|
+
4,
|
|
818
|
+
client.hello()
|
|
819
|
+
];
|
|
820
|
+
case 1:
|
|
821
|
+
_state.sent();
|
|
822
|
+
return [
|
|
823
|
+
4,
|
|
824
|
+
Promise.all(Array.from({
|
|
825
|
+
length: 50
|
|
826
|
+
}, function() {
|
|
827
|
+
return client.call('secureStorage', 'get');
|
|
828
|
+
}))
|
|
829
|
+
];
|
|
830
|
+
case 2:
|
|
831
|
+
_state.sent();
|
|
832
|
+
ids = host.sent.map(function(r) {
|
|
833
|
+
return r.id;
|
|
834
|
+
});
|
|
835
|
+
expect(new Set(ids).size).toBe(ids.length);
|
|
836
|
+
return [
|
|
837
|
+
2
|
|
838
|
+
];
|
|
839
|
+
}
|
|
840
|
+
});
|
|
841
|
+
})();
|
|
842
|
+
});
|
|
843
|
+
});
|
|
844
|
+
describe('validation des arguments (avant tout envoi)', function() {
|
|
845
|
+
it.each([
|
|
846
|
+
[
|
|
847
|
+
'namespace invalide',
|
|
848
|
+
'secure-storage',
|
|
849
|
+
'get'
|
|
850
|
+
],
|
|
851
|
+
[
|
|
852
|
+
'méthode invalide',
|
|
853
|
+
'secureStorage',
|
|
854
|
+
'get;drop'
|
|
855
|
+
],
|
|
856
|
+
[
|
|
857
|
+
'méthode vide',
|
|
858
|
+
'secureStorage',
|
|
859
|
+
''
|
|
860
|
+
],
|
|
861
|
+
[
|
|
862
|
+
'commence par un chiffre',
|
|
863
|
+
'secureStorage',
|
|
864
|
+
'1get'
|
|
865
|
+
]
|
|
866
|
+
])('%s ⇒ INVALID_ARGS', function(_label, ns, m) {
|
|
867
|
+
return _async_to_generator(function() {
|
|
868
|
+
var _setup, host, client;
|
|
869
|
+
return _ts_generator(this, function(_state) {
|
|
870
|
+
switch(_state.label){
|
|
871
|
+
case 0:
|
|
872
|
+
_setup = setup(), host = _setup.host, client = _setup.client;
|
|
873
|
+
return [
|
|
874
|
+
4,
|
|
875
|
+
client.hello()
|
|
876
|
+
];
|
|
877
|
+
case 1:
|
|
878
|
+
_state.sent();
|
|
879
|
+
return [
|
|
880
|
+
4,
|
|
881
|
+
rejection(client.call(ns, m))
|
|
882
|
+
];
|
|
883
|
+
case 2:
|
|
884
|
+
expect.apply(void 0, [
|
|
885
|
+
_state.sent().code
|
|
886
|
+
]).toBe('INVALID_ARGS');
|
|
887
|
+
expect(host.sent).toHaveLength(1);
|
|
888
|
+
return [
|
|
889
|
+
2
|
|
890
|
+
];
|
|
891
|
+
}
|
|
892
|
+
});
|
|
893
|
+
})();
|
|
894
|
+
});
|
|
895
|
+
it('arguments non sérialisables (référence circulaire) ⇒ INVALID_ARGS', function() {
|
|
896
|
+
return _async_to_generator(function() {
|
|
897
|
+
var _setup, host, client, circular;
|
|
898
|
+
return _ts_generator(this, function(_state) {
|
|
899
|
+
switch(_state.label){
|
|
900
|
+
case 0:
|
|
901
|
+
_setup = setup(), host = _setup.host, client = _setup.client;
|
|
902
|
+
return [
|
|
903
|
+
4,
|
|
904
|
+
client.hello()
|
|
905
|
+
];
|
|
906
|
+
case 1:
|
|
907
|
+
_state.sent();
|
|
908
|
+
circular = {};
|
|
909
|
+
circular.self = circular;
|
|
910
|
+
return [
|
|
911
|
+
4,
|
|
912
|
+
rejection(client.call('secureStorage', 'set', circular))
|
|
913
|
+
];
|
|
914
|
+
case 2:
|
|
915
|
+
expect.apply(void 0, [
|
|
916
|
+
_state.sent().code
|
|
917
|
+
]).toBe('INVALID_ARGS');
|
|
918
|
+
expect(host.sent).toHaveLength(1);
|
|
919
|
+
return [
|
|
920
|
+
2
|
|
921
|
+
];
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
})();
|
|
925
|
+
});
|
|
926
|
+
it('message trop volumineux ⇒ INVALID_ARGS (référence de fichier attendue)', function() {
|
|
927
|
+
return _async_to_generator(function() {
|
|
928
|
+
var _setup, host, client, error;
|
|
929
|
+
return _ts_generator(this, function(_state) {
|
|
930
|
+
switch(_state.label){
|
|
931
|
+
case 0:
|
|
932
|
+
_setup = setup(), host = _setup.host, client = _setup.client;
|
|
933
|
+
return [
|
|
934
|
+
4,
|
|
935
|
+
client.hello()
|
|
936
|
+
];
|
|
937
|
+
case 1:
|
|
938
|
+
_state.sent();
|
|
939
|
+
return [
|
|
940
|
+
4,
|
|
941
|
+
rejection(client.call('secureStorage', 'set', {
|
|
942
|
+
v: 'x'.repeat(MAX_MESSAGE_LENGTH)
|
|
943
|
+
}))
|
|
944
|
+
];
|
|
945
|
+
case 2:
|
|
946
|
+
error = _state.sent();
|
|
947
|
+
expect(error.code).toBe('INVALID_ARGS');
|
|
948
|
+
expect(error.message).toContain('référence de fichier');
|
|
949
|
+
expect(host.sent).toHaveLength(1);
|
|
950
|
+
return [
|
|
951
|
+
2
|
|
952
|
+
];
|
|
953
|
+
}
|
|
954
|
+
});
|
|
955
|
+
})();
|
|
956
|
+
});
|
|
957
|
+
it('échec de bridge.send ⇒ HOST_ERROR, sans appel en vol résiduel', function() {
|
|
958
|
+
return _async_to_generator(function() {
|
|
959
|
+
var host, client, bridge, failing, error;
|
|
960
|
+
return _ts_generator(this, function(_state) {
|
|
961
|
+
switch(_state.label){
|
|
962
|
+
case 0:
|
|
963
|
+
host = createMockHost({
|
|
964
|
+
capabilities: CAPS
|
|
965
|
+
});
|
|
966
|
+
client = createBridgeClient({
|
|
967
|
+
bridge: host.bridge,
|
|
968
|
+
environment: 'android'
|
|
969
|
+
});
|
|
970
|
+
return [
|
|
971
|
+
4,
|
|
972
|
+
client.hello()
|
|
973
|
+
];
|
|
974
|
+
case 1:
|
|
975
|
+
_state.sent();
|
|
976
|
+
bridge = {
|
|
977
|
+
send: function send() {
|
|
978
|
+
throw new Error('WebView détruite');
|
|
979
|
+
},
|
|
980
|
+
subscribe: host.bridge.subscribe
|
|
981
|
+
};
|
|
982
|
+
failing = createBridgeClient({
|
|
983
|
+
bridge: bridge,
|
|
984
|
+
environment: 'android'
|
|
985
|
+
});
|
|
986
|
+
return [
|
|
987
|
+
4,
|
|
988
|
+
rejection(failing.hello())
|
|
989
|
+
];
|
|
990
|
+
case 2:
|
|
991
|
+
error = _state.sent();
|
|
992
|
+
expect(error.code).toBe('HOST_ERROR');
|
|
993
|
+
expect(error.message).toContain('WebView détruite');
|
|
994
|
+
expect(failing.stats().inFlight).toBe(0);
|
|
995
|
+
return [
|
|
996
|
+
2
|
|
997
|
+
];
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
})();
|
|
1001
|
+
});
|
|
1002
|
+
});
|
|
1003
|
+
describe('délais', function() {
|
|
1004
|
+
beforeEach(function() {
|
|
1005
|
+
return vi.useFakeTimers();
|
|
1006
|
+
});
|
|
1007
|
+
afterEach(function() {
|
|
1008
|
+
return vi.useRealTimers();
|
|
1009
|
+
});
|
|
1010
|
+
it('hello : TIMEOUT rejouable, puis un second essai peut réussir', function() {
|
|
1011
|
+
return _async_to_generator(function() {
|
|
1012
|
+
var host, client, first, error, retry;
|
|
1013
|
+
return _ts_generator(this, function(_state) {
|
|
1014
|
+
switch(_state.label){
|
|
1015
|
+
case 0:
|
|
1016
|
+
host = createMockHost({
|
|
1017
|
+
capabilities: CAPS,
|
|
1018
|
+
respond: false
|
|
1019
|
+
});
|
|
1020
|
+
client = createBridgeClient({
|
|
1021
|
+
bridge: host.bridge,
|
|
1022
|
+
environment: 'android',
|
|
1023
|
+
timeoutMs: 1000
|
|
1024
|
+
});
|
|
1025
|
+
first = rejection(client.hello());
|
|
1026
|
+
return [
|
|
1027
|
+
4,
|
|
1028
|
+
vi.advanceTimersByTimeAsync(1000)
|
|
1029
|
+
];
|
|
1030
|
+
case 1:
|
|
1031
|
+
_state.sent();
|
|
1032
|
+
return [
|
|
1033
|
+
4,
|
|
1034
|
+
first
|
|
1035
|
+
];
|
|
1036
|
+
case 2:
|
|
1037
|
+
error = _state.sent();
|
|
1038
|
+
expect(error).toMatchObject({
|
|
1039
|
+
code: 'TIMEOUT',
|
|
1040
|
+
retryable: true
|
|
1041
|
+
});
|
|
1042
|
+
// Le Host « se réveille » : un nouvel appel doit renvoyer un hello (échec passager non mémorisé).
|
|
1043
|
+
retry = client.hello();
|
|
1044
|
+
retry.catch(function() {});
|
|
1045
|
+
expect(host.sent.filter(function(r) {
|
|
1046
|
+
return r.m === 'hello';
|
|
1047
|
+
})).toHaveLength(2);
|
|
1048
|
+
return [
|
|
1049
|
+
4,
|
|
1050
|
+
vi.advanceTimersByTimeAsync(1000)
|
|
1051
|
+
];
|
|
1052
|
+
case 3:
|
|
1053
|
+
_state.sent();
|
|
1054
|
+
return [
|
|
1055
|
+
2
|
|
1056
|
+
];
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
})();
|
|
1060
|
+
});
|
|
1061
|
+
it('appel : TIMEOUT retryable, délai par appel prioritaire, réponse tardive ignorée', function() {
|
|
1062
|
+
return _async_to_generator(function() {
|
|
1063
|
+
var host, client, hello, pendingCall;
|
|
1064
|
+
return _ts_generator(this, function(_state) {
|
|
1065
|
+
switch(_state.label){
|
|
1066
|
+
case 0:
|
|
1067
|
+
host = createMockHost({
|
|
1068
|
+
capabilities: CAPS,
|
|
1069
|
+
latencyMs: 5000,
|
|
1070
|
+
handlers: {
|
|
1071
|
+
'secureStorage.get': function() {
|
|
1072
|
+
return 'tard';
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
});
|
|
1076
|
+
client = createBridgeClient({
|
|
1077
|
+
bridge: host.bridge,
|
|
1078
|
+
environment: 'android',
|
|
1079
|
+
timeoutMs: 60000
|
|
1080
|
+
});
|
|
1081
|
+
hello = client.hello();
|
|
1082
|
+
return [
|
|
1083
|
+
4,
|
|
1084
|
+
vi.advanceTimersByTimeAsync(5000)
|
|
1085
|
+
];
|
|
1086
|
+
case 1:
|
|
1087
|
+
_state.sent();
|
|
1088
|
+
return [
|
|
1089
|
+
4,
|
|
1090
|
+
hello
|
|
1091
|
+
];
|
|
1092
|
+
case 2:
|
|
1093
|
+
_state.sent();
|
|
1094
|
+
pendingCall = rejection(client.call('secureStorage', 'get', {}, {
|
|
1095
|
+
timeoutMs: 100
|
|
1096
|
+
}));
|
|
1097
|
+
return [
|
|
1098
|
+
4,
|
|
1099
|
+
vi.advanceTimersByTimeAsync(100)
|
|
1100
|
+
];
|
|
1101
|
+
case 3:
|
|
1102
|
+
_state.sent();
|
|
1103
|
+
return [
|
|
1104
|
+
4,
|
|
1105
|
+
pendingCall
|
|
1106
|
+
];
|
|
1107
|
+
case 4:
|
|
1108
|
+
expect.apply(void 0, [
|
|
1109
|
+
_state.sent()
|
|
1110
|
+
]).toMatchObject({
|
|
1111
|
+
code: 'TIMEOUT',
|
|
1112
|
+
retryable: true,
|
|
1113
|
+
capability: 'secureStorage',
|
|
1114
|
+
method: 'get'
|
|
1115
|
+
});
|
|
1116
|
+
expect(client.stats().inFlight).toBe(0);
|
|
1117
|
+
return [
|
|
1118
|
+
4,
|
|
1119
|
+
vi.advanceTimersByTimeAsync(5000)
|
|
1120
|
+
];
|
|
1121
|
+
case 5:
|
|
1122
|
+
_state.sent(); // la réponse arrive après expiration
|
|
1123
|
+
expect(client.stats().ignoredMessages).toBe(1);
|
|
1124
|
+
return [
|
|
1125
|
+
2
|
|
1126
|
+
];
|
|
1127
|
+
}
|
|
1128
|
+
});
|
|
1129
|
+
})();
|
|
1130
|
+
});
|
|
1131
|
+
});
|
|
1132
|
+
describe('messages entrants', function() {
|
|
1133
|
+
it('ignore et compte tout ce qui est invalide, orphelin ou de version inconnue — sans effet de bord', function() {
|
|
1134
|
+
return _async_to_generator(function() {
|
|
1135
|
+
var _setup, host, client, before;
|
|
1136
|
+
return _ts_generator(this, function(_state) {
|
|
1137
|
+
switch(_state.label){
|
|
1138
|
+
case 0:
|
|
1139
|
+
_setup = setup(), host = _setup.host, client = _setup.client;
|
|
1140
|
+
return [
|
|
1141
|
+
4,
|
|
1142
|
+
client.hello()
|
|
1143
|
+
];
|
|
1144
|
+
case 1:
|
|
1145
|
+
_state.sent();
|
|
1146
|
+
before = client.stats().ignoredMessages;
|
|
1147
|
+
host.inject('{pas du json');
|
|
1148
|
+
host.inject(JSON.stringify({
|
|
1149
|
+
p: 'autre',
|
|
1150
|
+
v: 1,
|
|
1151
|
+
id: 'x',
|
|
1152
|
+
ok: true
|
|
1153
|
+
}));
|
|
1154
|
+
host.inject(JSON.stringify({
|
|
1155
|
+
p: 'egen-host',
|
|
1156
|
+
v: 1,
|
|
1157
|
+
id: 'inconnu',
|
|
1158
|
+
ok: true,
|
|
1159
|
+
r: 1
|
|
1160
|
+
})); // orpheline
|
|
1161
|
+
host.inject(JSON.stringify({
|
|
1162
|
+
p: 'egen-host',
|
|
1163
|
+
v: 9,
|
|
1164
|
+
ev: 'lifecycle.resume'
|
|
1165
|
+
})); // événement de version inconnue
|
|
1166
|
+
host.inject('x'.repeat(MAX_MESSAGE_LENGTH + 1));
|
|
1167
|
+
expect(client.stats().ignoredMessages - before).toBe(5);
|
|
1168
|
+
expect(client.stats().inFlight).toBe(0);
|
|
1169
|
+
return [
|
|
1170
|
+
2
|
|
1171
|
+
];
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
})();
|
|
1175
|
+
});
|
|
1176
|
+
});
|
|
1177
|
+
describe('événements', function() {
|
|
1178
|
+
it('route un événement à ses abonnés, avec sa donnée', function() {
|
|
1179
|
+
return _async_to_generator(function() {
|
|
1180
|
+
var _setup, host, client, resume, other;
|
|
1181
|
+
return _ts_generator(this, function(_state) {
|
|
1182
|
+
switch(_state.label){
|
|
1183
|
+
case 0:
|
|
1184
|
+
_setup = setup(), host = _setup.host, client = _setup.client;
|
|
1185
|
+
return [
|
|
1186
|
+
4,
|
|
1187
|
+
client.hello()
|
|
1188
|
+
];
|
|
1189
|
+
case 1:
|
|
1190
|
+
_state.sent();
|
|
1191
|
+
resume = vi.fn();
|
|
1192
|
+
other = vi.fn();
|
|
1193
|
+
client.onEvent('lifecycle.resume', resume);
|
|
1194
|
+
client.onEvent('lifecycle.pause', other);
|
|
1195
|
+
host.emit('lifecycle.resume', {
|
|
1196
|
+
at: 1
|
|
1197
|
+
});
|
|
1198
|
+
expect(resume).toHaveBeenCalledWith({
|
|
1199
|
+
at: 1
|
|
1200
|
+
});
|
|
1201
|
+
expect(other).not.toHaveBeenCalled();
|
|
1202
|
+
return [
|
|
1203
|
+
2
|
|
1204
|
+
];
|
|
1205
|
+
}
|
|
1206
|
+
});
|
|
1207
|
+
})();
|
|
1208
|
+
});
|
|
1209
|
+
it('se désabonne proprement', function() {
|
|
1210
|
+
return _async_to_generator(function() {
|
|
1211
|
+
var _setup, host, client, callback, unsubscribe;
|
|
1212
|
+
return _ts_generator(this, function(_state) {
|
|
1213
|
+
switch(_state.label){
|
|
1214
|
+
case 0:
|
|
1215
|
+
_setup = setup(), host = _setup.host, client = _setup.client;
|
|
1216
|
+
return [
|
|
1217
|
+
4,
|
|
1218
|
+
client.hello()
|
|
1219
|
+
];
|
|
1220
|
+
case 1:
|
|
1221
|
+
_state.sent();
|
|
1222
|
+
callback = vi.fn();
|
|
1223
|
+
unsubscribe = client.onEvent('lifecycle.resume', callback);
|
|
1224
|
+
unsubscribe();
|
|
1225
|
+
host.emit('lifecycle.resume');
|
|
1226
|
+
expect(callback).not.toHaveBeenCalled();
|
|
1227
|
+
return [
|
|
1228
|
+
2
|
|
1229
|
+
];
|
|
1230
|
+
}
|
|
1231
|
+
});
|
|
1232
|
+
})();
|
|
1233
|
+
});
|
|
1234
|
+
it("un abonné qui lève n'empêche ni les autres abonnés ni la suite", function() {
|
|
1235
|
+
return _async_to_generator(function() {
|
|
1236
|
+
var _setup, host, client, error, healthy;
|
|
1237
|
+
return _ts_generator(this, function(_state) {
|
|
1238
|
+
switch(_state.label){
|
|
1239
|
+
case 0:
|
|
1240
|
+
_setup = setup(), host = _setup.host, client = _setup.client;
|
|
1241
|
+
return [
|
|
1242
|
+
4,
|
|
1243
|
+
client.hello()
|
|
1244
|
+
];
|
|
1245
|
+
case 1:
|
|
1246
|
+
_state.sent();
|
|
1247
|
+
error = vi.spyOn(console, 'error').mockImplementation(function() {});
|
|
1248
|
+
healthy = vi.fn();
|
|
1249
|
+
client.onEvent('lifecycle.resume', function() {
|
|
1250
|
+
throw new Error('bug applicatif');
|
|
1251
|
+
});
|
|
1252
|
+
client.onEvent('lifecycle.resume', healthy);
|
|
1253
|
+
host.emit('lifecycle.resume');
|
|
1254
|
+
expect(healthy).toHaveBeenCalledTimes(1);
|
|
1255
|
+
expect(error).toHaveBeenCalled();
|
|
1256
|
+
error.mockRestore();
|
|
1257
|
+
return [
|
|
1258
|
+
2
|
|
1259
|
+
];
|
|
1260
|
+
}
|
|
1261
|
+
});
|
|
1262
|
+
})();
|
|
1263
|
+
});
|
|
1264
|
+
});
|