@webex/internal-plugin-device 2.59.2 → 2.59.3-next.1
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/.eslintrc.js +6 -6
- package/README.md +80 -80
- package/babel.config.js +3 -3
- package/dist/config.js +27 -27
- package/dist/config.js.map +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/device.js +226 -226
- package/dist/device.js.map +1 -1
- package/dist/features/feature-collection.js +14 -14
- package/dist/features/feature-collection.js.map +1 -1
- package/dist/features/feature-model.js +73 -73
- package/dist/features/feature-model.js.map +1 -1
- package/dist/features/features-model.js +28 -28
- package/dist/features/features-model.js.map +1 -1
- package/dist/features/index.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/interceptors/device-url.js +8 -8
- package/dist/interceptors/device-url.js.map +1 -1
- package/dist/metrics.js.map +1 -1
- package/jest.config.js +3 -3
- package/package.json +17 -16
- package/process +1 -1
- package/src/config.js +60 -60
- package/src/constants.js +23 -23
- package/src/device.js +835 -835
- package/src/features/feature-collection.js +30 -30
- package/src/features/feature-model.js +189 -189
- package/src/features/features-model.js +96 -96
- package/src/features/index.js +5 -5
- package/src/index.js +29 -29
- package/src/interceptors/device-url.js +61 -61
- package/src/metrics.js +5 -5
- package/test/integration/spec/device.js +904 -904
- package/test/integration/spec/webex.js +42 -42
- package/test/unit/spec/device.js +409 -409
- package/test/unit/spec/features/feature-collection.js +24 -24
- package/test/unit/spec/features/feature-model.js +255 -255
- package/test/unit/spec/features/features-model.js +97 -97
- package/test/unit/spec/interceptors/device-url.js +215 -215
- package/test/unit/spec/wdm-dto.json +104 -104
package/test/unit/spec/device.js
CHANGED
|
@@ -1,409 +1,409 @@
|
|
|
1
|
-
import {assert} from '@webex/test-helper-chai';
|
|
2
|
-
import {cloneDeep} from 'lodash';
|
|
3
|
-
import MockWebex from '@webex/test-helper-mock-webex';
|
|
4
|
-
import sinon from 'sinon';
|
|
5
|
-
import Device from '@webex/internal-plugin-device';
|
|
6
|
-
|
|
7
|
-
import dto from './wdm-dto';
|
|
8
|
-
|
|
9
|
-
describe('plugin-device', () => {
|
|
10
|
-
describe('Device', () => {
|
|
11
|
-
let webex;
|
|
12
|
-
let device;
|
|
13
|
-
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
webex = new MockWebex({
|
|
16
|
-
children: {
|
|
17
|
-
device: Device,
|
|
18
|
-
},
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
const clonedDTO = cloneDeep(dto);
|
|
22
|
-
|
|
23
|
-
webex.internal.device.set(clonedDTO);
|
|
24
|
-
|
|
25
|
-
device = webex.internal.device;
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
describe('events', () => {
|
|
29
|
-
describe('when a feature is changed', () => {
|
|
30
|
-
let spy;
|
|
31
|
-
let modifiedDTOFeatures;
|
|
32
|
-
|
|
33
|
-
beforeEach(() => {
|
|
34
|
-
spy = sinon.spy();
|
|
35
|
-
modifiedDTOFeatures = {
|
|
36
|
-
...dto.features,
|
|
37
|
-
user: [...dto.features.user, ...dto.features.developer],
|
|
38
|
-
};
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("should trigger a 'change' event", () => {
|
|
42
|
-
device.on('change', spy);
|
|
43
|
-
device.features.set(modifiedDTOFeatures);
|
|
44
|
-
assert.called(spy);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("should trigger a 'change:features' event", () => {
|
|
48
|
-
device.on('change:features', spy);
|
|
49
|
-
device.features.set(modifiedDTOFeatures);
|
|
50
|
-
assert.called(spy);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
describe('when an network inactivity property changes', () => {
|
|
55
|
-
beforeEach(() => {
|
|
56
|
-
device.checkNetworkReachability = sinon.spy();
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe('when the \'intranetInactivityCheckUrl\' changes', () => {
|
|
60
|
-
beforeEach(() => {
|
|
61
|
-
device.intranetInactivityCheckUrl = 'https://not-a-url.com';
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("should call 'checkNetworkReachability()'", () => {
|
|
65
|
-
assert.called(device.checkNetworkReachability);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should set isReachabilityChecked to true', () => {
|
|
69
|
-
assert.isTrue(device.isReachabilityChecked);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
describe('when the \'intranetInactivityDuration\' changes', () => {
|
|
74
|
-
beforeEach(() => {
|
|
75
|
-
device.intranetInactivityDuration = 1234;
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("should call 'checkNetworkReachability()'", () => {
|
|
79
|
-
assert.called(device.checkNetworkReachability);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('should set isReachabilityChecked to true', () => {
|
|
83
|
-
assert.isTrue(device.isReachabilityChecked);
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
describe('when the \'inNetworkInactivityDuration\' changes', () => {
|
|
88
|
-
beforeEach(() => {
|
|
89
|
-
device.inNetworkInactivityDuration = 1234;
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it("should call 'checkNetworkReachability()'", () => {
|
|
93
|
-
assert.called(device.checkNetworkReachability);
|
|
94
|
-
assert.isTrue(device.isReachabilityChecked);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe('derived properties', () => {
|
|
101
|
-
describe('#registered', () => {
|
|
102
|
-
describe('when the device does not have a url', () => {
|
|
103
|
-
beforeEach(() => {
|
|
104
|
-
device.url = undefined;
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it('should return false', () => {
|
|
108
|
-
assert.isFalse(device.registered);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('when the device does have a url', () => {
|
|
113
|
-
beforeEach(() => {
|
|
114
|
-
device.url = dto.url;
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('should return true', () => {
|
|
118
|
-
assert.isTrue(device.registered);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
describe('#setLogoutTimer()', () => {
|
|
125
|
-
describe('when the duration parameter is not set', () => {
|
|
126
|
-
it('should not change the existing timer', () => {
|
|
127
|
-
const {logoutTimer} = device;
|
|
128
|
-
|
|
129
|
-
device.setLogoutTimer();
|
|
130
|
-
assert.equal(device.logoutTimer, logoutTimer);
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
describe('when the duration parameter is zero or negative', () => {
|
|
135
|
-
it('should not change the existing timer', () => {
|
|
136
|
-
const {logoutTimer} = device;
|
|
137
|
-
|
|
138
|
-
device.setLogoutTimer(-1);
|
|
139
|
-
assert.equal(device.logoutTimer, logoutTimer);
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
describe('when the duration is valid', () => {
|
|
144
|
-
beforeEach(() => {
|
|
145
|
-
device.resetLogoutTimer = sinon.spy();
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("should create a 'change:lastUserActivityDate' listener", () => {
|
|
149
|
-
device.setLogoutTimer(60000);
|
|
150
|
-
device.trigger('change:lastUserActivityDate');
|
|
151
|
-
assert.called(device.resetLogoutTimer);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it('should set the logout timer', () => {
|
|
155
|
-
const {logoutTimer} = device;
|
|
156
|
-
|
|
157
|
-
device.setLogoutTimer(60000);
|
|
158
|
-
assert.notEqual(device.logoutTimer, logoutTimer);
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe('#serialize()', () => {
|
|
164
|
-
it('should serialize entitlement feature keys', () => {
|
|
165
|
-
assert.hasAllKeys(
|
|
166
|
-
device.serialize().features.entitlement,
|
|
167
|
-
Object.keys(dto.features.entitlement)
|
|
168
|
-
);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it('should serialize user feature keys', () => {
|
|
172
|
-
assert.hasAllKeys(device.serialize().features.user, Object.keys(dto.features.user));
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
describe('#refresh()', () => {
|
|
177
|
-
let requestSpy;
|
|
178
|
-
|
|
179
|
-
const setup = () => {
|
|
180
|
-
sinon.stub(device, 'canRegister').callsFake(() => Promise.resolve());
|
|
181
|
-
sinon.stub(device, 'processRegistrationSuccess').callsFake(() => {});
|
|
182
|
-
requestSpy = sinon.spy(device, 'request');
|
|
183
|
-
device.config.defaults = {};
|
|
184
|
-
device.set('registered', true);
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
it('If-None-Match header is added if etag is set', async () => {
|
|
188
|
-
setup();
|
|
189
|
-
|
|
190
|
-
device.set('etag', 'etag-value');
|
|
191
|
-
|
|
192
|
-
const result = device.refresh();
|
|
193
|
-
|
|
194
|
-
await result;
|
|
195
|
-
|
|
196
|
-
assert.deepEqual(requestSpy.args[0][0].headers, {
|
|
197
|
-
'If-None-Match': 'etag-value',
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it('If-None-Match header is not added if etag is not set', async () => {
|
|
202
|
-
setup();
|
|
203
|
-
|
|
204
|
-
const result = device.refresh();
|
|
205
|
-
|
|
206
|
-
await result;
|
|
207
|
-
|
|
208
|
-
assert.deepEqual(requestSpy.args[0][0].headers, {});
|
|
209
|
-
});
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
describe('#processRegistrationSuccess()', () => {
|
|
213
|
-
const getClonedDTO = (overrides) => {
|
|
214
|
-
const clonedDTO = cloneDeep(dto);
|
|
215
|
-
|
|
216
|
-
clonedDTO.features = {
|
|
217
|
-
developer: [
|
|
218
|
-
{
|
|
219
|
-
key: '1',
|
|
220
|
-
type: 'boolean',
|
|
221
|
-
val: 'true',
|
|
222
|
-
value: true,
|
|
223
|
-
mutable: true,
|
|
224
|
-
lastModified: '2015-06-29T20:02:48.033Z',
|
|
225
|
-
},
|
|
226
|
-
],
|
|
227
|
-
entitlement: [
|
|
228
|
-
{
|
|
229
|
-
key: '2',
|
|
230
|
-
val: 'true',
|
|
231
|
-
value: true,
|
|
232
|
-
mutable: false,
|
|
233
|
-
},
|
|
234
|
-
],
|
|
235
|
-
user: [
|
|
236
|
-
{
|
|
237
|
-
key: '3',
|
|
238
|
-
val: 'true',
|
|
239
|
-
value: true,
|
|
240
|
-
mutable: true,
|
|
241
|
-
},
|
|
242
|
-
],
|
|
243
|
-
...overrides,
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
return clonedDTO;
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
const checkFeatureNotPresent = (type, key) => {
|
|
250
|
-
assert.isUndefined(device.features[type].get(key));
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
const checkFeature = (type, key, expectedValue) => {
|
|
254
|
-
assert.equal(device.features[type].length, 1);
|
|
255
|
-
assert.deepEqual(device.features[type].get(key).get('value'), expectedValue);
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
it('features are set correctly if etag not in headers', () => {
|
|
259
|
-
const clonedDTO = getClonedDTO();
|
|
260
|
-
|
|
261
|
-
const response = {
|
|
262
|
-
body: {
|
|
263
|
-
...clonedDTO,
|
|
264
|
-
},
|
|
265
|
-
headers: {},
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
checkFeatureNotPresent('developer', '1');
|
|
269
|
-
checkFeatureNotPresent('entitlement', '2');
|
|
270
|
-
checkFeatureNotPresent('user', '3');
|
|
271
|
-
|
|
272
|
-
device.processRegistrationSuccess(response);
|
|
273
|
-
|
|
274
|
-
checkFeature('developer', '1', true);
|
|
275
|
-
checkFeature('entitlement', '2', true);
|
|
276
|
-
checkFeature('user', '3', true);
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
it('if the etag matches only the user and entitlement features are updated', () => {
|
|
280
|
-
const clonedDTO = getClonedDTO();
|
|
281
|
-
|
|
282
|
-
device.set('etag', 'etag-value');
|
|
283
|
-
|
|
284
|
-
const response = {
|
|
285
|
-
body: {
|
|
286
|
-
...clonedDTO,
|
|
287
|
-
},
|
|
288
|
-
headers: {
|
|
289
|
-
etag: 'etag-value',
|
|
290
|
-
},
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
checkFeatureNotPresent('developer', '1');
|
|
294
|
-
checkFeatureNotPresent('entitlement', '2');
|
|
295
|
-
checkFeatureNotPresent('user', '3');
|
|
296
|
-
|
|
297
|
-
device.processRegistrationSuccess(response);
|
|
298
|
-
|
|
299
|
-
checkFeatureNotPresent('developer', '1');
|
|
300
|
-
checkFeature('entitlement', '2', true);
|
|
301
|
-
checkFeature('user', '3', true);
|
|
302
|
-
|
|
303
|
-
// confirm that the etag is unchanged
|
|
304
|
-
assert.equal(device.get('etag'), 'etag-value');
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
it('if the etag matches only the user and entitlement features are updated - check when developer features are set', () => {
|
|
308
|
-
const clonedDTO = getClonedDTO();
|
|
309
|
-
|
|
310
|
-
device.set('etag', 'etag-value');
|
|
311
|
-
|
|
312
|
-
const response = {
|
|
313
|
-
body: {
|
|
314
|
-
...clonedDTO,
|
|
315
|
-
},
|
|
316
|
-
headers: {
|
|
317
|
-
etag: 'etag-value',
|
|
318
|
-
},
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
checkFeatureNotPresent('developer', '1');
|
|
322
|
-
checkFeatureNotPresent('entitlement', '2');
|
|
323
|
-
checkFeatureNotPresent('user', '3');
|
|
324
|
-
|
|
325
|
-
device.processRegistrationSuccess(response);
|
|
326
|
-
|
|
327
|
-
checkFeatureNotPresent('developer', '1');
|
|
328
|
-
checkFeature('entitlement', '2', true);
|
|
329
|
-
checkFeature('user', '3', true);
|
|
330
|
-
|
|
331
|
-
// confirm that the etag is unchanged
|
|
332
|
-
assert.equal(device.get('etag'), 'etag-value');
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
it('if the etag does not match all the features are updated', () => {
|
|
336
|
-
const clonedDTO = getClonedDTO();
|
|
337
|
-
|
|
338
|
-
device.set('etag', 'etag-value');
|
|
339
|
-
|
|
340
|
-
const response = {
|
|
341
|
-
body: {
|
|
342
|
-
...clonedDTO,
|
|
343
|
-
},
|
|
344
|
-
headers: {
|
|
345
|
-
etag: 'different-etag-value',
|
|
346
|
-
},
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
checkFeatureNotPresent('developer', '1');
|
|
350
|
-
checkFeatureNotPresent('entitlement', '2');
|
|
351
|
-
checkFeatureNotPresent('user', '3');
|
|
352
|
-
|
|
353
|
-
device.processRegistrationSuccess(response);
|
|
354
|
-
|
|
355
|
-
checkFeature('developer', '1', true);
|
|
356
|
-
checkFeature('entitlement', '2', true);
|
|
357
|
-
checkFeature('user', '3', true);
|
|
358
|
-
|
|
359
|
-
// confirm that the new etag is set
|
|
360
|
-
assert.equal(device.get('etag'), 'different-etag-value');
|
|
361
|
-
|
|
362
|
-
const newClonedDTO = getClonedDTO({
|
|
363
|
-
developer: [
|
|
364
|
-
{
|
|
365
|
-
key: '1',
|
|
366
|
-
type: 'boolean',
|
|
367
|
-
val: 'false',
|
|
368
|
-
value: false,
|
|
369
|
-
mutable: true,
|
|
370
|
-
lastModified: '2015-06-29T20:02:48.033Z',
|
|
371
|
-
},
|
|
372
|
-
],
|
|
373
|
-
entitlement: [
|
|
374
|
-
{
|
|
375
|
-
key: '2',
|
|
376
|
-
val: 'false',
|
|
377
|
-
value: false,
|
|
378
|
-
mutable: false,
|
|
379
|
-
},
|
|
380
|
-
],
|
|
381
|
-
user: [
|
|
382
|
-
{
|
|
383
|
-
key: '3',
|
|
384
|
-
val: 'false',
|
|
385
|
-
value: false,
|
|
386
|
-
mutable: true,
|
|
387
|
-
},
|
|
388
|
-
],
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
const newResponse = {
|
|
392
|
-
body: {
|
|
393
|
-
...newClonedDTO,
|
|
394
|
-
},
|
|
395
|
-
headers: {
|
|
396
|
-
etag: 'different-etag-value',
|
|
397
|
-
},
|
|
398
|
-
};
|
|
399
|
-
|
|
400
|
-
device.processRegistrationSuccess(newResponse);
|
|
401
|
-
|
|
402
|
-
// only the entitlement and user features should have been changed to false
|
|
403
|
-
checkFeature('developer', '1', true);
|
|
404
|
-
checkFeature('entitlement', '2', false);
|
|
405
|
-
checkFeature('user', '3', false);
|
|
406
|
-
});
|
|
407
|
-
});
|
|
408
|
-
});
|
|
409
|
-
});
|
|
1
|
+
import {assert} from '@webex/test-helper-chai';
|
|
2
|
+
import {cloneDeep} from 'lodash';
|
|
3
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
4
|
+
import sinon from 'sinon';
|
|
5
|
+
import Device from '@webex/internal-plugin-device';
|
|
6
|
+
|
|
7
|
+
import dto from './wdm-dto';
|
|
8
|
+
|
|
9
|
+
describe('plugin-device', () => {
|
|
10
|
+
describe('Device', () => {
|
|
11
|
+
let webex;
|
|
12
|
+
let device;
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
webex = new MockWebex({
|
|
16
|
+
children: {
|
|
17
|
+
device: Device,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const clonedDTO = cloneDeep(dto);
|
|
22
|
+
|
|
23
|
+
webex.internal.device.set(clonedDTO);
|
|
24
|
+
|
|
25
|
+
device = webex.internal.device;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe('events', () => {
|
|
29
|
+
describe('when a feature is changed', () => {
|
|
30
|
+
let spy;
|
|
31
|
+
let modifiedDTOFeatures;
|
|
32
|
+
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
spy = sinon.spy();
|
|
35
|
+
modifiedDTOFeatures = {
|
|
36
|
+
...dto.features,
|
|
37
|
+
user: [...dto.features.user, ...dto.features.developer],
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should trigger a 'change' event", () => {
|
|
42
|
+
device.on('change', spy);
|
|
43
|
+
device.features.set(modifiedDTOFeatures);
|
|
44
|
+
assert.called(spy);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should trigger a 'change:features' event", () => {
|
|
48
|
+
device.on('change:features', spy);
|
|
49
|
+
device.features.set(modifiedDTOFeatures);
|
|
50
|
+
assert.called(spy);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('when an network inactivity property changes', () => {
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
device.checkNetworkReachability = sinon.spy();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('when the \'intranetInactivityCheckUrl\' changes', () => {
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
device.intranetInactivityCheckUrl = 'https://not-a-url.com';
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should call 'checkNetworkReachability()'", () => {
|
|
65
|
+
assert.called(device.checkNetworkReachability);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should set isReachabilityChecked to true', () => {
|
|
69
|
+
assert.isTrue(device.isReachabilityChecked);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('when the \'intranetInactivityDuration\' changes', () => {
|
|
74
|
+
beforeEach(() => {
|
|
75
|
+
device.intranetInactivityDuration = 1234;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("should call 'checkNetworkReachability()'", () => {
|
|
79
|
+
assert.called(device.checkNetworkReachability);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should set isReachabilityChecked to true', () => {
|
|
83
|
+
assert.isTrue(device.isReachabilityChecked);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe('when the \'inNetworkInactivityDuration\' changes', () => {
|
|
88
|
+
beforeEach(() => {
|
|
89
|
+
device.inNetworkInactivityDuration = 1234;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("should call 'checkNetworkReachability()'", () => {
|
|
93
|
+
assert.called(device.checkNetworkReachability);
|
|
94
|
+
assert.isTrue(device.isReachabilityChecked);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('derived properties', () => {
|
|
101
|
+
describe('#registered', () => {
|
|
102
|
+
describe('when the device does not have a url', () => {
|
|
103
|
+
beforeEach(() => {
|
|
104
|
+
device.url = undefined;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should return false', () => {
|
|
108
|
+
assert.isFalse(device.registered);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('when the device does have a url', () => {
|
|
113
|
+
beforeEach(() => {
|
|
114
|
+
device.url = dto.url;
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should return true', () => {
|
|
118
|
+
assert.isTrue(device.registered);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe('#setLogoutTimer()', () => {
|
|
125
|
+
describe('when the duration parameter is not set', () => {
|
|
126
|
+
it('should not change the existing timer', () => {
|
|
127
|
+
const {logoutTimer} = device;
|
|
128
|
+
|
|
129
|
+
device.setLogoutTimer();
|
|
130
|
+
assert.equal(device.logoutTimer, logoutTimer);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('when the duration parameter is zero or negative', () => {
|
|
135
|
+
it('should not change the existing timer', () => {
|
|
136
|
+
const {logoutTimer} = device;
|
|
137
|
+
|
|
138
|
+
device.setLogoutTimer(-1);
|
|
139
|
+
assert.equal(device.logoutTimer, logoutTimer);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('when the duration is valid', () => {
|
|
144
|
+
beforeEach(() => {
|
|
145
|
+
device.resetLogoutTimer = sinon.spy();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("should create a 'change:lastUserActivityDate' listener", () => {
|
|
149
|
+
device.setLogoutTimer(60000);
|
|
150
|
+
device.trigger('change:lastUserActivityDate');
|
|
151
|
+
assert.called(device.resetLogoutTimer);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('should set the logout timer', () => {
|
|
155
|
+
const {logoutTimer} = device;
|
|
156
|
+
|
|
157
|
+
device.setLogoutTimer(60000);
|
|
158
|
+
assert.notEqual(device.logoutTimer, logoutTimer);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
describe('#serialize()', () => {
|
|
164
|
+
it('should serialize entitlement feature keys', () => {
|
|
165
|
+
assert.hasAllKeys(
|
|
166
|
+
device.serialize().features.entitlement,
|
|
167
|
+
Object.keys(dto.features.entitlement)
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should serialize user feature keys', () => {
|
|
172
|
+
assert.hasAllKeys(device.serialize().features.user, Object.keys(dto.features.user));
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
describe('#refresh()', () => {
|
|
177
|
+
let requestSpy;
|
|
178
|
+
|
|
179
|
+
const setup = () => {
|
|
180
|
+
sinon.stub(device, 'canRegister').callsFake(() => Promise.resolve());
|
|
181
|
+
sinon.stub(device, 'processRegistrationSuccess').callsFake(() => {});
|
|
182
|
+
requestSpy = sinon.spy(device, 'request');
|
|
183
|
+
device.config.defaults = {};
|
|
184
|
+
device.set('registered', true);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
it('If-None-Match header is added if etag is set', async () => {
|
|
188
|
+
setup();
|
|
189
|
+
|
|
190
|
+
device.set('etag', 'etag-value');
|
|
191
|
+
|
|
192
|
+
const result = device.refresh();
|
|
193
|
+
|
|
194
|
+
await result;
|
|
195
|
+
|
|
196
|
+
assert.deepEqual(requestSpy.args[0][0].headers, {
|
|
197
|
+
'If-None-Match': 'etag-value',
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('If-None-Match header is not added if etag is not set', async () => {
|
|
202
|
+
setup();
|
|
203
|
+
|
|
204
|
+
const result = device.refresh();
|
|
205
|
+
|
|
206
|
+
await result;
|
|
207
|
+
|
|
208
|
+
assert.deepEqual(requestSpy.args[0][0].headers, {});
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
describe('#processRegistrationSuccess()', () => {
|
|
213
|
+
const getClonedDTO = (overrides) => {
|
|
214
|
+
const clonedDTO = cloneDeep(dto);
|
|
215
|
+
|
|
216
|
+
clonedDTO.features = {
|
|
217
|
+
developer: [
|
|
218
|
+
{
|
|
219
|
+
key: '1',
|
|
220
|
+
type: 'boolean',
|
|
221
|
+
val: 'true',
|
|
222
|
+
value: true,
|
|
223
|
+
mutable: true,
|
|
224
|
+
lastModified: '2015-06-29T20:02:48.033Z',
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
entitlement: [
|
|
228
|
+
{
|
|
229
|
+
key: '2',
|
|
230
|
+
val: 'true',
|
|
231
|
+
value: true,
|
|
232
|
+
mutable: false,
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
user: [
|
|
236
|
+
{
|
|
237
|
+
key: '3',
|
|
238
|
+
val: 'true',
|
|
239
|
+
value: true,
|
|
240
|
+
mutable: true,
|
|
241
|
+
},
|
|
242
|
+
],
|
|
243
|
+
...overrides,
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
return clonedDTO;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const checkFeatureNotPresent = (type, key) => {
|
|
250
|
+
assert.isUndefined(device.features[type].get(key));
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const checkFeature = (type, key, expectedValue) => {
|
|
254
|
+
assert.equal(device.features[type].length, 1);
|
|
255
|
+
assert.deepEqual(device.features[type].get(key).get('value'), expectedValue);
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
it('features are set correctly if etag not in headers', () => {
|
|
259
|
+
const clonedDTO = getClonedDTO();
|
|
260
|
+
|
|
261
|
+
const response = {
|
|
262
|
+
body: {
|
|
263
|
+
...clonedDTO,
|
|
264
|
+
},
|
|
265
|
+
headers: {},
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
checkFeatureNotPresent('developer', '1');
|
|
269
|
+
checkFeatureNotPresent('entitlement', '2');
|
|
270
|
+
checkFeatureNotPresent('user', '3');
|
|
271
|
+
|
|
272
|
+
device.processRegistrationSuccess(response);
|
|
273
|
+
|
|
274
|
+
checkFeature('developer', '1', true);
|
|
275
|
+
checkFeature('entitlement', '2', true);
|
|
276
|
+
checkFeature('user', '3', true);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('if the etag matches only the user and entitlement features are updated', () => {
|
|
280
|
+
const clonedDTO = getClonedDTO();
|
|
281
|
+
|
|
282
|
+
device.set('etag', 'etag-value');
|
|
283
|
+
|
|
284
|
+
const response = {
|
|
285
|
+
body: {
|
|
286
|
+
...clonedDTO,
|
|
287
|
+
},
|
|
288
|
+
headers: {
|
|
289
|
+
etag: 'etag-value',
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
checkFeatureNotPresent('developer', '1');
|
|
294
|
+
checkFeatureNotPresent('entitlement', '2');
|
|
295
|
+
checkFeatureNotPresent('user', '3');
|
|
296
|
+
|
|
297
|
+
device.processRegistrationSuccess(response);
|
|
298
|
+
|
|
299
|
+
checkFeatureNotPresent('developer', '1');
|
|
300
|
+
checkFeature('entitlement', '2', true);
|
|
301
|
+
checkFeature('user', '3', true);
|
|
302
|
+
|
|
303
|
+
// confirm that the etag is unchanged
|
|
304
|
+
assert.equal(device.get('etag'), 'etag-value');
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('if the etag matches only the user and entitlement features are updated - check when developer features are set', () => {
|
|
308
|
+
const clonedDTO = getClonedDTO();
|
|
309
|
+
|
|
310
|
+
device.set('etag', 'etag-value');
|
|
311
|
+
|
|
312
|
+
const response = {
|
|
313
|
+
body: {
|
|
314
|
+
...clonedDTO,
|
|
315
|
+
},
|
|
316
|
+
headers: {
|
|
317
|
+
etag: 'etag-value',
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
checkFeatureNotPresent('developer', '1');
|
|
322
|
+
checkFeatureNotPresent('entitlement', '2');
|
|
323
|
+
checkFeatureNotPresent('user', '3');
|
|
324
|
+
|
|
325
|
+
device.processRegistrationSuccess(response);
|
|
326
|
+
|
|
327
|
+
checkFeatureNotPresent('developer', '1');
|
|
328
|
+
checkFeature('entitlement', '2', true);
|
|
329
|
+
checkFeature('user', '3', true);
|
|
330
|
+
|
|
331
|
+
// confirm that the etag is unchanged
|
|
332
|
+
assert.equal(device.get('etag'), 'etag-value');
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
it('if the etag does not match all the features are updated', () => {
|
|
336
|
+
const clonedDTO = getClonedDTO();
|
|
337
|
+
|
|
338
|
+
device.set('etag', 'etag-value');
|
|
339
|
+
|
|
340
|
+
const response = {
|
|
341
|
+
body: {
|
|
342
|
+
...clonedDTO,
|
|
343
|
+
},
|
|
344
|
+
headers: {
|
|
345
|
+
etag: 'different-etag-value',
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
checkFeatureNotPresent('developer', '1');
|
|
350
|
+
checkFeatureNotPresent('entitlement', '2');
|
|
351
|
+
checkFeatureNotPresent('user', '3');
|
|
352
|
+
|
|
353
|
+
device.processRegistrationSuccess(response);
|
|
354
|
+
|
|
355
|
+
checkFeature('developer', '1', true);
|
|
356
|
+
checkFeature('entitlement', '2', true);
|
|
357
|
+
checkFeature('user', '3', true);
|
|
358
|
+
|
|
359
|
+
// confirm that the new etag is set
|
|
360
|
+
assert.equal(device.get('etag'), 'different-etag-value');
|
|
361
|
+
|
|
362
|
+
const newClonedDTO = getClonedDTO({
|
|
363
|
+
developer: [
|
|
364
|
+
{
|
|
365
|
+
key: '1',
|
|
366
|
+
type: 'boolean',
|
|
367
|
+
val: 'false',
|
|
368
|
+
value: false,
|
|
369
|
+
mutable: true,
|
|
370
|
+
lastModified: '2015-06-29T20:02:48.033Z',
|
|
371
|
+
},
|
|
372
|
+
],
|
|
373
|
+
entitlement: [
|
|
374
|
+
{
|
|
375
|
+
key: '2',
|
|
376
|
+
val: 'false',
|
|
377
|
+
value: false,
|
|
378
|
+
mutable: false,
|
|
379
|
+
},
|
|
380
|
+
],
|
|
381
|
+
user: [
|
|
382
|
+
{
|
|
383
|
+
key: '3',
|
|
384
|
+
val: 'false',
|
|
385
|
+
value: false,
|
|
386
|
+
mutable: true,
|
|
387
|
+
},
|
|
388
|
+
],
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
const newResponse = {
|
|
392
|
+
body: {
|
|
393
|
+
...newClonedDTO,
|
|
394
|
+
},
|
|
395
|
+
headers: {
|
|
396
|
+
etag: 'different-etag-value',
|
|
397
|
+
},
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
device.processRegistrationSuccess(newResponse);
|
|
401
|
+
|
|
402
|
+
// only the entitlement and user features should have been changed to false
|
|
403
|
+
checkFeature('developer', '1', true);
|
|
404
|
+
checkFeature('entitlement', '2', false);
|
|
405
|
+
checkFeature('user', '3', false);
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
});
|