@webex/internal-plugin-metrics 3.0.0 → 3.1.0-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/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +90 -14
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +39 -29
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +10 -3
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/client-metrics-prelogin-batcher.js +32 -0
- package/dist/client-metrics-prelogin-batcher.js.map +1 -0
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +10 -25
- package/dist/metrics.js.map +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/new-metrics.js +5 -4
- package/dist/new-metrics.js.map +1 -1
- package/dist/prelogin-metrics-batcher.js +1 -1
- package/dist/prelogin-metrics-batcher.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +41 -8
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +10 -12
- package/dist/types/client-metrics-prelogin-batcher.d.ts +2 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/metrics.types.d.ts +3 -1
- package/package.json +13 -13
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +89 -13
- package/src/call-diagnostic/call-diagnostic-metrics.ts +14 -0
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +17 -3
- package/src/client-metrics-prelogin-batcher.ts +26 -0
- package/src/index.ts +2 -0
- package/src/metrics.js +8 -23
- package/src/metrics.types.ts +12 -1
- package/src/new-metrics.ts +2 -2
- package/src/prelogin-metrics-batcher.ts +1 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +18 -7
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +199 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +122 -24
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +28 -7
- package/test/unit/spec/client-metrics-prelogin-batcher.ts +54 -0
- package/test/unit/spec/metrics.js +9 -31
- package/test/unit/spec/new-metrics.ts +29 -31
- package/test/unit/spec/prelogin-metrics-batcher.ts +6 -3
|
@@ -41,11 +41,41 @@ describe('internal-plugin-metrics', () => {
|
|
|
41
41
|
assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), now.getTime());
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
it('should save latency correctly', () => {
|
|
44
|
+
it('should save latency correctly by default and overwrites', () => {
|
|
45
45
|
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
46
46
|
cdl.saveLatency('internal.client.pageJMT', 10);
|
|
47
47
|
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
48
48
|
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
|
|
49
|
+
cdl.saveLatency('internal.client.pageJMT', 20);
|
|
50
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
51
|
+
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should overwrite latency when accumulate is false', () => {
|
|
55
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
56
|
+
cdl.saveLatency('internal.client.pageJMT', 10, false);
|
|
57
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
58
|
+
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
|
|
59
|
+
cdl.saveLatency('internal.client.pageJMT', 20, false);
|
|
60
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
61
|
+
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should save latency correctly when accumulate is true', () => {
|
|
65
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
66
|
+
cdl.saveLatency('internal.client.pageJMT', 10, true);
|
|
67
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
68
|
+
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should save latency correctly when accumulate is true and there is existing value', () => {
|
|
72
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
73
|
+
cdl.saveLatency('internal.client.pageJMT', 10);
|
|
74
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
75
|
+
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
|
|
76
|
+
cdl.saveLatency('internal.client.pageJMT', 10, true);
|
|
77
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
78
|
+
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
|
|
49
79
|
});
|
|
50
80
|
|
|
51
81
|
it('should save only first timestamp correctly', () => {
|
|
@@ -78,8 +108,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
78
108
|
cdl.saveTimestamp({key: 'client.alert.displayed'});
|
|
79
109
|
cdl.saveTimestamp({key: 'client.alert.removed'});
|
|
80
110
|
assert.deepEqual(cdl.latencyTimestamps.size, 2);
|
|
111
|
+
cdl.saveLatency('internal.api.fetch.intelligence.models', 42);
|
|
112
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
113
|
+
|
|
81
114
|
cdl.clearTimestamps();
|
|
115
|
+
|
|
82
116
|
assert.deepEqual(cdl.latencyTimestamps.size, 0);
|
|
117
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
83
118
|
});
|
|
84
119
|
|
|
85
120
|
it('should calculate diff between timestamps correctly', () => {
|
|
@@ -111,6 +146,127 @@ describe('internal-plugin-metrics', () => {
|
|
|
111
146
|
assert.deepEqual(cdl.getMeetingInfoReqResp(), 10);
|
|
112
147
|
});
|
|
113
148
|
|
|
149
|
+
describe('measureLatency', () => {
|
|
150
|
+
let clock;
|
|
151
|
+
let saveLatencySpy;
|
|
152
|
+
|
|
153
|
+
beforeEach(() => {
|
|
154
|
+
clock = sinon.useFakeTimers();
|
|
155
|
+
|
|
156
|
+
saveLatencySpy = sinon.stub(cdl, 'saveLatency');
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
afterEach(() => {
|
|
160
|
+
clock.restore();
|
|
161
|
+
sinon.restore();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('checks measureLatency with accumulate false', async () => {
|
|
165
|
+
const key = 'internal.client.pageJMT';
|
|
166
|
+
const accumulate = false;
|
|
167
|
+
|
|
168
|
+
const callbackStub = sinon.stub().callsFake(() => {
|
|
169
|
+
clock.tick(50);
|
|
170
|
+
return Promise.resolve('test');
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// accumulate should be false by default
|
|
174
|
+
const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT');
|
|
175
|
+
|
|
176
|
+
const resolvedValue = await promise;
|
|
177
|
+
assert.deepEqual(resolvedValue, 'test');
|
|
178
|
+
assert.calledOnceWithExactly(callbackStub);
|
|
179
|
+
assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('checks measureLatency with accumulate true', async () => {
|
|
183
|
+
const key = 'internal.download.time';
|
|
184
|
+
const accumulate = true;
|
|
185
|
+
const callbackStub = sinon.stub().callsFake(() => {
|
|
186
|
+
clock.tick(20);
|
|
187
|
+
return Promise.resolve('test123');
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const promise = cdl.measureLatency(callbackStub, 'internal.download.time', accumulate);
|
|
191
|
+
|
|
192
|
+
const resolvedValue = await promise;
|
|
193
|
+
assert.deepEqual(resolvedValue, 'test123');
|
|
194
|
+
assert.calledOnceWithExactly(callbackStub);
|
|
195
|
+
assert.calledOnceWithExactly(saveLatencySpy, key, 20, accumulate);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('checks measureLatency when callBack rejects', async () => {
|
|
199
|
+
const key = 'internal.client.pageJMT';
|
|
200
|
+
const accumulate = false;
|
|
201
|
+
const error = new Error('some error');
|
|
202
|
+
const callbackStub = sinon.stub().callsFake(() => {
|
|
203
|
+
clock.tick(50);
|
|
204
|
+
return Promise.reject(error);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', accumulate);
|
|
208
|
+
|
|
209
|
+
const rejectedValue = await assert.isRejected(promise);
|
|
210
|
+
assert.deepEqual(rejectedValue, error);
|
|
211
|
+
assert.calledOnceWithExactly(callbackStub);
|
|
212
|
+
assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
describe('getRefreshCaptchaReqResp', () => {
|
|
217
|
+
it('returns undefined when no precomputed value available', () => {
|
|
218
|
+
assert.deepEqual(cdl.getRefreshCaptchaReqResp(), undefined);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('returns the correct value', () => {
|
|
222
|
+
cdl.saveLatency('internal.refresh.captcha.time', 123);
|
|
223
|
+
|
|
224
|
+
assert.deepEqual(cdl.getRefreshCaptchaReqResp(), 123);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('returns the correct whole number', () => {
|
|
228
|
+
cdl.saveLatency('internal.refresh.captcha.time', 321.44);
|
|
229
|
+
|
|
230
|
+
assert.deepEqual(cdl.getRefreshCaptchaReqResp(), 321);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
describe('getReachabilityClustersReqResp', () => {
|
|
235
|
+
it('returns undefined when no precomputed value available', () => {
|
|
236
|
+
assert.deepEqual(cdl.getReachabilityClustersReqResp(), undefined);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('returns the correct value', () => {
|
|
240
|
+
cdl.saveLatency('internal.get.cluster.time', 123);
|
|
241
|
+
|
|
242
|
+
assert.deepEqual(cdl.getReachabilityClustersReqResp(), 123);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('returns the correct whole number', () => {
|
|
246
|
+
cdl.saveLatency('internal.get.cluster.time', 321.44);
|
|
247
|
+
|
|
248
|
+
assert.deepEqual(cdl.getReachabilityClustersReqResp(), 321);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
describe('getExchangeCITokenJMT', () => {
|
|
253
|
+
it('returns undefined when no precomputed value available', () => {
|
|
254
|
+
assert.deepEqual(cdl.getExchangeCITokenJMT(), undefined);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('returns the correct value', () => {
|
|
258
|
+
cdl.saveLatency('internal.exchange.ci.token.time', 123);
|
|
259
|
+
|
|
260
|
+
assert.deepEqual(cdl.getExchangeCITokenJMT(), 123);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('returns the correct whole number', () => {
|
|
264
|
+
cdl.saveLatency('internal.exchange.ci.token.time', 321.44);
|
|
265
|
+
|
|
266
|
+
assert.deepEqual(cdl.getExchangeCITokenJMT(), 321);
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
114
270
|
describe('saveTimestamp', () => {
|
|
115
271
|
afterEach(() => {
|
|
116
272
|
sinon.restore();
|
|
@@ -512,9 +668,51 @@ describe('internal-plugin-metrics', () => {
|
|
|
512
668
|
assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
|
|
513
669
|
});
|
|
514
670
|
|
|
671
|
+
it('calculates getU2CTime correctly', () => {
|
|
672
|
+
it('returns undefined when no precomputed value available', () => {
|
|
673
|
+
assert.deepEqual(cdl.getU2CTime(), undefined);
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
it('returns the correct value', () => {
|
|
677
|
+
cdl.saveLatency('internal.get.u2c.time', 123);
|
|
678
|
+
|
|
679
|
+
assert.deepEqual(cdl.getU2CTime(), 123);
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
it('returns the correct whole number', () => {
|
|
683
|
+
cdl.saveLatency('internal.get.u2c.time', 321.44);
|
|
684
|
+
|
|
685
|
+
assert.deepEqual(cdl.getU2CTime(), 321);
|
|
686
|
+
});
|
|
687
|
+
});
|
|
688
|
+
|
|
515
689
|
it('calculates getDownloadTimeJMT correctly', () => {
|
|
516
690
|
cdl.saveLatency('internal.download.time', 1000);
|
|
517
691
|
assert.deepEqual(cdl.getDownloadTimeJMT(), 1000);
|
|
518
692
|
});
|
|
693
|
+
|
|
694
|
+
describe('getOtherAppApiReqResp', () => {
|
|
695
|
+
it('returns undefined when no precomputed value available', () => {
|
|
696
|
+
assert.deepEqual(cdl.getOtherAppApiReqResp(), undefined);
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
it('returns undefined if it is less than 0', () => {
|
|
700
|
+
cdl.saveLatency('internal.other.app.api.time', 0);
|
|
701
|
+
|
|
702
|
+
assert.deepEqual(cdl.getOtherAppApiReqResp(), undefined);
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
it('returns the correct value', () => {
|
|
706
|
+
cdl.saveLatency('internal.other.app.api.time', 123);
|
|
707
|
+
|
|
708
|
+
assert.deepEqual(cdl.getOtherAppApiReqResp(), 123);
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
it('returns the correct whole number', () => {
|
|
712
|
+
cdl.saveLatency('internal.other.app.api.time', 321.44);
|
|
713
|
+
|
|
714
|
+
assert.deepEqual(cdl.getOtherAppApiReqResp(), 321);
|
|
715
|
+
});
|
|
716
|
+
});
|
|
519
717
|
});
|
|
520
718
|
});
|
|
@@ -223,6 +223,43 @@ describe('internal-plugin-metrics', () => {
|
|
|
223
223
|
});
|
|
224
224
|
});
|
|
225
225
|
|
|
226
|
+
it('should build origin correctly with browserLaunchMethod', () => {
|
|
227
|
+
sinon.stub(CallDiagnosticUtils, 'anonymizeIPAddress').returns('1.1.1.1');
|
|
228
|
+
|
|
229
|
+
//@ts-ignore
|
|
230
|
+
const res = cd.getOrigin(
|
|
231
|
+
{
|
|
232
|
+
subClientType: 'WEB_APP',
|
|
233
|
+
clientType: 'TEAMS_CLIENT',
|
|
234
|
+
newEnvironment: 'test-new-env',
|
|
235
|
+
clientLaunchMethod: 'url-handler',
|
|
236
|
+
browserLaunchMethod: 'thinclient',
|
|
237
|
+
},
|
|
238
|
+
fakeMeeting.id
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
assert.deepEqual(res, {
|
|
242
|
+
clientInfo: {
|
|
243
|
+
browser: getBrowserName(),
|
|
244
|
+
browserVersion: getBrowserVersion(),
|
|
245
|
+
clientType: 'TEAMS_CLIENT',
|
|
246
|
+
clientVersion: 'webex-js-sdk/webex-version',
|
|
247
|
+
publicNetworkPrefix: '1.1.1.1',
|
|
248
|
+
localNetworkPrefix: '1.1.1.1',
|
|
249
|
+
os: getOSNameInternal(),
|
|
250
|
+
osVersion: getOSVersion(),
|
|
251
|
+
subClientType: 'WEB_APP',
|
|
252
|
+
clientLaunchMethod: 'url-handler',
|
|
253
|
+
browserLaunchMethod: 'thinclient',
|
|
254
|
+
},
|
|
255
|
+
environment: 'meeting_evn',
|
|
256
|
+
newEnvironment: 'test-new-env',
|
|
257
|
+
name: 'endpoint',
|
|
258
|
+
networkType: 'unknown',
|
|
259
|
+
userAgent,
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
|
|
226
263
|
it('should build origin correctly with no meeting', () => {
|
|
227
264
|
sinon.stub(CallDiagnosticUtils, 'anonymizeIPAddress').returns('1.1.1.1');
|
|
228
265
|
|
|
@@ -302,6 +339,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
302
339
|
|
|
303
340
|
describe('#getIdentifiers', () => {
|
|
304
341
|
it('should build identifiers correctly', () => {
|
|
342
|
+
webex.internal.device = {
|
|
343
|
+
...webex.internal.device,
|
|
344
|
+
config: {installationId: 'installationId'},
|
|
345
|
+
};
|
|
346
|
+
|
|
305
347
|
const res = cd.getIdentifiers({
|
|
306
348
|
mediaConnections: [
|
|
307
349
|
{mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
|
|
@@ -315,6 +357,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
315
357
|
locusId: 'url',
|
|
316
358
|
locusStartTime: 'lastActive',
|
|
317
359
|
locusUrl: 'locus/url',
|
|
360
|
+
machineId: 'installationId',
|
|
318
361
|
mediaAgentAlias: 'mediaAgentAlias',
|
|
319
362
|
mediaAgentGroupId: 'mediaAgentGroupId',
|
|
320
363
|
orgId: 'orgId',
|
|
@@ -498,7 +541,10 @@ describe('internal-plugin-metrics', () => {
|
|
|
498
541
|
it('should prepare diagnostic event successfully', () => {
|
|
499
542
|
const options = {meetingId: fakeMeeting.id};
|
|
500
543
|
const getOriginStub = sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
|
|
501
|
-
const clearEmptyKeysRecursivelyStub = sinon.stub(
|
|
544
|
+
const clearEmptyKeysRecursivelyStub = sinon.stub(
|
|
545
|
+
CallDiagnosticUtils,
|
|
546
|
+
'clearEmptyKeysRecursively'
|
|
547
|
+
);
|
|
502
548
|
|
|
503
549
|
const res = cd.prepareDiagnosticEvent(
|
|
504
550
|
{
|
|
@@ -715,7 +761,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
715
761
|
]);
|
|
716
762
|
});
|
|
717
763
|
|
|
718
|
-
it('should submit client event successfully with correlationId, webexConferenceIdStr and globalMeetingId',
|
|
764
|
+
it('should submit client event successfully with correlationId, webexConferenceIdStr and globalMeetingId', () => {
|
|
719
765
|
const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
|
|
720
766
|
const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
|
|
721
767
|
const generateClientEventErrorPayloadSpy = sinon.spy(cd, 'generateClientEventErrorPayload');
|
|
@@ -853,11 +899,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
853
899
|
options
|
|
854
900
|
);
|
|
855
901
|
assert.notCalled(submitToCallDiagnosticsSpy);
|
|
856
|
-
assert.calledWith(
|
|
902
|
+
assert.calledWith(
|
|
903
|
+
submitToCallDiagnosticsPreLoginSpy,
|
|
904
|
+
{
|
|
857
905
|
eventId: 'my-fake-id',
|
|
858
906
|
version: 1,
|
|
859
|
-
origin: {
|
|
860
|
-
originTime: {
|
|
907
|
+
origin: {origin: 'fake-origin'},
|
|
908
|
+
originTime: {triggered: now.toISOString(), sent: 'not_defined_yet'},
|
|
861
909
|
senderCountryCode: 'UK',
|
|
862
910
|
event: {
|
|
863
911
|
name: 'client.alert.displayed',
|
|
@@ -869,12 +917,14 @@ describe('internal-plugin-metrics', () => {
|
|
|
869
917
|
orgId: 'orgId',
|
|
870
918
|
locusUrl: 'locus-url',
|
|
871
919
|
webexConferenceIdStr: 'webexConferenceIdStr1',
|
|
872
|
-
globalMeetingId: 'globalMeetingId1'
|
|
920
|
+
globalMeetingId: 'globalMeetingId1',
|
|
873
921
|
},
|
|
874
|
-
eventData: {
|
|
875
|
-
loginType: 'login-ci'
|
|
922
|
+
eventData: {webClientDomain: 'whatever'},
|
|
923
|
+
loginType: 'login-ci',
|
|
876
924
|
},
|
|
877
|
-
|
|
925
|
+
},
|
|
926
|
+
options.preLoginId
|
|
927
|
+
);
|
|
878
928
|
});
|
|
879
929
|
|
|
880
930
|
it('should use meeting loginType if present and meetingId provided', () => {
|
|
@@ -1339,7 +1389,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1339
1389
|
});
|
|
1340
1390
|
});
|
|
1341
1391
|
|
|
1342
|
-
describe(
|
|
1392
|
+
describe('#submitToCallDiagnostics', () => {
|
|
1343
1393
|
it('should send request to call diagnostic batcher', () => {
|
|
1344
1394
|
const requestStub = sinon.stub();
|
|
1345
1395
|
//@ts-ignore
|
|
@@ -1348,7 +1398,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1348
1398
|
cd.submitToCallDiagnostics({event: 'test'});
|
|
1349
1399
|
assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
|
|
1350
1400
|
});
|
|
1351
|
-
})
|
|
1401
|
+
});
|
|
1352
1402
|
|
|
1353
1403
|
describe('#submitMQE', () => {
|
|
1354
1404
|
it('submits the event correctly', () => {
|
|
@@ -1402,6 +1452,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1402
1452
|
},
|
|
1403
1453
|
eventData: {webClientDomain: 'whatever'},
|
|
1404
1454
|
intervals: [{}],
|
|
1455
|
+
callingServiceType: 'LOCUS',
|
|
1405
1456
|
sourceMetadata: {
|
|
1406
1457
|
applicationSoftwareType: 'webex-js-sdk',
|
|
1407
1458
|
applicationSoftwareVersion: 'webex-version',
|
|
@@ -1437,6 +1488,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1437
1488
|
},
|
|
1438
1489
|
eventData: {webClientDomain: 'whatever'},
|
|
1439
1490
|
intervals: [{}],
|
|
1491
|
+
callingServiceType: 'LOCUS',
|
|
1440
1492
|
sourceMetadata: {
|
|
1441
1493
|
applicationSoftwareType: 'webex-js-sdk',
|
|
1442
1494
|
applicationSoftwareVersion: 'webex-version',
|
|
@@ -1470,6 +1522,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1470
1522
|
},
|
|
1471
1523
|
eventData: {webClientDomain: 'whatever'},
|
|
1472
1524
|
intervals: [{}],
|
|
1525
|
+
callingServiceType: 'LOCUS',
|
|
1473
1526
|
sourceMetadata: {
|
|
1474
1527
|
applicationSoftwareType: 'webex-js-sdk',
|
|
1475
1528
|
applicationSoftwareVersion: 'webex-version',
|
|
@@ -1801,6 +1854,27 @@ describe('internal-plugin-metrics', () => {
|
|
|
1801
1854
|
});
|
|
1802
1855
|
});
|
|
1803
1856
|
|
|
1857
|
+
it('should override custom properties for an unknown error', () => {
|
|
1858
|
+
const error = new Error('bad times');
|
|
1859
|
+
|
|
1860
|
+
(error as any).payloadOverrides = {
|
|
1861
|
+
shownToUser: true,
|
|
1862
|
+
category: 'expected',
|
|
1863
|
+
};
|
|
1864
|
+
|
|
1865
|
+
const res = cd.generateClientEventErrorPayload(error);
|
|
1866
|
+
assert.deepEqual(res, {
|
|
1867
|
+
category: 'expected',
|
|
1868
|
+
errorDescription: 'UnknownError',
|
|
1869
|
+
fatal: true,
|
|
1870
|
+
name: 'other',
|
|
1871
|
+
shownToUser: true,
|
|
1872
|
+
serviceErrorCode: 9999,
|
|
1873
|
+
errorCode: 9999,
|
|
1874
|
+
rawErrorMessage: 'bad times',
|
|
1875
|
+
});
|
|
1876
|
+
});
|
|
1877
|
+
|
|
1804
1878
|
it('should override custom properties for a NetworkOrCORSError', () => {
|
|
1805
1879
|
const error = new WebexHttpError.NetworkOrCORSError({
|
|
1806
1880
|
url: 'https://example.com',
|
|
@@ -1942,12 +2016,16 @@ describe('internal-plugin-metrics', () => {
|
|
|
1942
2016
|
|
|
1943
2017
|
describe('httpStatusCode', () => {
|
|
1944
2018
|
it('should include httpStatusCode for browser media errors', () => {
|
|
1945
|
-
const res = cd.generateClientEventErrorPayload({
|
|
2019
|
+
const res = cd.generateClientEventErrorPayload({
|
|
2020
|
+
name: 'PermissionDeniedError',
|
|
2021
|
+
message: 'bad times',
|
|
2022
|
+
statusCode: 401,
|
|
2023
|
+
});
|
|
1946
2024
|
assert.deepEqual(res, {
|
|
1947
2025
|
category: 'expected',
|
|
1948
2026
|
errorCode: 4032,
|
|
1949
2027
|
errorData: {
|
|
1950
|
-
errorName: 'PermissionDeniedError'
|
|
2028
|
+
errorName: 'PermissionDeniedError',
|
|
1951
2029
|
},
|
|
1952
2030
|
errorDescription: 'CameraPermissionDenied',
|
|
1953
2031
|
fatal: true,
|
|
@@ -1960,12 +2038,16 @@ describe('internal-plugin-metrics', () => {
|
|
|
1960
2038
|
});
|
|
1961
2039
|
|
|
1962
2040
|
it('should include httpStatusCode for SdpOfferCreationErrors', () => {
|
|
1963
|
-
const res = cd.generateClientEventErrorPayload({
|
|
2041
|
+
const res = cd.generateClientEventErrorPayload({
|
|
2042
|
+
name: 'SdpOfferCreationError',
|
|
2043
|
+
message: 'bad times',
|
|
2044
|
+
statusCode: 404,
|
|
2045
|
+
});
|
|
1964
2046
|
assert.deepEqual(res, {
|
|
1965
2047
|
category: 'media',
|
|
1966
2048
|
errorCode: 2050,
|
|
1967
2049
|
errorData: {
|
|
1968
|
-
errorName: 'SdpOfferCreationError'
|
|
2050
|
+
errorName: 'SdpOfferCreationError',
|
|
1969
2051
|
},
|
|
1970
2052
|
errorDescription: 'SdpOfferCreationError',
|
|
1971
2053
|
fatal: true,
|
|
@@ -1978,7 +2060,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
1978
2060
|
});
|
|
1979
2061
|
|
|
1980
2062
|
it('should include httpStatusCode for service error codes', () => {
|
|
1981
|
-
const res = cd.generateClientEventErrorPayload({
|
|
2063
|
+
const res = cd.generateClientEventErrorPayload({
|
|
2064
|
+
body: {errorCode: 58400},
|
|
2065
|
+
message: 'bad times',
|
|
2066
|
+
statusCode: 400,
|
|
2067
|
+
});
|
|
1982
2068
|
assert.deepEqual(res, {
|
|
1983
2069
|
category: 'signaling',
|
|
1984
2070
|
errorCode: 4100,
|
|
@@ -1993,7 +2079,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
1993
2079
|
});
|
|
1994
2080
|
|
|
1995
2081
|
it('should include httpStatusCode for locus service error codes', () => {
|
|
1996
|
-
const res = cd.generateClientEventErrorPayload({
|
|
2082
|
+
const res = cd.generateClientEventErrorPayload({
|
|
2083
|
+
body: {errorCode: 2403001},
|
|
2084
|
+
message: 'bad times',
|
|
2085
|
+
statusCode: 400,
|
|
2086
|
+
});
|
|
1997
2087
|
assert.deepEqual(res, {
|
|
1998
2088
|
category: 'expected',
|
|
1999
2089
|
errorCode: 3007,
|
|
@@ -2008,7 +2098,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
2008
2098
|
});
|
|
2009
2099
|
|
|
2010
2100
|
it('should include httpStatusCode for meetingInfo service error codes', () => {
|
|
2011
|
-
const res = cd.generateClientEventErrorPayload({
|
|
2101
|
+
const res = cd.generateClientEventErrorPayload({
|
|
2102
|
+
body: {data: {meetingInfo: {}}},
|
|
2103
|
+
message: 'bad times',
|
|
2104
|
+
statusCode: 400,
|
|
2105
|
+
});
|
|
2012
2106
|
assert.deepEqual(res, {
|
|
2013
2107
|
category: 'signaling',
|
|
2014
2108
|
errorCode: 4100,
|
|
@@ -2023,8 +2117,10 @@ describe('internal-plugin-metrics', () => {
|
|
|
2023
2117
|
});
|
|
2024
2118
|
|
|
2025
2119
|
it('should include httpStatusCode for network errors', () => {
|
|
2026
|
-
const error = new WebexHttpError.NetworkOrCORSError(
|
|
2027
|
-
|
|
2120
|
+
const error = new WebexHttpError.NetworkOrCORSError({
|
|
2121
|
+
statusCode: 400,
|
|
2122
|
+
options: {service: '', headers: {}},
|
|
2123
|
+
});
|
|
2028
2124
|
const res = cd.generateClientEventErrorPayload(error);
|
|
2029
2125
|
assert.deepEqual(res, {
|
|
2030
2126
|
category: 'network',
|
|
@@ -2040,8 +2136,10 @@ describe('internal-plugin-metrics', () => {
|
|
|
2040
2136
|
});
|
|
2041
2137
|
|
|
2042
2138
|
it('should include httpStatusCode for unauthorized errors', () => {
|
|
2043
|
-
const error = new WebexHttpError.Unauthorized(
|
|
2044
|
-
|
|
2139
|
+
const error = new WebexHttpError.Unauthorized({
|
|
2140
|
+
statusCode: 401,
|
|
2141
|
+
options: {service: '', headers: {}},
|
|
2142
|
+
});
|
|
2045
2143
|
const res = cd.generateClientEventErrorPayload(error);
|
|
2046
2144
|
assert.deepEqual(res, {
|
|
2047
2145
|
category: 'network',
|
|
@@ -2244,7 +2342,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
2244
2342
|
});
|
|
2245
2343
|
});
|
|
2246
2344
|
|
|
2247
|
-
describe(
|
|
2345
|
+
describe('#submitToCallDiagnosticsPreLogin', () => {
|
|
2248
2346
|
it('should send request to call diagnostic batcher and saves preLoginId', () => {
|
|
2249
2347
|
const requestStub = sinon.stub();
|
|
2250
2348
|
//@ts-ignore
|
|
@@ -2257,7 +2355,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
2257
2355
|
assert.calledWith(cd.preLoginMetricsBatcher.savePreLoginId, preLoginId);
|
|
2258
2356
|
assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
|
|
2259
2357
|
});
|
|
2260
|
-
})
|
|
2358
|
+
});
|
|
2261
2359
|
|
|
2262
2360
|
describe('#isServiceErrorExpected', () => {
|
|
2263
2361
|
it('returns true for code mapped to "expected"', () => {
|
|
@@ -301,17 +301,31 @@ describe('internal-plugin-metrics', () => {
|
|
|
301
301
|
|
|
302
302
|
[
|
|
303
303
|
['client.exit.app', {}],
|
|
304
|
-
[
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
304
|
+
[
|
|
305
|
+
'client.login.end',
|
|
306
|
+
{
|
|
307
|
+
joinTimes: {
|
|
308
|
+
otherAppApiReqResp: undefined,
|
|
309
|
+
exchangeCITokenJMT: undefined,
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
[
|
|
314
|
+
'client.webexapp.launched',
|
|
315
|
+
{
|
|
316
|
+
joinTimes: {
|
|
317
|
+
downloadTime: undefined,
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
],
|
|
309
321
|
[
|
|
310
322
|
'client.interstitial-window.launched',
|
|
311
323
|
{
|
|
312
324
|
joinTimes: {
|
|
313
325
|
clickToInterstitial: undefined,
|
|
314
326
|
meetingInfoReqResp: undefined,
|
|
327
|
+
refreshCaptchaServiceReqResp: undefined,
|
|
328
|
+
downloadIntelligenceModelsReqResp: undefined,
|
|
315
329
|
},
|
|
316
330
|
},
|
|
317
331
|
],
|
|
@@ -322,6 +336,8 @@ describe('internal-plugin-metrics', () => {
|
|
|
322
336
|
showInterstitialTime: undefined,
|
|
323
337
|
meetingInfoReqResp: undefined,
|
|
324
338
|
registerWDMDeviceJMT: undefined,
|
|
339
|
+
getU2CTime: undefined,
|
|
340
|
+
getReachabilityClustersReqResp: undefined,
|
|
325
341
|
},
|
|
326
342
|
},
|
|
327
343
|
],
|
|
@@ -332,13 +348,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
332
348
|
meetingInfoReqResp: undefined,
|
|
333
349
|
callInitJoinReq: undefined,
|
|
334
350
|
joinReqResp: undefined,
|
|
335
|
-
joinReqSentReceived: undefined,
|
|
336
351
|
pageJmt: undefined,
|
|
337
352
|
clickToInterstitial: undefined,
|
|
338
353
|
interstitialToJoinOK: undefined,
|
|
339
354
|
totalJmt: undefined,
|
|
340
355
|
clientJmt: undefined,
|
|
341
|
-
downloadTime: undefined
|
|
356
|
+
downloadTime: undefined,
|
|
342
357
|
},
|
|
343
358
|
},
|
|
344
359
|
],
|
|
@@ -600,6 +615,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
600
615
|
turnServerUsed: true,
|
|
601
616
|
errorCode: DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
|
|
602
617
|
},
|
|
618
|
+
{
|
|
619
|
+
signalingState: 'stable',
|
|
620
|
+
iceConnectionState: 'disconnected',
|
|
621
|
+
turnServerUsed: true,
|
|
622
|
+
errorCode: DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
|
|
623
|
+
},
|
|
603
624
|
{
|
|
604
625
|
signalingState: 'stable',
|
|
605
626
|
iceConnectionState: 'failed',
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {assert} from '@webex/test-helper-chai';
|
|
6
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
7
|
+
import sinon from 'sinon';
|
|
8
|
+
import Metrics from '@webex/internal-plugin-metrics';
|
|
9
|
+
import PreLoginMetricsBatcher from '@webex/internal-plugin-metrics';
|
|
10
|
+
import ClientMetricsPreloginBatcher from '@webex/internal-plugin-metrics';
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
describe('internal-plugin-metrics', () => {
|
|
14
|
+
describe('ClientMetricsPreloginBatcher', () => {
|
|
15
|
+
let webex;
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
//@ts-ignore
|
|
19
|
+
webex = new MockWebex({
|
|
20
|
+
children: {
|
|
21
|
+
metrics: Metrics,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
webex.request = (options) =>
|
|
26
|
+
Promise.resolve({body: {items: []}, waitForServiceTimeout: 15, options});
|
|
27
|
+
|
|
28
|
+
sinon.spy(webex, 'request');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
sinon.restore();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should be an instance of PreLoginMetricsBatcher', () => {
|
|
36
|
+
const clientMetricsPreloginBatcher = new ClientMetricsPreloginBatcher();
|
|
37
|
+
assert.instanceOf(clientMetricsPreloginBatcher, PreLoginMetricsBatcher);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
it('checks prepareItem', async () => {
|
|
42
|
+
const testItem = {id: 1};
|
|
43
|
+
const resultPromise = await webex.internal.metrics.clientMetricsPreloginBatcher.prepareItem(testItem);
|
|
44
|
+
assert.strictEqual(resultPromise, testItem);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('checks prepareRequest', async () => {
|
|
48
|
+
const testQueue = [];
|
|
49
|
+
|
|
50
|
+
const resultPromise = await webex.internal.metrics.clientMetricsPreloginBatcher.prepareRequest(testQueue);
|
|
51
|
+
assert.strictEqual(resultPromise, testQueue);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|