@webex/internal-plugin-metrics 3.0.0 → 3.1.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.
Files changed (39) hide show
  1. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +90 -14
  2. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics.js +38 -29
  4. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +10 -3
  6. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  7. package/dist/client-metrics-prelogin-batcher.js +32 -0
  8. package/dist/client-metrics-prelogin-batcher.js.map +1 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/metrics.js +10 -25
  11. package/dist/metrics.js.map +1 -1
  12. package/dist/metrics.types.js.map +1 -1
  13. package/dist/new-metrics.js +5 -4
  14. package/dist/new-metrics.js.map +1 -1
  15. package/dist/prelogin-metrics-batcher.js +1 -1
  16. package/dist/prelogin-metrics-batcher.js.map +1 -1
  17. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +41 -8
  18. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +10 -12
  19. package/dist/types/client-metrics-prelogin-batcher.d.ts +2 -0
  20. package/dist/types/index.d.ts +2 -2
  21. package/dist/types/metrics.types.d.ts +3 -1
  22. package/package.json +13 -13
  23. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +89 -13
  24. package/src/call-diagnostic/call-diagnostic-metrics.ts +13 -0
  25. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +17 -3
  26. package/src/client-metrics-prelogin-batcher.ts +26 -0
  27. package/src/index.ts +2 -0
  28. package/src/metrics.js +8 -23
  29. package/src/metrics.types.ts +12 -1
  30. package/src/new-metrics.ts +2 -2
  31. package/src/prelogin-metrics-batcher.ts +1 -1
  32. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +18 -7
  33. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +199 -1
  34. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +119 -24
  35. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +28 -7
  36. package/test/unit/spec/client-metrics-prelogin-batcher.ts +54 -0
  37. package/test/unit/spec/metrics.js +9 -31
  38. package/test/unit/spec/new-metrics.ts +29 -31
  39. 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(CallDiagnosticUtils, 'clearEmptyKeysRecursively');
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', async () => {
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(submitToCallDiagnosticsPreLoginSpy, {
902
+ assert.calledWith(
903
+ submitToCallDiagnosticsPreLoginSpy,
904
+ {
857
905
  eventId: 'my-fake-id',
858
906
  version: 1,
859
- origin: { origin: 'fake-origin' },
860
- originTime: { triggered: now.toISOString(), sent: 'not_defined_yet' },
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: { webClientDomain: 'whatever' },
875
- loginType: 'login-ci'
922
+ eventData: {webClientDomain: 'whatever'},
923
+ loginType: 'login-ci',
876
924
  },
877
- }, options.preLoginId);
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("#submitToCallDiagnostics", () => {
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', () => {
@@ -1801,6 +1851,27 @@ describe('internal-plugin-metrics', () => {
1801
1851
  });
1802
1852
  });
1803
1853
 
1854
+ it('should override custom properties for an unknown error', () => {
1855
+ const error = new Error('bad times');
1856
+
1857
+ (error as any).payloadOverrides = {
1858
+ shownToUser: true,
1859
+ category: 'expected',
1860
+ };
1861
+
1862
+ const res = cd.generateClientEventErrorPayload(error);
1863
+ assert.deepEqual(res, {
1864
+ category: 'expected',
1865
+ errorDescription: 'UnknownError',
1866
+ fatal: true,
1867
+ name: 'other',
1868
+ shownToUser: true,
1869
+ serviceErrorCode: 9999,
1870
+ errorCode: 9999,
1871
+ rawErrorMessage: 'bad times',
1872
+ });
1873
+ });
1874
+
1804
1875
  it('should override custom properties for a NetworkOrCORSError', () => {
1805
1876
  const error = new WebexHttpError.NetworkOrCORSError({
1806
1877
  url: 'https://example.com',
@@ -1942,12 +2013,16 @@ describe('internal-plugin-metrics', () => {
1942
2013
 
1943
2014
  describe('httpStatusCode', () => {
1944
2015
  it('should include httpStatusCode for browser media errors', () => {
1945
- const res = cd.generateClientEventErrorPayload({name: 'PermissionDeniedError', message: 'bad times', statusCode: 401});
2016
+ const res = cd.generateClientEventErrorPayload({
2017
+ name: 'PermissionDeniedError',
2018
+ message: 'bad times',
2019
+ statusCode: 401,
2020
+ });
1946
2021
  assert.deepEqual(res, {
1947
2022
  category: 'expected',
1948
2023
  errorCode: 4032,
1949
2024
  errorData: {
1950
- errorName: 'PermissionDeniedError'
2025
+ errorName: 'PermissionDeniedError',
1951
2026
  },
1952
2027
  errorDescription: 'CameraPermissionDenied',
1953
2028
  fatal: true,
@@ -1960,12 +2035,16 @@ describe('internal-plugin-metrics', () => {
1960
2035
  });
1961
2036
 
1962
2037
  it('should include httpStatusCode for SdpOfferCreationErrors', () => {
1963
- const res = cd.generateClientEventErrorPayload({name: 'SdpOfferCreationError', message: 'bad times', statusCode: 404});
2038
+ const res = cd.generateClientEventErrorPayload({
2039
+ name: 'SdpOfferCreationError',
2040
+ message: 'bad times',
2041
+ statusCode: 404,
2042
+ });
1964
2043
  assert.deepEqual(res, {
1965
2044
  category: 'media',
1966
2045
  errorCode: 2050,
1967
2046
  errorData: {
1968
- errorName: 'SdpOfferCreationError'
2047
+ errorName: 'SdpOfferCreationError',
1969
2048
  },
1970
2049
  errorDescription: 'SdpOfferCreationError',
1971
2050
  fatal: true,
@@ -1978,7 +2057,11 @@ describe('internal-plugin-metrics', () => {
1978
2057
  });
1979
2058
 
1980
2059
  it('should include httpStatusCode for service error codes', () => {
1981
- const res = cd.generateClientEventErrorPayload({body: {errorCode: 58400}, message: 'bad times', statusCode: 400});
2060
+ const res = cd.generateClientEventErrorPayload({
2061
+ body: {errorCode: 58400},
2062
+ message: 'bad times',
2063
+ statusCode: 400,
2064
+ });
1982
2065
  assert.deepEqual(res, {
1983
2066
  category: 'signaling',
1984
2067
  errorCode: 4100,
@@ -1993,7 +2076,11 @@ describe('internal-plugin-metrics', () => {
1993
2076
  });
1994
2077
 
1995
2078
  it('should include httpStatusCode for locus service error codes', () => {
1996
- const res = cd.generateClientEventErrorPayload({body: {errorCode: 2403001}, message: 'bad times', statusCode: 400});
2079
+ const res = cd.generateClientEventErrorPayload({
2080
+ body: {errorCode: 2403001},
2081
+ message: 'bad times',
2082
+ statusCode: 400,
2083
+ });
1997
2084
  assert.deepEqual(res, {
1998
2085
  category: 'expected',
1999
2086
  errorCode: 3007,
@@ -2008,7 +2095,11 @@ describe('internal-plugin-metrics', () => {
2008
2095
  });
2009
2096
 
2010
2097
  it('should include httpStatusCode for meetingInfo service error codes', () => {
2011
- const res = cd.generateClientEventErrorPayload({body: {data: {meetingInfo: {}}}, message: 'bad times', statusCode: 400});
2098
+ const res = cd.generateClientEventErrorPayload({
2099
+ body: {data: {meetingInfo: {}}},
2100
+ message: 'bad times',
2101
+ statusCode: 400,
2102
+ });
2012
2103
  assert.deepEqual(res, {
2013
2104
  category: 'signaling',
2014
2105
  errorCode: 4100,
@@ -2023,8 +2114,10 @@ describe('internal-plugin-metrics', () => {
2023
2114
  });
2024
2115
 
2025
2116
  it('should include httpStatusCode for network errors', () => {
2026
- const error = new WebexHttpError.NetworkOrCORSError(
2027
- {statusCode: 400, options: {service: '', headers: {}}});
2117
+ const error = new WebexHttpError.NetworkOrCORSError({
2118
+ statusCode: 400,
2119
+ options: {service: '', headers: {}},
2120
+ });
2028
2121
  const res = cd.generateClientEventErrorPayload(error);
2029
2122
  assert.deepEqual(res, {
2030
2123
  category: 'network',
@@ -2040,8 +2133,10 @@ describe('internal-plugin-metrics', () => {
2040
2133
  });
2041
2134
 
2042
2135
  it('should include httpStatusCode for unauthorized errors', () => {
2043
- const error = new WebexHttpError.Unauthorized(
2044
- {statusCode: 401, options: {service: '', headers: {}}});
2136
+ const error = new WebexHttpError.Unauthorized({
2137
+ statusCode: 401,
2138
+ options: {service: '', headers: {}},
2139
+ });
2045
2140
  const res = cd.generateClientEventErrorPayload(error);
2046
2141
  assert.deepEqual(res, {
2047
2142
  category: 'network',
@@ -2244,7 +2339,7 @@ describe('internal-plugin-metrics', () => {
2244
2339
  });
2245
2340
  });
2246
2341
 
2247
- describe("#submitToCallDiagnosticsPreLogin", () => {
2342
+ describe('#submitToCallDiagnosticsPreLogin', () => {
2248
2343
  it('should send request to call diagnostic batcher and saves preLoginId', () => {
2249
2344
  const requestStub = sinon.stub();
2250
2345
  //@ts-ignore
@@ -2257,7 +2352,7 @@ describe('internal-plugin-metrics', () => {
2257
2352
  assert.calledWith(cd.preLoginMetricsBatcher.savePreLoginId, preLoginId);
2258
2353
  assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
2259
2354
  });
2260
- })
2355
+ });
2261
2356
 
2262
2357
  describe('#isServiceErrorExpected', () => {
2263
2358
  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
- ['client.webexapp.launched', {
305
- joinTimes: {
306
- downloadTime: undefined,
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
+ });