@webex/internal-plugin-metrics 3.5.0 → 3.6.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 (53) hide show
  1. package/dist/business-metrics.js +119 -9
  2. package/dist/business-metrics.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +1 -1
  4. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics.js +26 -7
  6. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  7. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +7 -2
  8. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  9. package/dist/call-diagnostic/config.js +13 -3
  10. package/dist/call-diagnostic/config.js.map +1 -1
  11. package/dist/index.js +7 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/metrics.js +1 -1
  14. package/dist/metrics.types.js.map +1 -1
  15. package/dist/new-metrics.js +5 -2
  16. package/dist/new-metrics.js.map +1 -1
  17. package/dist/rtcMetrics/constants.js +11 -0
  18. package/dist/rtcMetrics/constants.js.map +1 -0
  19. package/dist/rtcMetrics/index.js +223 -0
  20. package/dist/rtcMetrics/index.js.map +1 -0
  21. package/dist/types/business-metrics.d.ts +36 -4
  22. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +4 -1
  23. package/dist/types/call-diagnostic/config.d.ts +3 -0
  24. package/dist/types/index.d.ts +2 -1
  25. package/dist/types/metrics.types.d.ts +19 -2
  26. package/dist/types/new-metrics.d.ts +5 -3
  27. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  28. package/dist/types/rtcMetrics/index.d.ts +80 -0
  29. package/package.json +12 -12
  30. package/src/business-metrics.ts +97 -5
  31. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +1 -1
  32. package/src/call-diagnostic/call-diagnostic-metrics.ts +26 -7
  33. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +11 -5
  34. package/src/call-diagnostic/config.ts +12 -0
  35. package/src/index.ts +2 -0
  36. package/src/metrics.types.ts +98 -23
  37. package/src/new-metrics.ts +12 -2
  38. package/src/rtcMetrics/constants.ts +3 -0
  39. package/src/rtcMetrics/index.ts +205 -0
  40. package/test/unit/spec/business/business-metrics.ts +69 -2
  41. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +2 -1
  42. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +4 -6
  43. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +489 -16
  44. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +7 -3
  45. package/test/unit/spec/new-metrics.ts +18 -3
  46. package/test/unit/spec/prelogin-metrics-batcher.ts +3 -1
  47. package/test/unit/spec/rtcMetrics/index.ts +196 -0
  48. package/dist/behavioral/behavioral-metrics.js +0 -199
  49. package/dist/behavioral/behavioral-metrics.js.map +0 -1
  50. package/dist/behavioral/config.js +0 -11
  51. package/dist/behavioral/config.js.map +0 -1
  52. package/dist/types/behavioral/behavioral-metrics.d.ts +0 -63
  53. package/dist/types/behavioral/config.d.ts +0 -1
@@ -1,7 +1,9 @@
1
1
  import sinon from 'sinon';
2
+ import bowser from 'bowser';
2
3
  import {assert} from '@webex/test-helper-chai';
3
4
  import {WebexHttpError} from '@webex/webex-core';
4
5
  import {BrowserDetection} from '@webex/common';
6
+ import window from 'global/window';
5
7
  import {
6
8
  CallDiagnosticLatencies,
7
9
  CallDiagnosticMetrics,
@@ -40,21 +42,26 @@ describe('internal-plugin-metrics', () => {
40
42
  },
41
43
  meetingInfo: {},
42
44
  getCurUserType: () => 'host',
43
- statsAnalyzer: {
44
- getLocalIpAddress: () => '192.168.1.90',
45
- },
46
45
  };
47
46
 
48
47
  const fakeMeeting2 = {
49
48
  ...fakeMeeting,
50
49
  id: '2',
51
50
  correlationId: 'correlationId2',
52
- callStateForMetrics: {loginType: 'fakeLoginType'},
51
+ callStateForMetrics: {loginType: 'fakeLoginType', joinFlowVersion: 'Other'},
52
+ };
53
+
54
+ const fakeMeeting3 = {
55
+ ...fakeMeeting,
56
+ id: '3',
57
+ correlationId: 'correlationId3',
58
+ sessionCorrelationId: 'sessionCorrelationId3',
53
59
  };
54
60
 
55
61
  const fakeMeetings = {
56
62
  1: fakeMeeting,
57
63
  2: fakeMeeting2,
64
+ 3: fakeMeeting3,
58
65
  };
59
66
 
60
67
  let webex;
@@ -86,8 +93,19 @@ describe('internal-plugin-metrics', () => {
86
93
  clientName: 'Cantina',
87
94
  },
88
95
  },
96
+ getBasicMeetingInformation: (id) => fakeMeetings[id],
89
97
  meetingCollection: {
90
- get: (id) => fakeMeetings[id],
98
+ get: (meetingId) => {
99
+ return {
100
+ statsAnalyzer: {
101
+ getLocalIpAddress: () => {
102
+ if (meetingId) {
103
+ return '192.168.1.90';
104
+ }
105
+ },
106
+ },
107
+ };
108
+ },
91
109
  },
92
110
  geoHintInfo: {
93
111
  clientAddress: '1.3.4.5',
@@ -366,6 +384,94 @@ describe('internal-plugin-metrics', () => {
366
384
  });
367
385
  });
368
386
 
387
+ [undefined, null, '', false, 0].forEach((sessionCorrelationId) => {
388
+ it(`should build identifiers correctly and not add session correlation id if it is falsy: ${sessionCorrelationId}`, () => {
389
+ cd.device = {
390
+ ...cd.device,
391
+ config: {installationId: 'installationId'},
392
+ };
393
+
394
+ const res = cd.getIdentifiers({
395
+ mediaConnections: [
396
+ {mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
397
+ ],
398
+ meeting: {...fakeMeeting, sessionCorrelationId},
399
+ sessionCorrelationId: sessionCorrelationId as any,
400
+ });
401
+
402
+ assert.deepEqual(res, {
403
+ correlationId: 'correlationId',
404
+ deviceId: 'deviceUrl',
405
+ locusId: 'url',
406
+ locusStartTime: 'lastActive',
407
+ locusUrl: 'locus/url',
408
+ machineId: 'installationId',
409
+ mediaAgentAlias: 'mediaAgentAlias',
410
+ mediaAgentGroupId: 'mediaAgentGroupId',
411
+ orgId: 'orgId',
412
+ userId: 'userId',
413
+ });
414
+ });
415
+ });
416
+
417
+ it('should build identifiers correctly with sessionCorrelationID as a param', () => {
418
+ cd.device = {
419
+ ...cd.device,
420
+ config: {installationId: 'installationId'},
421
+ };
422
+
423
+ const res = cd.getIdentifiers({
424
+ mediaConnections: [
425
+ {mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
426
+ ],
427
+ meeting: fakeMeeting,
428
+ sessionCorrelationId: 'sessionCorrelationId',
429
+ });
430
+
431
+ assert.deepEqual(res, {
432
+ correlationId: 'correlationId',
433
+ sessionCorrelationId: 'sessionCorrelationId',
434
+ deviceId: 'deviceUrl',
435
+ locusId: 'url',
436
+ locusStartTime: 'lastActive',
437
+ locusUrl: 'locus/url',
438
+ machineId: 'installationId',
439
+ mediaAgentAlias: 'mediaAgentAlias',
440
+ mediaAgentGroupId: 'mediaAgentGroupId',
441
+ orgId: 'orgId',
442
+ userId: 'userId',
443
+ });
444
+ });
445
+
446
+ it('should build identifiers correctly with sessionCorrelationID as a param and a meeting with session correlation id, and the param should take precedence', () => {
447
+ cd.device = {
448
+ ...cd.device,
449
+ config: {installationId: 'installationId'},
450
+ };
451
+
452
+ const res = cd.getIdentifiers({
453
+ mediaConnections: [
454
+ {mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
455
+ ],
456
+ meeting: {...fakeMeeting, sessionCorrelationId: 'sessionCorrelationId1'},
457
+ sessionCorrelationId: 'sessionCorrelationId',
458
+ });
459
+
460
+ assert.deepEqual(res, {
461
+ correlationId: 'correlationId',
462
+ sessionCorrelationId: 'sessionCorrelationId',
463
+ deviceId: 'deviceUrl',
464
+ locusId: 'url',
465
+ locusStartTime: 'lastActive',
466
+ locusUrl: 'locus/url',
467
+ machineId: 'installationId',
468
+ mediaAgentAlias: 'mediaAgentAlias',
469
+ mediaAgentGroupId: 'mediaAgentGroupId',
470
+ orgId: 'orgId',
471
+ userId: 'userId',
472
+ });
473
+ });
474
+
369
475
  it('should build identifiers correctly with a meeting that has meetingInfo with a webexConferenceIdStr and globalMeetingId, and that should take precedence over the options passed to it', () => {
370
476
  const res = cd.getIdentifiers({
371
477
  mediaConnections: [
@@ -466,6 +572,42 @@ describe('internal-plugin-metrics', () => {
466
572
  });
467
573
  });
468
574
 
575
+ it('should build identifiers correctly with a meeting that has sessionCorrelationId', () => {
576
+ const res = cd.getIdentifiers({
577
+ mediaConnections: [
578
+ {mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
579
+ ],
580
+ webexConferenceIdStr: 'webexConferenceIdStr',
581
+ globalMeetingId: 'globalMeetingId',
582
+ meeting: {
583
+ ...fakeMeeting,
584
+ sessionCorrelationId: 'sessionCorrelationId1',
585
+ meetingInfo: {
586
+ ...fakeMeeting.meetingInfo,
587
+ confIdStr: 'webexConferenceIdStr1',
588
+ meetingId: 'globalMeetingId1',
589
+ siteName: 'siteName1',
590
+ },
591
+ },
592
+ });
593
+
594
+ assert.deepEqual(res, {
595
+ correlationId: 'correlationId',
596
+ sessionCorrelationId: 'sessionCorrelationId1',
597
+ webexConferenceIdStr: 'webexConferenceIdStr1',
598
+ globalMeetingId: 'globalMeetingId1',
599
+ deviceId: 'deviceUrl',
600
+ locusId: 'url',
601
+ locusStartTime: 'lastActive',
602
+ locusUrl: 'locus/url',
603
+ mediaAgentAlias: 'mediaAgentAlias',
604
+ mediaAgentGroupId: 'mediaAgentGroupId',
605
+ orgId: 'orgId',
606
+ userId: 'userId',
607
+ webexSiteName: 'siteName1',
608
+ });
609
+ });
610
+
469
611
  it('should build identifiers correctly given webexConferenceIdStr', () => {
470
612
  const res = cd.getIdentifiers({
471
613
  correlationId: 'correlationId',
@@ -512,6 +654,22 @@ describe('internal-plugin-metrics', () => {
512
654
  });
513
655
  });
514
656
 
657
+ it('should build identifiers correctly given sessionCorrelationId', () => {
658
+ const res = cd.getIdentifiers({
659
+ correlationId: 'correlationId',
660
+ sessionCorrelationId: 'sessionCorrelationId',
661
+ });
662
+
663
+ assert.deepEqual(res, {
664
+ correlationId: 'correlationId',
665
+ sessionCorrelationId: 'sessionCorrelationId',
666
+ deviceId: 'deviceUrl',
667
+ locusUrl: 'locus-url',
668
+ orgId: 'orgId',
669
+ userId: 'userId',
670
+ });
671
+ });
672
+
515
673
  it('should throw Error if correlationId is missing', () => {
516
674
  assert.throws(() =>
517
675
  cd.getIdentifiers({
@@ -606,6 +764,7 @@ describe('internal-plugin-metrics', () => {
606
764
  options,
607
765
  });
608
766
 
767
+ assert.called(getIdentifiersSpy);
609
768
  assert.calledWith(getIdentifiersSpy, {
610
769
  meeting: fakeMeeting,
611
770
  mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
@@ -720,6 +879,142 @@ describe('internal-plugin-metrics', () => {
720
879
  ]);
721
880
  });
722
881
 
882
+ it('should submit client event successfully with meetingId which has a sessionCorrelationId', () => {
883
+ const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
884
+ const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
885
+ const generateClientEventErrorPayloadSpy = sinon.spy(cd, 'generateClientEventErrorPayload');
886
+ const getIdentifiersSpy = sinon.spy(cd, 'getIdentifiers');
887
+ const getSubServiceTypeSpy = sinon.spy(cd, 'getSubServiceType');
888
+ sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
889
+ const validatorSpy = sinon.spy(cd, 'validator');
890
+ const options = {
891
+ meetingId: fakeMeeting3.id,
892
+ mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
893
+ };
894
+
895
+ cd.submitClientEvent({
896
+ name: 'client.alert.displayed',
897
+ options,
898
+ });
899
+
900
+ assert.called(getIdentifiersSpy);
901
+ assert.calledWith(getIdentifiersSpy, {
902
+ meeting: {...fakeMeeting3, sessionCorrelationId: 'sessionCorrelationId3'},
903
+ mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
904
+ webexConferenceIdStr: undefined,
905
+ globalMeetingId: undefined,
906
+ sessionCorrelationId: undefined,
907
+ });
908
+ assert.notCalled(generateClientEventErrorPayloadSpy);
909
+ assert.calledWith(
910
+ prepareDiagnosticEventSpy,
911
+ {
912
+ canProceed: true,
913
+ eventData: {
914
+ webClientDomain: 'whatever',
915
+ },
916
+ identifiers: {
917
+ correlationId: 'correlationId3',
918
+ sessionCorrelationId: 'sessionCorrelationId3',
919
+ deviceId: 'deviceUrl',
920
+ locusId: 'url',
921
+ locusStartTime: 'lastActive',
922
+ locusUrl: 'locus/url',
923
+ mediaAgentAlias: 'alias',
924
+ mediaAgentGroupId: '1',
925
+ orgId: 'orgId',
926
+ userId: 'userId',
927
+ },
928
+ loginType: 'login-ci',
929
+ name: 'client.alert.displayed',
930
+ userType: 'host',
931
+ isConvergedArchitectureEnabled: undefined,
932
+ webexSubServiceType: undefined,
933
+ },
934
+ options
935
+ );
936
+ assert.calledWith(submitToCallDiagnosticsSpy, {
937
+ event: {
938
+ canProceed: true,
939
+ eventData: {
940
+ webClientDomain: 'whatever',
941
+ },
942
+ identifiers: {
943
+ correlationId: 'correlationId3',
944
+ sessionCorrelationId: 'sessionCorrelationId3',
945
+ deviceId: 'deviceUrl',
946
+ locusId: 'url',
947
+ locusStartTime: 'lastActive',
948
+ locusUrl: 'locus/url',
949
+ mediaAgentAlias: 'alias',
950
+ mediaAgentGroupId: '1',
951
+ orgId: 'orgId',
952
+ userId: 'userId',
953
+ },
954
+ loginType: 'login-ci',
955
+ name: 'client.alert.displayed',
956
+ userType: 'host',
957
+ isConvergedArchitectureEnabled: undefined,
958
+ webexSubServiceType: undefined,
959
+ },
960
+ eventId: 'my-fake-id',
961
+ origin: {
962
+ origin: 'fake-origin',
963
+ },
964
+ originTime: {
965
+ sent: 'not_defined_yet',
966
+ triggered: now.toISOString(),
967
+ },
968
+ senderCountryCode: 'UK',
969
+ version: 1,
970
+ });
971
+ assert.calledWith(validatorSpy, {
972
+ type: 'ce',
973
+ event: {
974
+ event: {
975
+ canProceed: true,
976
+ eventData: {
977
+ webClientDomain: 'whatever',
978
+ },
979
+ identifiers: {
980
+ correlationId: 'correlationId3',
981
+ sessionCorrelationId: 'sessionCorrelationId3',
982
+ deviceId: 'deviceUrl',
983
+ locusId: 'url',
984
+ locusStartTime: 'lastActive',
985
+ locusUrl: 'locus/url',
986
+ mediaAgentAlias: 'alias',
987
+ mediaAgentGroupId: '1',
988
+ orgId: 'orgId',
989
+ userId: 'userId',
990
+ },
991
+ loginType: 'login-ci',
992
+ name: 'client.alert.displayed',
993
+ userType: 'host',
994
+ isConvergedArchitectureEnabled: undefined,
995
+ webexSubServiceType: undefined,
996
+ },
997
+ eventId: 'my-fake-id',
998
+ origin: {
999
+ origin: 'fake-origin',
1000
+ },
1001
+ originTime: {
1002
+ sent: 'not_defined_yet',
1003
+ triggered: now.toISOString(),
1004
+ },
1005
+ senderCountryCode: 'UK',
1006
+ version: 1,
1007
+ },
1008
+ });
1009
+
1010
+ const webexLoggerLogCalls = webex.logger.log.getCalls();
1011
+ assert.deepEqual(webexLoggerLogCalls[1].args, [
1012
+ 'call-diagnostic-events -> ',
1013
+ 'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
1014
+ `name: client.alert.displayed`,
1015
+ ]);
1016
+ });
1017
+
723
1018
  it('should log browser data, but only for the first call diagnostic event', () => {
724
1019
  const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
725
1020
  const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
@@ -727,6 +1022,9 @@ describe('internal-plugin-metrics', () => {
727
1022
  const getIdentifiersSpy = sinon.spy(cd, 'getIdentifiers');
728
1023
  const getSubServiceTypeSpy = sinon.spy(cd, 'getSubServiceType');
729
1024
  const validatorSpy = sinon.spy(cd, 'validator');
1025
+ sinon.stub(window.navigator, 'userAgent').get(() => userAgent);
1026
+ sinon.stub(bowser, 'getParser').returns(userAgent);
1027
+
730
1028
  const options = {
731
1029
  meetingId: fakeMeeting.id,
732
1030
  mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
@@ -755,7 +1053,7 @@ describe('internal-plugin-metrics', () => {
755
1053
  assert.deepEqual(webexLoggerLogCalls[2].args, [
756
1054
  'call-diagnostic-events -> ',
757
1055
  'CallDiagnosticMetrics: @createClientEventObjectInMeeting => collected browser data',
758
- '{"error":"unable to access window.navigator.userAgent"}',
1056
+ `${JSON.stringify(userAgent)}`,
759
1057
  ]);
760
1058
 
761
1059
  assert.deepEqual(webexLoggerLogCalls[3].args, [
@@ -776,7 +1074,7 @@ describe('internal-plugin-metrics', () => {
776
1074
  correlationId: 'correlationId',
777
1075
  webexConferenceIdStr: 'webexConferenceIdStr1',
778
1076
  globalMeetingId: 'globalMeetingId1',
779
- sessionCorrelationId: 'sessionCorrelationId1'
1077
+ sessionCorrelationId: 'sessionCorrelationId1',
780
1078
  };
781
1079
 
782
1080
  cd.submitClientEvent({
@@ -870,7 +1168,7 @@ describe('internal-plugin-metrics', () => {
870
1168
  webexConferenceIdStr: 'webexConferenceIdStr1',
871
1169
  globalMeetingId: 'globalMeetingId1',
872
1170
  preLoginId: 'myPreLoginId',
873
- sessionCorrelationId: 'sessionCorrelationId1'
1171
+ sessionCorrelationId: 'sessionCorrelationId1',
874
1172
  };
875
1173
 
876
1174
  cd.submitClientEvent({
@@ -883,7 +1181,7 @@ describe('internal-plugin-metrics', () => {
883
1181
  webexConferenceIdStr: 'webexConferenceIdStr1',
884
1182
  globalMeetingId: 'globalMeetingId1',
885
1183
  preLoginId: 'myPreLoginId',
886
- sessionCorrelationId: 'sessionCorrelationId1'
1184
+ sessionCorrelationId: 'sessionCorrelationId1',
887
1185
  });
888
1186
 
889
1187
  assert.notCalled(generateClientEventErrorPayloadSpy);
@@ -972,6 +1270,59 @@ describe('internal-plugin-metrics', () => {
972
1270
  loginType: 'fakeLoginType',
973
1271
  name: 'client.alert.displayed',
974
1272
  userType: 'host',
1273
+ joinFlowVersion: 'Other',
1274
+ isConvergedArchitectureEnabled: undefined,
1275
+ webexSubServiceType: undefined,
1276
+ },
1277
+ eventId: 'my-fake-id',
1278
+ origin: {
1279
+ origin: 'fake-origin',
1280
+ },
1281
+ originTime: {
1282
+ sent: 'not_defined_yet',
1283
+ triggered: now.toISOString(),
1284
+ },
1285
+ senderCountryCode: 'UK',
1286
+ version: 1,
1287
+ });
1288
+ });
1289
+
1290
+ it('should use meeting loginType if present and meetingId provided, with sessionCorrelationId', () => {
1291
+ const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
1292
+ sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
1293
+ const options = {
1294
+ meetingId: fakeMeeting2.id,
1295
+ mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
1296
+ sessionCorrelationId: 'sessionCorrelationId1',
1297
+ };
1298
+
1299
+ cd.submitClientEvent({
1300
+ name: 'client.alert.displayed',
1301
+ options,
1302
+ });
1303
+
1304
+ assert.calledWith(submitToCallDiagnosticsSpy, {
1305
+ event: {
1306
+ canProceed: true,
1307
+ eventData: {
1308
+ webClientDomain: 'whatever',
1309
+ },
1310
+ identifiers: {
1311
+ correlationId: 'correlationId2',
1312
+ sessionCorrelationId: 'sessionCorrelationId1',
1313
+ deviceId: 'deviceUrl',
1314
+ locusId: 'url',
1315
+ locusStartTime: 'lastActive',
1316
+ locusUrl: 'locus/url',
1317
+ mediaAgentAlias: 'alias',
1318
+ mediaAgentGroupId: '1',
1319
+ orgId: 'orgId',
1320
+ userId: 'userId',
1321
+ },
1322
+ loginType: 'fakeLoginType',
1323
+ name: 'client.alert.displayed',
1324
+ userType: 'host',
1325
+ joinFlowVersion: 'Other',
975
1326
  isConvergedArchitectureEnabled: undefined,
976
1327
  webexSubServiceType: undefined,
977
1328
  },
@@ -1111,6 +1462,9 @@ describe('internal-plugin-metrics', () => {
1111
1462
  name: 'other',
1112
1463
  category: 'other',
1113
1464
  errorCode: 9999,
1465
+ errorData: {
1466
+ errorName: 'Error',
1467
+ },
1114
1468
  serviceErrorCode: 9999,
1115
1469
  errorDescription: 'UnknownError',
1116
1470
  rawErrorMessage: 'bad times',
@@ -1144,7 +1498,7 @@ describe('internal-plugin-metrics', () => {
1144
1498
  assert.deepEqual(webexLoggerLogCalls[2].args, [
1145
1499
  'call-diagnostic-events -> ',
1146
1500
  'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
1147
- `generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"other","errorCode":9999,"serviceErrorCode":9999,"rawErrorMessage":"bad times","errorDescription":"UnknownError"}`,
1501
+ `generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"other","errorCode":9999,"errorData":{"errorName":"Error"},"serviceErrorCode":9999,"rawErrorMessage":"bad times","errorDescription":"UnknownError"}`,
1148
1502
  ]);
1149
1503
  });
1150
1504
 
@@ -1182,6 +1536,9 @@ describe('internal-plugin-metrics', () => {
1182
1536
  name: 'other',
1183
1537
  category: 'other',
1184
1538
  errorCode: 9999,
1539
+ errorData: {
1540
+ errorName: 'Error',
1541
+ },
1185
1542
  serviceErrorCode: 9999,
1186
1543
  errorDescription: 'UnknownError',
1187
1544
  rawErrorMessage: 'bad times',
@@ -1213,7 +1570,7 @@ describe('internal-plugin-metrics', () => {
1213
1570
  assert.deepEqual(webexLoggerLogCalls[2].args, [
1214
1571
  'call-diagnostic-events -> ',
1215
1572
  'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
1216
- `generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"other","errorCode":9999,"serviceErrorCode":9999,"rawErrorMessage":"bad times","errorDescription":"UnknownError"}`,
1573
+ `generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"other","errorCode":9999,"errorData":{"errorName":"Error"},"serviceErrorCode":9999,"rawErrorMessage":"bad times","errorDescription":"UnknownError"}`,
1217
1574
  ]);
1218
1575
  });
1219
1576
 
@@ -1367,7 +1724,8 @@ describe('internal-plugin-metrics', () => {
1367
1724
  });
1368
1725
 
1369
1726
  it('should send behavioral event if meetingId provided but meeting is undefined', () => {
1370
- webex.meetings.meetingCollection.get = sinon.stub().returns(undefined);
1727
+ webex.meetings.getBasicMeetingInformation = sinon.stub().returns(undefined);
1728
+
1371
1729
  cd.submitClientEvent({name: 'client.alert.displayed', options: {meetingId: 'meetingId'}});
1372
1730
  assert.calledWith(
1373
1731
  webex.internal.metrics.submitClientMetrics,
@@ -1428,7 +1786,7 @@ describe('internal-plugin-metrics', () => {
1428
1786
  meetingId: fakeMeeting.id,
1429
1787
  webexConferenceIdStr: 'webexConferenceIdStr1',
1430
1788
  globalMeetingId: 'globalMeetingId1',
1431
- sessionCorrelationId: 'sessionCorrelationId1'
1789
+ sessionCorrelationId: 'sessionCorrelationId1',
1432
1790
  };
1433
1791
 
1434
1792
  cd.submitMQE({
@@ -1571,7 +1929,7 @@ describe('internal-plugin-metrics', () => {
1571
1929
  });
1572
1930
 
1573
1931
  it('should send behavioral event if meeting is undefined', () => {
1574
- webex.meetings.meetingCollection.get = sinon.stub().returns(undefined);
1932
+ webex.meetings.getBasicMeetingInformation = sinon.stub().returns(undefined);
1575
1933
  cd.submitMQE({
1576
1934
  name: 'client.mediaquality.event',
1577
1935
  payload: {
@@ -1893,6 +2251,9 @@ describe('internal-plugin-metrics', () => {
1893
2251
  shownToUser: true,
1894
2252
  serviceErrorCode: 9999,
1895
2253
  errorCode: 9999,
2254
+ errorData: {
2255
+ errorName: 'Error',
2256
+ },
1896
2257
  rawErrorMessage: 'bad times',
1897
2258
  });
1898
2259
  });
@@ -2036,6 +2397,40 @@ describe('internal-plugin-metrics', () => {
2036
2397
  });
2037
2398
  });
2038
2399
 
2400
+ it('should generate event error payload correctly for wdm error 4404002', () => {
2401
+ const res = cd.generateClientEventErrorPayload({
2402
+ body: {errorCode: 4404002},
2403
+ message: 'Operation denied due to region restriction',
2404
+ });
2405
+ assert.deepEqual(res, {
2406
+ category: 'expected',
2407
+ errorDescription: 'WdmRestrictedRegion',
2408
+ fatal: true,
2409
+ name: 'other',
2410
+ shownToUser: false,
2411
+ serviceErrorCode: 4404002,
2412
+ errorCode: 13000,
2413
+ rawErrorMessage: 'Operation denied due to region restriction',
2414
+ });
2415
+ });
2416
+
2417
+ it('should generate event error payload correctly for wdm error 4404003', () => {
2418
+ const res = cd.generateClientEventErrorPayload({
2419
+ body: {errorCode: 4404003},
2420
+ message: 'Operation denied due to region restriction',
2421
+ });
2422
+ assert.deepEqual(res, {
2423
+ category: 'expected',
2424
+ errorDescription: 'WdmRestrictedRegion',
2425
+ fatal: true,
2426
+ name: 'other',
2427
+ shownToUser: false,
2428
+ serviceErrorCode: 4404003,
2429
+ errorCode: 13000,
2430
+ rawErrorMessage: 'Operation denied due to region restriction',
2431
+ });
2432
+ });
2433
+
2039
2434
  describe('httpStatusCode', () => {
2040
2435
  it('should include httpStatusCode for browser media errors', () => {
2041
2436
  const res = cd.generateClientEventErrorPayload({
@@ -2314,6 +2709,7 @@ describe('internal-plugin-metrics', () => {
2314
2709
  environment: 'meeting_evn',
2315
2710
  name: 'endpoint',
2316
2711
  networkType: 'unknown',
2712
+ upgradeChannel: 'test',
2317
2713
  userAgent,
2318
2714
  },
2319
2715
  originTime: {
@@ -2362,6 +2758,83 @@ describe('internal-plugin-metrics', () => {
2362
2758
  ]);
2363
2759
  });
2364
2760
  });
2761
+
2762
+ it('includes expected joinFlowVersion from options when in-meeting', async () => {
2763
+ // meetingId means in-meeting
2764
+ const options = {
2765
+ meetingId: fakeMeeting.id,
2766
+ joinFlowVersion: 'NewFTE',
2767
+ };
2768
+
2769
+ const triggered = new Date();
2770
+ const fetchOptions = await cd.buildClientEventFetchRequestOptions({
2771
+ name: 'client.exit.app',
2772
+ payload: {trigger: 'user-interaction', canProceed: false},
2773
+ options,
2774
+ });
2775
+
2776
+ assert.equal(
2777
+ fetchOptions.body.metrics[0].eventPayload.event.joinFlowVersion,
2778
+ options.joinFlowVersion
2779
+ );
2780
+ });
2781
+
2782
+ it('includes expected joinFlowVersion from meeting callStateForMetrics when in-meeting', async () => {
2783
+ // meetingId means in-meeting
2784
+ const options = {
2785
+ meetingId: fakeMeeting2.id,
2786
+ };
2787
+
2788
+ const triggered = new Date();
2789
+ const fetchOptions = await cd.buildClientEventFetchRequestOptions({
2790
+ name: 'client.exit.app',
2791
+ payload: {trigger: 'user-interaction', canProceed: false},
2792
+ options,
2793
+ });
2794
+
2795
+ assert.equal(fetchOptions.body.metrics[0].eventPayload.event.joinFlowVersion, 'Other');
2796
+ });
2797
+
2798
+ it('prioritizes joinFlowVersion from options over meeting callStateForMetrics', async () => {
2799
+ // meetingId means in-meeting
2800
+ const options = {
2801
+ meetingId: fakeMeeting2.id,
2802
+ joinFlowVersion: 'NewFTE',
2803
+ };
2804
+
2805
+ const triggered = new Date();
2806
+ const fetchOptions = await cd.buildClientEventFetchRequestOptions({
2807
+ name: 'client.exit.app',
2808
+ payload: {trigger: 'user-interaction', canProceed: false},
2809
+ options,
2810
+ });
2811
+
2812
+ assert.equal(
2813
+ fetchOptions.body.metrics[0].eventPayload.event.joinFlowVersion,
2814
+ options.joinFlowVersion
2815
+ );
2816
+ });
2817
+
2818
+ it('includes expected joinFlowVersion from options during prejoin', async () => {
2819
+ // correlationId and no meeting id means prejoin
2820
+ const options = {
2821
+ correlationId: 'myCorrelationId',
2822
+ preLoginId: 'myPreLoginId',
2823
+ joinFlowVersion: 'NewFTE',
2824
+ };
2825
+
2826
+ const triggered = new Date();
2827
+ const fetchOptions = await cd.buildClientEventFetchRequestOptions({
2828
+ name: 'client.exit.app',
2829
+ payload: {trigger: 'user-interaction', canProceed: false},
2830
+ options,
2831
+ });
2832
+
2833
+ assert.equal(
2834
+ fetchOptions.body.metrics[0].eventPayload.event.joinFlowVersion,
2835
+ options.joinFlowVersion
2836
+ );
2837
+ });
2365
2838
  });
2366
2839
 
2367
2840
  describe('#submitToCallDiagnosticsPreLogin', () => {
@@ -2397,11 +2870,11 @@ describe('internal-plugin-metrics', () => {
2397
2870
  // The method is called in beforeEach itself. We are just testing it here
2398
2871
  it('sets the received deviceInfo to call-diagnostics', () => {
2399
2872
  const webexLoggerLogCalls = webex.logger.log.getCalls();
2400
- const device = { userId: 'userId', url: 'deviceUrl', orgId: 'orgId' };
2873
+ const device = {userId: 'userId', url: 'deviceUrl', orgId: 'orgId'};
2401
2874
 
2402
2875
  assert.deepEqual(webexLoggerLogCalls[0].args, [
2403
2876
  'CallDiagnosticMetrics: @setDeviceInfo called',
2404
- device
2877
+ device,
2405
2878
  ]);
2406
2879
 
2407
2880
  assert.deepEqual(cd.device, device);