@webex/internal-plugin-metrics 3.0.0 → 3.1.0-next.2

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 (40) 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 +60 -38
  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 +0 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/metrics.js +10 -25
  12. package/dist/metrics.js.map +1 -1
  13. package/dist/metrics.types.js.map +1 -1
  14. package/dist/new-metrics.js +5 -4
  15. package/dist/new-metrics.js.map +1 -1
  16. package/dist/prelogin-metrics-batcher.js +1 -1
  17. package/dist/prelogin-metrics-batcher.js.map +1 -1
  18. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +41 -8
  19. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +17 -12
  20. package/dist/types/client-metrics-prelogin-batcher.d.ts +2 -0
  21. package/dist/types/index.d.ts +2 -3
  22. package/dist/types/metrics.types.d.ts +3 -1
  23. package/package.json +12 -13
  24. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +89 -13
  25. package/src/call-diagnostic/call-diagnostic-metrics.ts +35 -8
  26. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +17 -3
  27. package/src/client-metrics-prelogin-batcher.ts +26 -0
  28. package/src/index.ts +2 -2
  29. package/src/metrics.js +8 -23
  30. package/src/metrics.types.ts +12 -1
  31. package/src/new-metrics.ts +2 -2
  32. package/src/prelogin-metrics-batcher.ts +1 -1
  33. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +25 -15
  34. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +199 -1
  35. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +155 -41
  36. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +28 -7
  37. package/test/unit/spec/client-metrics-prelogin-batcher.ts +54 -0
  38. package/test/unit/spec/metrics.js +9 -31
  39. package/test/unit/spec/new-metrics.ts +29 -31
  40. package/test/unit/spec/prelogin-metrics-batcher.ts +13 -10
@@ -114,6 +114,7 @@ describe('internal-plugin-metrics', () => {
114
114
  sinon.useFakeTimers(now.getTime());
115
115
  cd = new CallDiagnosticMetrics({}, {parent: webex});
116
116
  sinon.stub(uuid, 'v4').returns('my-fake-id');
117
+ cd.setDeviceInfo(webex.internal.device);
117
118
  });
118
119
 
119
120
  afterEach(() => {
@@ -223,6 +224,43 @@ describe('internal-plugin-metrics', () => {
223
224
  });
224
225
  });
225
226
 
227
+ it('should build origin correctly with browserLaunchMethod', () => {
228
+ sinon.stub(CallDiagnosticUtils, 'anonymizeIPAddress').returns('1.1.1.1');
229
+
230
+ //@ts-ignore
231
+ const res = cd.getOrigin(
232
+ {
233
+ subClientType: 'WEB_APP',
234
+ clientType: 'TEAMS_CLIENT',
235
+ newEnvironment: 'test-new-env',
236
+ clientLaunchMethod: 'url-handler',
237
+ browserLaunchMethod: 'thinclient',
238
+ },
239
+ fakeMeeting.id
240
+ );
241
+
242
+ assert.deepEqual(res, {
243
+ clientInfo: {
244
+ browser: getBrowserName(),
245
+ browserVersion: getBrowserVersion(),
246
+ clientType: 'TEAMS_CLIENT',
247
+ clientVersion: 'webex-js-sdk/webex-version',
248
+ publicNetworkPrefix: '1.1.1.1',
249
+ localNetworkPrefix: '1.1.1.1',
250
+ os: getOSNameInternal(),
251
+ osVersion: getOSVersion(),
252
+ subClientType: 'WEB_APP',
253
+ clientLaunchMethod: 'url-handler',
254
+ browserLaunchMethod: 'thinclient',
255
+ },
256
+ environment: 'meeting_evn',
257
+ newEnvironment: 'test-new-env',
258
+ name: 'endpoint',
259
+ networkType: 'unknown',
260
+ userAgent,
261
+ });
262
+ });
263
+
226
264
  it('should build origin correctly with no meeting', () => {
227
265
  sinon.stub(CallDiagnosticUtils, 'anonymizeIPAddress').returns('1.1.1.1');
228
266
 
@@ -302,6 +340,11 @@ describe('internal-plugin-metrics', () => {
302
340
 
303
341
  describe('#getIdentifiers', () => {
304
342
  it('should build identifiers correctly', () => {
343
+ cd.device = {
344
+ ...cd.device,
345
+ config: {installationId: 'installationId'},
346
+ };
347
+
305
348
  const res = cd.getIdentifiers({
306
349
  mediaConnections: [
307
350
  {mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
@@ -315,6 +358,7 @@ describe('internal-plugin-metrics', () => {
315
358
  locusId: 'url',
316
359
  locusStartTime: 'lastActive',
317
360
  locusUrl: 'locus/url',
361
+ machineId: 'installationId',
318
362
  mediaAgentAlias: 'mediaAgentAlias',
319
363
  mediaAgentGroupId: 'mediaAgentGroupId',
320
364
  orgId: 'orgId',
@@ -478,7 +522,7 @@ describe('internal-plugin-metrics', () => {
478
522
  });
479
523
 
480
524
  it('should build identifiers correctly given preLoginId and no device userId available', () => {
481
- webex.internal.device.userId = undefined;
525
+ cd.device.userId = undefined;
482
526
 
483
527
  const res = cd.getIdentifiers({
484
528
  correlationId: 'correlationId',
@@ -498,7 +542,10 @@ describe('internal-plugin-metrics', () => {
498
542
  it('should prepare diagnostic event successfully', () => {
499
543
  const options = {meetingId: fakeMeeting.id};
500
544
  const getOriginStub = sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
501
- const clearEmptyKeysRecursivelyStub = sinon.stub(CallDiagnosticUtils, 'clearEmptyKeysRecursively');
545
+ const clearEmptyKeysRecursivelyStub = sinon.stub(
546
+ CallDiagnosticUtils,
547
+ 'clearEmptyKeysRecursively'
548
+ );
502
549
 
503
550
  const res = cd.prepareDiagnosticEvent(
504
551
  {
@@ -663,7 +710,7 @@ describe('internal-plugin-metrics', () => {
663
710
  });
664
711
 
665
712
  const webexLoggerLogCalls = webex.logger.log.getCalls();
666
- assert.deepEqual(webexLoggerLogCalls[0].args, [
713
+ assert.deepEqual(webexLoggerLogCalls[1].args, [
667
714
  'call-diagnostic-events -> ',
668
715
  'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
669
716
  `name: client.alert.displayed`,
@@ -694,28 +741,28 @@ describe('internal-plugin-metrics', () => {
694
741
 
695
742
  const webexLoggerLogCalls = webex.logger.log.getCalls();
696
743
 
697
- assert.deepEqual(webexLoggerLogCalls.length, 3);
744
+ assert.deepEqual(webexLoggerLogCalls.length, 4);
698
745
 
699
- assert.deepEqual(webexLoggerLogCalls[0].args, [
746
+ assert.deepEqual(webexLoggerLogCalls[1].args, [
700
747
  'call-diagnostic-events -> ',
701
748
  'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
702
749
  `name: client.alert.displayed`,
703
750
  ]);
704
751
 
705
- assert.deepEqual(webexLoggerLogCalls[1].args, [
752
+ assert.deepEqual(webexLoggerLogCalls[2].args, [
706
753
  'call-diagnostic-events -> ',
707
754
  'CallDiagnosticMetrics: @createClientEventObjectInMeeting => collected browser data',
708
755
  '{"error":"unable to access window.navigator.userAgent"}',
709
756
  ]);
710
757
 
711
- assert.deepEqual(webexLoggerLogCalls[2].args, [
758
+ assert.deepEqual(webexLoggerLogCalls[3].args, [
712
759
  'call-diagnostic-events -> ',
713
760
  'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
714
761
  `name: client.alert.displayed`,
715
762
  ]);
716
763
  });
717
764
 
718
- it('should submit client event successfully with correlationId, webexConferenceIdStr and globalMeetingId', async () => {
765
+ it('should submit client event successfully with correlationId, webexConferenceIdStr and globalMeetingId', () => {
719
766
  const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
720
767
  const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
721
768
  const generateClientEventErrorPayloadSpy = sinon.spy(cd, 'generateClientEventErrorPayload');
@@ -794,7 +841,7 @@ describe('internal-plugin-metrics', () => {
794
841
 
795
842
  const webexLoggerLogCalls = webex.logger.log.getCalls();
796
843
 
797
- assert.deepEqual(webexLoggerLogCalls[0].args, [
844
+ assert.deepEqual(webexLoggerLogCalls[1].args, [
798
845
  'call-diagnostic-events -> ',
799
846
  'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
800
847
  `name: client.alert.displayed`,
@@ -802,7 +849,7 @@ describe('internal-plugin-metrics', () => {
802
849
  });
803
850
 
804
851
  it('should submit client event successfully with preLoginId', () => {
805
- webex.internal.device.userId = undefined;
852
+ cd.device.userId = undefined;
806
853
 
807
854
  const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
808
855
  const submitToCallDiagnosticsPreLoginSpy = sinon.spy(cd, 'submitToCallDiagnosticsPreLogin');
@@ -853,11 +900,13 @@ describe('internal-plugin-metrics', () => {
853
900
  options
854
901
  );
855
902
  assert.notCalled(submitToCallDiagnosticsSpy);
856
- assert.calledWith(submitToCallDiagnosticsPreLoginSpy, {
903
+ assert.calledWith(
904
+ submitToCallDiagnosticsPreLoginSpy,
905
+ {
857
906
  eventId: 'my-fake-id',
858
907
  version: 1,
859
- origin: { origin: 'fake-origin' },
860
- originTime: { triggered: now.toISOString(), sent: 'not_defined_yet' },
908
+ origin: {origin: 'fake-origin'},
909
+ originTime: {triggered: now.toISOString(), sent: 'not_defined_yet'},
861
910
  senderCountryCode: 'UK',
862
911
  event: {
863
912
  name: 'client.alert.displayed',
@@ -869,12 +918,14 @@ describe('internal-plugin-metrics', () => {
869
918
  orgId: 'orgId',
870
919
  locusUrl: 'locus-url',
871
920
  webexConferenceIdStr: 'webexConferenceIdStr1',
872
- globalMeetingId: 'globalMeetingId1'
921
+ globalMeetingId: 'globalMeetingId1',
873
922
  },
874
- eventData: { webClientDomain: 'whatever' },
875
- loginType: 'login-ci'
923
+ eventData: {webClientDomain: 'whatever'},
924
+ loginType: 'login-ci',
876
925
  },
877
- }, options.preLoginId);
926
+ },
927
+ options.preLoginId
928
+ );
878
929
  });
879
930
 
880
931
  it('should use meeting loginType if present and meetingId provided', () => {
@@ -997,13 +1048,13 @@ describe('internal-plugin-metrics', () => {
997
1048
  });
998
1049
 
999
1050
  const webexLoggerLogCalls = webex.logger.log.getCalls();
1000
- assert.deepEqual(webexLoggerLogCalls[0].args, [
1051
+ assert.deepEqual(webexLoggerLogCalls[1].args, [
1001
1052
  'call-diagnostic-events -> ',
1002
1053
  'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
1003
1054
  `name: client.alert.displayed`,
1004
1055
  ]);
1005
1056
 
1006
- assert.deepEqual(webexLoggerLogCalls[1].args, [
1057
+ assert.deepEqual(webexLoggerLogCalls[2].args, [
1007
1058
  'call-diagnostic-events -> ',
1008
1059
  'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
1009
1060
  `generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"expected","errorCode":4029,"serviceErrorCode":2409005,"errorDescription":"StartRecordingFailed"}`,
@@ -1073,13 +1124,13 @@ describe('internal-plugin-metrics', () => {
1073
1124
  });
1074
1125
 
1075
1126
  const webexLoggerLogCalls = webex.logger.log.getCalls();
1076
- assert.deepEqual(webexLoggerLogCalls[0].args, [
1127
+ assert.deepEqual(webexLoggerLogCalls[1].args, [
1077
1128
  'call-diagnostic-events -> ',
1078
1129
  'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
1079
1130
  `name: client.alert.displayed`,
1080
1131
  ]);
1081
1132
 
1082
- assert.deepEqual(webexLoggerLogCalls[1].args, [
1133
+ assert.deepEqual(webexLoggerLogCalls[2].args, [
1083
1134
  'call-diagnostic-events -> ',
1084
1135
  'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
1085
1136
  `generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"other","errorCode":9999,"serviceErrorCode":9999,"rawErrorMessage":"bad times","errorDescription":"UnknownError"}`,
@@ -1142,13 +1193,13 @@ describe('internal-plugin-metrics', () => {
1142
1193
 
1143
1194
  const webexLoggerLogCalls = webex.logger.log.getCalls();
1144
1195
 
1145
- assert.deepEqual(webexLoggerLogCalls[0].args, [
1196
+ assert.deepEqual(webexLoggerLogCalls[1].args, [
1146
1197
  'call-diagnostic-events -> ',
1147
1198
  'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
1148
1199
  `name: client.alert.displayed`,
1149
1200
  ]);
1150
1201
 
1151
- assert.deepEqual(webexLoggerLogCalls[1].args, [
1202
+ assert.deepEqual(webexLoggerLogCalls[2].args, [
1152
1203
  'call-diagnostic-events -> ',
1153
1204
  'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
1154
1205
  `generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"other","errorCode":9999,"serviceErrorCode":9999,"rawErrorMessage":"bad times","errorDescription":"UnknownError"}`,
@@ -1215,13 +1266,13 @@ describe('internal-plugin-metrics', () => {
1215
1266
 
1216
1267
  const webexLoggerLogCalls = webex.logger.log.getCalls();
1217
1268
 
1218
- assert.deepEqual(webexLoggerLogCalls[0].args, [
1269
+ assert.deepEqual(webexLoggerLogCalls[1].args, [
1219
1270
  'call-diagnostic-events -> ',
1220
1271
  'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
1221
1272
  `name: client.alert.displayed`,
1222
1273
  ]);
1223
1274
 
1224
- assert.deepEqual(webexLoggerLogCalls[1].args, [
1275
+ assert.deepEqual(webexLoggerLogCalls[2].args, [
1225
1276
  'call-diagnostic-events -> ',
1226
1277
  'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
1227
1278
  `generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"expected","errorCode":4029,"serviceErrorCode":2409005,"errorDescription":"StartRecordingFailed"}`,
@@ -1339,7 +1390,7 @@ describe('internal-plugin-metrics', () => {
1339
1390
  });
1340
1391
  });
1341
1392
 
1342
- describe("#submitToCallDiagnostics", () => {
1393
+ describe('#submitToCallDiagnostics', () => {
1343
1394
  it('should send request to call diagnostic batcher', () => {
1344
1395
  const requestStub = sinon.stub();
1345
1396
  //@ts-ignore
@@ -1348,7 +1399,7 @@ describe('internal-plugin-metrics', () => {
1348
1399
  cd.submitToCallDiagnostics({event: 'test'});
1349
1400
  assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
1350
1401
  });
1351
- })
1402
+ });
1352
1403
 
1353
1404
  describe('#submitMQE', () => {
1354
1405
  it('submits the event correctly', () => {
@@ -1402,6 +1453,7 @@ describe('internal-plugin-metrics', () => {
1402
1453
  },
1403
1454
  eventData: {webClientDomain: 'whatever'},
1404
1455
  intervals: [{}],
1456
+ callingServiceType: 'LOCUS',
1405
1457
  sourceMetadata: {
1406
1458
  applicationSoftwareType: 'webex-js-sdk',
1407
1459
  applicationSoftwareVersion: 'webex-version',
@@ -1437,6 +1489,7 @@ describe('internal-plugin-metrics', () => {
1437
1489
  },
1438
1490
  eventData: {webClientDomain: 'whatever'},
1439
1491
  intervals: [{}],
1492
+ callingServiceType: 'LOCUS',
1440
1493
  sourceMetadata: {
1441
1494
  applicationSoftwareType: 'webex-js-sdk',
1442
1495
  applicationSoftwareVersion: 'webex-version',
@@ -1470,6 +1523,7 @@ describe('internal-plugin-metrics', () => {
1470
1523
  },
1471
1524
  eventData: {webClientDomain: 'whatever'},
1472
1525
  intervals: [{}],
1526
+ callingServiceType: 'LOCUS',
1473
1527
  sourceMetadata: {
1474
1528
  applicationSoftwareType: 'webex-js-sdk',
1475
1529
  applicationSoftwareVersion: 'webex-version',
@@ -1801,6 +1855,27 @@ describe('internal-plugin-metrics', () => {
1801
1855
  });
1802
1856
  });
1803
1857
 
1858
+ it('should override custom properties for an unknown error', () => {
1859
+ const error = new Error('bad times');
1860
+
1861
+ (error as any).payloadOverrides = {
1862
+ shownToUser: true,
1863
+ category: 'expected',
1864
+ };
1865
+
1866
+ const res = cd.generateClientEventErrorPayload(error);
1867
+ assert.deepEqual(res, {
1868
+ category: 'expected',
1869
+ errorDescription: 'UnknownError',
1870
+ fatal: true,
1871
+ name: 'other',
1872
+ shownToUser: true,
1873
+ serviceErrorCode: 9999,
1874
+ errorCode: 9999,
1875
+ rawErrorMessage: 'bad times',
1876
+ });
1877
+ });
1878
+
1804
1879
  it('should override custom properties for a NetworkOrCORSError', () => {
1805
1880
  const error = new WebexHttpError.NetworkOrCORSError({
1806
1881
  url: 'https://example.com',
@@ -1942,12 +2017,16 @@ describe('internal-plugin-metrics', () => {
1942
2017
 
1943
2018
  describe('httpStatusCode', () => {
1944
2019
  it('should include httpStatusCode for browser media errors', () => {
1945
- const res = cd.generateClientEventErrorPayload({name: 'PermissionDeniedError', message: 'bad times', statusCode: 401});
2020
+ const res = cd.generateClientEventErrorPayload({
2021
+ name: 'PermissionDeniedError',
2022
+ message: 'bad times',
2023
+ statusCode: 401,
2024
+ });
1946
2025
  assert.deepEqual(res, {
1947
2026
  category: 'expected',
1948
2027
  errorCode: 4032,
1949
2028
  errorData: {
1950
- errorName: 'PermissionDeniedError'
2029
+ errorName: 'PermissionDeniedError',
1951
2030
  },
1952
2031
  errorDescription: 'CameraPermissionDenied',
1953
2032
  fatal: true,
@@ -1960,12 +2039,16 @@ describe('internal-plugin-metrics', () => {
1960
2039
  });
1961
2040
 
1962
2041
  it('should include httpStatusCode for SdpOfferCreationErrors', () => {
1963
- const res = cd.generateClientEventErrorPayload({name: 'SdpOfferCreationError', message: 'bad times', statusCode: 404});
2042
+ const res = cd.generateClientEventErrorPayload({
2043
+ name: 'SdpOfferCreationError',
2044
+ message: 'bad times',
2045
+ statusCode: 404,
2046
+ });
1964
2047
  assert.deepEqual(res, {
1965
2048
  category: 'media',
1966
2049
  errorCode: 2050,
1967
2050
  errorData: {
1968
- errorName: 'SdpOfferCreationError'
2051
+ errorName: 'SdpOfferCreationError',
1969
2052
  },
1970
2053
  errorDescription: 'SdpOfferCreationError',
1971
2054
  fatal: true,
@@ -1978,7 +2061,11 @@ describe('internal-plugin-metrics', () => {
1978
2061
  });
1979
2062
 
1980
2063
  it('should include httpStatusCode for service error codes', () => {
1981
- const res = cd.generateClientEventErrorPayload({body: {errorCode: 58400}, message: 'bad times', statusCode: 400});
2064
+ const res = cd.generateClientEventErrorPayload({
2065
+ body: {errorCode: 58400},
2066
+ message: 'bad times',
2067
+ statusCode: 400,
2068
+ });
1982
2069
  assert.deepEqual(res, {
1983
2070
  category: 'signaling',
1984
2071
  errorCode: 4100,
@@ -1993,7 +2080,11 @@ describe('internal-plugin-metrics', () => {
1993
2080
  });
1994
2081
 
1995
2082
  it('should include httpStatusCode for locus service error codes', () => {
1996
- const res = cd.generateClientEventErrorPayload({body: {errorCode: 2403001}, message: 'bad times', statusCode: 400});
2083
+ const res = cd.generateClientEventErrorPayload({
2084
+ body: {errorCode: 2403001},
2085
+ message: 'bad times',
2086
+ statusCode: 400,
2087
+ });
1997
2088
  assert.deepEqual(res, {
1998
2089
  category: 'expected',
1999
2090
  errorCode: 3007,
@@ -2008,7 +2099,11 @@ describe('internal-plugin-metrics', () => {
2008
2099
  });
2009
2100
 
2010
2101
  it('should include httpStatusCode for meetingInfo service error codes', () => {
2011
- const res = cd.generateClientEventErrorPayload({body: {data: {meetingInfo: {}}}, message: 'bad times', statusCode: 400});
2102
+ const res = cd.generateClientEventErrorPayload({
2103
+ body: {data: {meetingInfo: {}}},
2104
+ message: 'bad times',
2105
+ statusCode: 400,
2106
+ });
2012
2107
  assert.deepEqual(res, {
2013
2108
  category: 'signaling',
2014
2109
  errorCode: 4100,
@@ -2023,8 +2118,10 @@ describe('internal-plugin-metrics', () => {
2023
2118
  });
2024
2119
 
2025
2120
  it('should include httpStatusCode for network errors', () => {
2026
- const error = new WebexHttpError.NetworkOrCORSError(
2027
- {statusCode: 400, options: {service: '', headers: {}}});
2121
+ const error = new WebexHttpError.NetworkOrCORSError({
2122
+ statusCode: 400,
2123
+ options: {service: '', headers: {}},
2124
+ });
2028
2125
  const res = cd.generateClientEventErrorPayload(error);
2029
2126
  assert.deepEqual(res, {
2030
2127
  category: 'network',
@@ -2040,8 +2137,10 @@ describe('internal-plugin-metrics', () => {
2040
2137
  });
2041
2138
 
2042
2139
  it('should include httpStatusCode for unauthorized errors', () => {
2043
- const error = new WebexHttpError.Unauthorized(
2044
- {statusCode: 401, options: {service: '', headers: {}}});
2140
+ const error = new WebexHttpError.Unauthorized({
2141
+ statusCode: 401,
2142
+ options: {service: '', headers: {}},
2143
+ });
2045
2144
  const res = cd.generateClientEventErrorPayload(error);
2046
2145
  assert.deepEqual(res, {
2047
2146
  category: 'network',
@@ -2235,7 +2334,7 @@ describe('internal-plugin-metrics', () => {
2235
2334
 
2236
2335
  const webexLoggerLogCalls = webex.logger.log.getCalls();
2237
2336
 
2238
- assert.deepEqual(webexLoggerLogCalls[0].args, [
2337
+ assert.deepEqual(webexLoggerLogCalls[1].args, [
2239
2338
  'call-diagnostic-events -> ',
2240
2339
  'CallDiagnosticMetrics: @buildClientEventFetchRequestOptions. Building request options object for fetch()...',
2241
2340
  `name: client.exit.app`,
@@ -2244,7 +2343,7 @@ describe('internal-plugin-metrics', () => {
2244
2343
  });
2245
2344
  });
2246
2345
 
2247
- describe("#submitToCallDiagnosticsPreLogin", () => {
2346
+ describe('#submitToCallDiagnosticsPreLogin', () => {
2248
2347
  it('should send request to call diagnostic batcher and saves preLoginId', () => {
2249
2348
  const requestStub = sinon.stub();
2250
2349
  //@ts-ignore
@@ -2257,7 +2356,7 @@ describe('internal-plugin-metrics', () => {
2257
2356
  assert.calledWith(cd.preLoginMetricsBatcher.savePreLoginId, preLoginId);
2258
2357
  assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
2259
2358
  });
2260
- })
2359
+ });
2261
2360
 
2262
2361
  describe('#isServiceErrorExpected', () => {
2263
2362
  it('returns true for code mapped to "expected"', () => {
@@ -2272,5 +2371,20 @@ describe('internal-plugin-metrics', () => {
2272
2371
  assert.isFalse(cd.isServiceErrorExpected(999999));
2273
2372
  });
2274
2373
  });
2374
+
2375
+ describe('#setDeviceInfo', () => {
2376
+ // The method is called in beforeEach itself. We are just testing it here
2377
+ it('sets the received deviceInfo to call-diagnostics', () => {
2378
+ const webexLoggerLogCalls = webex.logger.log.getCalls();
2379
+ const device = { userId: 'userId', url: 'deviceUrl', orgId: 'orgId' };
2380
+
2381
+ assert.deepEqual(webexLoggerLogCalls[0].args, [
2382
+ 'CallDiagnosticMetrics: @setDeviceInfo called',
2383
+ device
2384
+ ]);
2385
+
2386
+ assert.deepEqual(cd.device, device);
2387
+ });
2388
+ });
2275
2389
  });
2276
2390
  });
@@ -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
+ });
@@ -104,9 +104,15 @@ describe('plugin-metrics', () => {
104
104
  };
105
105
  webex.config.metrics.type = ['operational'];
106
106
  webex.config.metrics.appType = 'sdk';
107
+ webex.meetings = {
108
+ config: {
109
+ metrics: {
110
+ clientVersion: '43.0.105'
111
+ }
112
+ }
113
+ }
107
114
 
108
115
  sinon.spy(webex, 'request');
109
- sinon.spy(metrics, 'postPreLoginMetric');
110
116
  sinon.spy(metrics, 'aliasUser');
111
117
  });
112
118
 
@@ -180,6 +186,7 @@ describe('plugin-metrics', () => {
180
186
  },
181
187
  metricName: 'test',
182
188
  tags: {
189
+ appVersion: '43.0.105',
183
190
  browser: '',
184
191
  domain: 'whatever',
185
192
  os: 'other',
@@ -199,7 +206,7 @@ describe('plugin-metrics', () => {
199
206
 
200
207
  describe('#submitClientMetrics()', () => {
201
208
  describe('before login', () => {
202
- it('posts pre-login metric', () => {
209
+ it('clientMetricsPreloginBatcher pre-login metric', () => {
203
210
  const date = clock.now;
204
211
  const promise = metrics.submitClientMetrics(eventName, mockPayload, preLoginId);
205
212
 
@@ -207,8 +214,6 @@ describe('plugin-metrics', () => {
207
214
  .then(() => clock.tick(config.metrics.batcherWait))
208
215
  .then(() => promise)
209
216
  .then(() => {
210
- assert.called(metrics.postPreLoginMetric);
211
- assert.calledOnce(webex.credentials.getClientToken);
212
217
  assert.calledOnce(webex.request);
213
218
  const req = webex.request.args[0][0];
214
219
  const metric = req.body.metrics[0];
@@ -296,33 +301,6 @@ describe('plugin-metrics', () => {
296
301
  });
297
302
  });
298
303
 
299
- describe('#postPreLoginMetric()', () => {
300
- it('returns an HttpResponse object', () => {
301
- const promise = metrics.postPreLoginMetric(preLoginProps, preLoginId);
302
-
303
- return promiseTick(50)
304
- .then(() => clock.tick(config.metrics.batcherWait))
305
- .then(() => promise)
306
- .then(() => {
307
- assert.calledOnce(webex.request);
308
- const req = webex.request.args[0][0];
309
- const metric = req.body.metrics[0];
310
- const {headers} = req;
311
-
312
- assert.property(headers, 'x-prelogin-userid');
313
- assert.property(metric, 'metricName');
314
- assert.property(metric, 'tags');
315
- assert.property(metric, 'fields');
316
- assert.property(metric, 'timestamp');
317
-
318
- assert.equal(metric.timestamp, transformedProps.timestamp);
319
- assert.equal(metric.metricName, eventName);
320
- assert.equal(metric.tags.testTag, 'tag value');
321
- assert.equal(metric.fields.testField, 123);
322
- });
323
- });
324
- });
325
-
326
304
  describe('#aliasUser()', () => {
327
305
  it('returns an HttpResponse object', () =>
328
306
  metrics.aliasUser(preLoginId).then(() => {