@webex/internal-plugin-metrics 3.12.0-next.9 → 3.12.0-webex-services-ready.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.
Files changed (38) hide show
  1. package/dist/batcher.js +3 -0
  2. package/dist/batcher.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +23 -0
  4. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +29 -25
  6. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  7. package/dist/call-diagnostic/call-diagnostic-metrics.js +55 -8
  8. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  9. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +5 -0
  10. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  11. package/dist/call-diagnostic/config.js +14 -2
  12. package/dist/call-diagnostic/config.js.map +1 -1
  13. package/dist/config.js +1 -0
  14. package/dist/config.js.map +1 -1
  15. package/dist/metrics.js +1 -1
  16. package/dist/metrics.types.js.map +1 -1
  17. package/dist/prelogin-metrics-batcher.js +23 -0
  18. package/dist/prelogin-metrics-batcher.js.map +1 -1
  19. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +23 -0
  20. package/dist/types/call-diagnostic/config.d.ts +4 -0
  21. package/dist/types/config.d.ts +1 -0
  22. package/dist/types/metrics.types.d.ts +2 -2
  23. package/package.json +11 -11
  24. package/src/batcher.js +4 -0
  25. package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +26 -0
  26. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +54 -38
  27. package/src/call-diagnostic/call-diagnostic-metrics.ts +46 -1
  28. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +5 -0
  29. package/src/call-diagnostic/config.ts +13 -0
  30. package/src/config.js +1 -0
  31. package/src/metrics.types.ts +1 -1
  32. package/src/prelogin-metrics-batcher.ts +26 -0
  33. package/test/unit/spec/batcher.js +43 -0
  34. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +145 -0
  35. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +105 -95
  36. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +680 -159
  37. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +27 -0
  38. package/test/unit/spec/prelogin-metrics-batcher.ts +190 -36
@@ -857,6 +857,77 @@ describe('internal-plugin-metrics', () => {
857
857
  });
858
858
  });
859
859
 
860
+ describe('#prepareDiagnosticEvent isAutomatedUser field', () => {
861
+ it('should set isAutomatedUser to false when window is not defined', () => {
862
+ const options = {meetingId: fakeMeeting.id};
863
+ sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
864
+
865
+ const res = cd.prepareDiagnosticEvent(
866
+ {
867
+ canProceed: true,
868
+ identifiers: {correlationId: 'test-id'},
869
+ name: 'client.alert.displayed',
870
+ isAutomatedUser: false,
871
+ },
872
+ options
873
+ );
874
+
875
+ // In the test environment, isAutomatedUser should be false since we're not in a webdriver environment
876
+ assert.isFalse(
877
+ res.event.isAutomatedUser,
878
+ 'isAutomatedUser should be false in non-webdriver test environment'
879
+ );
880
+ });
881
+
882
+ it('should include isAutomatedUser field in the returned event', () => {
883
+ const options = {meetingId: fakeMeeting.id};
884
+ sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
885
+
886
+ const res = cd.prepareDiagnosticEvent(
887
+ {
888
+ canProceed: true,
889
+ identifiers: {correlationId: 'test-id'},
890
+ name: 'client.alert.displayed',
891
+ isAutomatedUser: false,
892
+ },
893
+ options
894
+ );
895
+
896
+ // Verify the isAutomatedUser field is present in the event
897
+ assert.isDefined(res.event.isAutomatedUser, 'isAutomatedUser field should be defined');
898
+ assert.isBoolean(res.event.isAutomatedUser, 'isAutomatedUser should be a boolean');
899
+ });
900
+
901
+ it('should set isAutomatedUser to true when navigator.webdriver is true', () => {
902
+ const originalDescriptor = Object.getOwnPropertyDescriptor(global, 'navigator');
903
+ Object.defineProperty(global, 'navigator', {
904
+ value: {webdriver: true},
905
+ configurable: true,
906
+ writable: true,
907
+ });
908
+
909
+ const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
910
+ sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
911
+ cd.setMercuryConnectedStatus(true);
912
+
913
+ cd.submitClientEvent({
914
+ name: 'client.alert.displayed',
915
+ options: {correlationId: 'correlationId'},
916
+ });
917
+
918
+ assert.isTrue(
919
+ prepareDiagnosticEventSpy.firstCall.args[0].isAutomatedUser,
920
+ 'isAutomatedUser should be true when navigator.webdriver is set'
921
+ );
922
+
923
+ if (originalDescriptor) {
924
+ Object.defineProperty(global, 'navigator', originalDescriptor);
925
+ } else {
926
+ delete (global as any).navigator;
927
+ }
928
+ });
929
+ });
930
+
860
931
  describe('#submitClientEvent', () => {
861
932
  it('should submit client event successfully with meetingId', () => {
862
933
  const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
@@ -907,11 +978,14 @@ describe('internal-plugin-metrics', () => {
907
978
  userId: 'userId',
908
979
  },
909
980
  loginType: 'login-ci',
981
+ telemetryOptOut: undefined,
910
982
  name: 'client.alert.displayed',
911
983
  userType: 'host',
912
984
  isConvergedArchitectureEnabled: undefined,
913
985
  webexSubServiceType: undefined,
914
986
  webClientPreload: undefined,
987
+ isVipMeeting: false,
988
+ isAutomatedUser: false,
915
989
  },
916
990
  options
917
991
  );
@@ -935,11 +1009,14 @@ describe('internal-plugin-metrics', () => {
935
1009
  userId: 'userId',
936
1010
  },
937
1011
  loginType: 'login-ci',
1012
+ telemetryOptOut: undefined,
938
1013
  name: 'client.alert.displayed',
939
1014
  userType: 'host',
940
1015
  isConvergedArchitectureEnabled: undefined,
941
1016
  webexSubServiceType: undefined,
942
1017
  webClientPreload: undefined,
1018
+ isVipMeeting: false,
1019
+ isAutomatedUser: false,
943
1020
  },
944
1021
  eventId: 'my-fake-id',
945
1022
  origin: {
@@ -974,11 +1051,14 @@ describe('internal-plugin-metrics', () => {
974
1051
  userId: 'userId',
975
1052
  },
976
1053
  loginType: 'login-ci',
1054
+ telemetryOptOut: undefined,
977
1055
  name: 'client.alert.displayed',
978
1056
  userType: 'host',
979
1057
  isConvergedArchitectureEnabled: undefined,
980
1058
  webexSubServiceType: undefined,
981
1059
  webClientPreload: undefined,
1060
+ isVipMeeting: false,
1061
+ isAutomatedUser: false,
982
1062
  },
983
1063
  eventId: 'my-fake-id',
984
1064
  origin: {
@@ -1049,11 +1129,14 @@ describe('internal-plugin-metrics', () => {
1049
1129
  userId: 'userId',
1050
1130
  },
1051
1131
  loginType: 'login-ci',
1132
+ telemetryOptOut: undefined,
1052
1133
  name: 'client.alert.displayed',
1053
1134
  userType: 'host',
1054
1135
  isConvergedArchitectureEnabled: undefined,
1055
1136
  webexSubServiceType: undefined,
1056
1137
  webClientPreload: undefined,
1138
+ isVipMeeting: false,
1139
+ isAutomatedUser: false,
1057
1140
  },
1058
1141
  options
1059
1142
  );
@@ -1077,11 +1160,14 @@ describe('internal-plugin-metrics', () => {
1077
1160
  userId: 'userId',
1078
1161
  },
1079
1162
  loginType: 'login-ci',
1163
+ telemetryOptOut: undefined,
1080
1164
  name: 'client.alert.displayed',
1081
1165
  userType: 'host',
1082
1166
  isConvergedArchitectureEnabled: undefined,
1083
1167
  webexSubServiceType: undefined,
1084
1168
  webClientPreload: undefined,
1169
+ isVipMeeting: false,
1170
+ isAutomatedUser: false,
1085
1171
  },
1086
1172
  eventId: 'my-fake-id',
1087
1173
  origin: {
@@ -1116,11 +1202,14 @@ describe('internal-plugin-metrics', () => {
1116
1202
  userId: 'userId',
1117
1203
  },
1118
1204
  loginType: 'login-ci',
1205
+ telemetryOptOut: undefined,
1119
1206
  name: 'client.alert.displayed',
1120
1207
  userType: 'host',
1121
1208
  isConvergedArchitectureEnabled: undefined,
1122
1209
  webexSubServiceType: undefined,
1123
1210
  webClientPreload: undefined,
1211
+ isVipMeeting: false,
1212
+ isAutomatedUser: false,
1124
1213
  },
1125
1214
  eventId: 'my-fake-id',
1126
1215
  origin: {
@@ -1192,11 +1281,14 @@ describe('internal-plugin-metrics', () => {
1192
1281
  userId: 'userId',
1193
1282
  },
1194
1283
  loginType: 'login-ci',
1284
+ telemetryOptOut: undefined,
1195
1285
  name: 'client.alert.displayed',
1196
1286
  userType: 'host',
1197
1287
  isConvergedArchitectureEnabled: undefined,
1198
1288
  webexSubServiceType: undefined,
1199
1289
  webClientPreload: undefined,
1290
+ isVipMeeting: false,
1291
+ isAutomatedUser: false,
1200
1292
  },
1201
1293
  options
1202
1294
  );
@@ -1221,11 +1313,14 @@ describe('internal-plugin-metrics', () => {
1221
1313
  userId: 'userId',
1222
1314
  },
1223
1315
  loginType: 'login-ci',
1316
+ telemetryOptOut: undefined,
1224
1317
  name: 'client.alert.displayed',
1225
1318
  userType: 'host',
1226
1319
  isConvergedArchitectureEnabled: undefined,
1227
1320
  webexSubServiceType: undefined,
1228
1321
  webClientPreload: undefined,
1322
+ isVipMeeting: false,
1323
+ isAutomatedUser: false,
1229
1324
  },
1230
1325
  eventId: 'my-fake-id',
1231
1326
  origin: {
@@ -1261,11 +1356,14 @@ describe('internal-plugin-metrics', () => {
1261
1356
  userId: 'userId',
1262
1357
  },
1263
1358
  loginType: 'login-ci',
1359
+ telemetryOptOut: undefined,
1264
1360
  name: 'client.alert.displayed',
1265
1361
  userType: 'host',
1266
1362
  isConvergedArchitectureEnabled: undefined,
1267
1363
  webexSubServiceType: undefined,
1268
1364
  webClientPreload: undefined,
1365
+ isVipMeeting: false,
1366
+ isAutomatedUser: false,
1269
1367
  },
1270
1368
  eventId: 'my-fake-id',
1271
1369
  origin: {
@@ -1336,11 +1434,14 @@ describe('internal-plugin-metrics', () => {
1336
1434
  userId: 'userId',
1337
1435
  },
1338
1436
  loginType: 'login-ci',
1437
+ telemetryOptOut: undefined,
1339
1438
  webClientPreload: undefined,
1340
1439
  name: 'client.alert.displayed',
1341
1440
  userType: 'host',
1342
1441
  isConvergedArchitectureEnabled: undefined,
1343
1442
  webexSubServiceType: undefined,
1443
+ isVipMeeting: false,
1444
+ isAutomatedUser: false,
1344
1445
  },
1345
1446
  options
1346
1447
  );
@@ -1365,11 +1466,14 @@ describe('internal-plugin-metrics', () => {
1365
1466
  userId: 'userId',
1366
1467
  },
1367
1468
  loginType: 'login-ci',
1469
+ telemetryOptOut: undefined,
1368
1470
  webClientPreload: undefined,
1369
1471
  name: 'client.alert.displayed',
1370
1472
  userType: 'host',
1371
1473
  isConvergedArchitectureEnabled: undefined,
1372
1474
  webexSubServiceType: undefined,
1475
+ isVipMeeting: false,
1476
+ isAutomatedUser: false,
1373
1477
  },
1374
1478
  eventId: 'my-fake-id',
1375
1479
  origin: {
@@ -1405,11 +1509,14 @@ describe('internal-plugin-metrics', () => {
1405
1509
  userId: 'userId',
1406
1510
  },
1407
1511
  loginType: 'login-ci',
1512
+ telemetryOptOut: undefined,
1408
1513
  webClientPreload: undefined,
1409
1514
  name: 'client.alert.displayed',
1410
1515
  userType: 'host',
1411
1516
  isConvergedArchitectureEnabled: undefined,
1412
1517
  webexSubServiceType: undefined,
1518
+ isVipMeeting: false,
1519
+ isAutomatedUser: false,
1413
1520
  },
1414
1521
  eventId: 'my-fake-id',
1415
1522
  origin: {
@@ -1480,6 +1587,7 @@ describe('internal-plugin-metrics', () => {
1480
1587
  userId: 'userId',
1481
1588
  },
1482
1589
  loginType: 'login-ci',
1590
+ telemetryOptOut: undefined,
1483
1591
  name: 'client.alert.displayed',
1484
1592
  userType: 'host',
1485
1593
  userNameInput: 'test',
@@ -1487,6 +1595,8 @@ describe('internal-plugin-metrics', () => {
1487
1595
  isConvergedArchitectureEnabled: undefined,
1488
1596
  webexSubServiceType: undefined,
1489
1597
  webClientPreload: undefined,
1598
+ isVipMeeting: false,
1599
+ isAutomatedUser: false,
1490
1600
  },
1491
1601
  options
1492
1602
  );
@@ -1511,6 +1621,7 @@ describe('internal-plugin-metrics', () => {
1511
1621
  userId: 'userId',
1512
1622
  },
1513
1623
  loginType: 'login-ci',
1624
+ telemetryOptOut: undefined,
1514
1625
  name: 'client.alert.displayed',
1515
1626
  userType: 'host',
1516
1627
  userNameInput: 'test',
@@ -1518,6 +1629,8 @@ describe('internal-plugin-metrics', () => {
1518
1629
  isConvergedArchitectureEnabled: undefined,
1519
1630
  webexSubServiceType: undefined,
1520
1631
  webClientPreload: undefined,
1632
+ isVipMeeting: false,
1633
+ isAutomatedUser: false,
1521
1634
  },
1522
1635
  eventId: 'my-fake-id',
1523
1636
  origin: {
@@ -1553,6 +1666,7 @@ describe('internal-plugin-metrics', () => {
1553
1666
  userId: 'userId',
1554
1667
  },
1555
1668
  loginType: 'login-ci',
1669
+ telemetryOptOut: undefined,
1556
1670
  name: 'client.alert.displayed',
1557
1671
  userType: 'host',
1558
1672
  userNameInput: 'test',
@@ -1560,6 +1674,8 @@ describe('internal-plugin-metrics', () => {
1560
1674
  isConvergedArchitectureEnabled: undefined,
1561
1675
  webexSubServiceType: undefined,
1562
1676
  webClientPreload: undefined,
1677
+ isVipMeeting: false,
1678
+ isAutomatedUser: false,
1563
1679
  },
1564
1680
  eventId: 'my-fake-id',
1565
1681
  origin: {
@@ -1684,8 +1800,10 @@ describe('internal-plugin-metrics', () => {
1684
1800
  userId: 'userId',
1685
1801
  },
1686
1802
  loginType: 'login-ci',
1803
+ telemetryOptOut: undefined,
1687
1804
  name: 'client.alert.displayed',
1688
1805
  webClientPreload: undefined,
1806
+ isAutomatedUser: false,
1689
1807
  },
1690
1808
  options
1691
1809
  );
@@ -1707,8 +1825,10 @@ describe('internal-plugin-metrics', () => {
1707
1825
  userId: 'userId',
1708
1826
  },
1709
1827
  loginType: 'login-ci',
1828
+ telemetryOptOut: undefined,
1710
1829
  name: 'client.alert.displayed',
1711
1830
  webClientPreload: undefined,
1831
+ isAutomatedUser: false,
1712
1832
  },
1713
1833
  eventId: 'my-fake-id',
1714
1834
  origin: {
@@ -1782,8 +1902,10 @@ describe('internal-plugin-metrics', () => {
1782
1902
  userId: 'myPreLoginId',
1783
1903
  },
1784
1904
  loginType: 'login-ci',
1905
+ telemetryOptOut: undefined,
1785
1906
  name: 'client.alert.displayed',
1786
1907
  webClientPreload: undefined,
1908
+ isAutomatedUser: false,
1787
1909
  },
1788
1910
  options
1789
1911
  );
@@ -1811,7 +1933,9 @@ describe('internal-plugin-metrics', () => {
1811
1933
  },
1812
1934
  eventData: {webClientDomain: 'whatever', isMercuryConnected: true},
1813
1935
  loginType: 'login-ci',
1936
+ telemetryOptOut: undefined,
1814
1937
  webClientPreload: undefined,
1938
+ isAutomatedUser: false,
1815
1939
  },
1816
1940
  },
1817
1941
  options.preLoginId
@@ -1873,8 +1997,10 @@ describe('internal-plugin-metrics', () => {
1873
1997
  userNameInput: 'current',
1874
1998
  emailInput: 'current',
1875
1999
  loginType: 'login-ci',
2000
+ telemetryOptOut: undefined,
1876
2001
  name: 'client.alert.displayed',
1877
2002
  webClientPreload: undefined,
2003
+ isAutomatedUser: false,
1878
2004
  },
1879
2005
  options
1880
2006
  );
@@ -1902,9 +2028,11 @@ describe('internal-plugin-metrics', () => {
1902
2028
  },
1903
2029
  eventData: {webClientDomain: 'whatever', isMercuryConnected: true},
1904
2030
  loginType: 'login-ci',
2031
+ telemetryOptOut: undefined,
1905
2032
  userNameInput: 'current',
1906
2033
  emailInput: 'current',
1907
2034
  webClientPreload: undefined,
2035
+ isAutomatedUser: false,
1908
2036
  },
1909
2037
  },
1910
2038
  options.preLoginId
@@ -1944,12 +2072,15 @@ describe('internal-plugin-metrics', () => {
1944
2072
  userId: 'userId',
1945
2073
  },
1946
2074
  loginType: 'fakeLoginType',
2075
+ telemetryOptOut: undefined,
1947
2076
  name: 'client.alert.displayed',
1948
2077
  userType: 'host',
1949
2078
  joinFlowVersion: 'Other',
1950
2079
  isConvergedArchitectureEnabled: undefined,
1951
2080
  webexSubServiceType: undefined,
1952
2081
  webClientPreload: undefined,
2082
+ isVipMeeting: false,
2083
+ isAutomatedUser: false,
1953
2084
  },
1954
2085
  eventId: 'my-fake-id',
1955
2086
  origin: {
@@ -1999,12 +2130,15 @@ describe('internal-plugin-metrics', () => {
1999
2130
  userId: 'userId',
2000
2131
  },
2001
2132
  loginType: 'fakeLoginType',
2133
+ telemetryOptOut: undefined,
2002
2134
  name: 'client.alert.displayed',
2003
2135
  userType: 'host',
2004
2136
  joinFlowVersion: 'Other',
2005
2137
  isConvergedArchitectureEnabled: undefined,
2006
2138
  webexSubServiceType: undefined,
2007
2139
  webClientPreload: undefined,
2140
+ isVipMeeting: false,
2141
+ isAutomatedUser: false,
2008
2142
  },
2009
2143
  eventId: 'my-fake-id',
2010
2144
  origin: {
@@ -2059,8 +2193,10 @@ describe('internal-plugin-metrics', () => {
2059
2193
  userId: 'userId',
2060
2194
  },
2061
2195
  loginType: 'login-ci',
2196
+ telemetryOptOut: undefined,
2062
2197
  name: 'client.alert.displayed',
2063
2198
  webClientPreload: true,
2199
+ isAutomatedUser: false,
2064
2200
  },
2065
2201
  options
2066
2202
  );
@@ -2082,8 +2218,216 @@ describe('internal-plugin-metrics', () => {
2082
2218
  userId: 'userId',
2083
2219
  },
2084
2220
  loginType: 'login-ci',
2221
+ telemetryOptOut: undefined,
2085
2222
  name: 'client.alert.displayed',
2086
2223
  webClientPreload: true,
2224
+ isAutomatedUser: false,
2225
+ },
2226
+ eventId: 'my-fake-id',
2227
+ origin: {
2228
+ origin: 'fake-origin',
2229
+ },
2230
+ originTime: {
2231
+ sent: 'not_defined_yet',
2232
+ triggered: now.toISOString(),
2233
+ },
2234
+ senderCountryCode: 'UK',
2235
+ version: 1,
2236
+ });
2237
+ });
2238
+
2239
+ it('should submit client event with isVipMeeting: false when vipMeeting is false', () => {
2240
+ const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
2241
+ const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
2242
+ const generateClientEventErrorPayloadSpy = sinon.spy(cd, 'generateClientEventErrorPayload');
2243
+ sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
2244
+
2245
+ webex.meetings.getBasicMeetingInformation = sinon.stub().returns({
2246
+ ...fakeMeeting,
2247
+ meetingInfo: {
2248
+ vipmeeting: false,
2249
+ },
2250
+ });
2251
+
2252
+ const options = {
2253
+ correlationId: 'correlationId',
2254
+ webexConferenceIdStr: 'webexConferenceIdStr1',
2255
+ globalMeetingId: 'globalMeetingId1',
2256
+ sessionCorrelationId: 'sessionCorrelationId1',
2257
+ meetingId: fakeMeeting.id,
2258
+ };
2259
+ cd.setMercuryConnectedStatus(true);
2260
+ cd.submitClientEvent({
2261
+ name: 'client.alert.displayed',
2262
+ options,
2263
+ });
2264
+
2265
+ assert.notCalled(generateClientEventErrorPayloadSpy);
2266
+ assert.calledWith(
2267
+ prepareDiagnosticEventSpy,
2268
+ {
2269
+ canProceed: true,
2270
+ eventData: {
2271
+ webClientDomain: 'whatever',
2272
+ isMercuryConnected: true,
2273
+ },
2274
+ identifiers: {
2275
+ correlationId: 'correlationId',
2276
+ webexConferenceIdStr: 'webexConferenceIdStr1',
2277
+ globalMeetingId: 'globalMeetingId1',
2278
+ sessionCorrelationId: 'sessionCorrelationId1',
2279
+ deviceId: 'deviceUrl',
2280
+ locusId: 'url',
2281
+ locusSessionId: 'locusSessionId',
2282
+ locusStartTime: 'lastActive',
2283
+ locusUrl: 'locus/url',
2284
+ orgId: 'orgId',
2285
+ userId: 'userId',
2286
+ },
2287
+ loginType: 'login-ci',
2288
+ telemetryOptOut: undefined,
2289
+ name: 'client.alert.displayed',
2290
+ userType: 'host',
2291
+ isConvergedArchitectureEnabled: undefined,
2292
+ webexSubServiceType: undefined,
2293
+ webClientPreload: undefined,
2294
+ isVipMeeting: false,
2295
+ isAutomatedUser: false,
2296
+ },
2297
+ options
2298
+ );
2299
+ assert.calledWith(submitToCallDiagnosticsSpy, {
2300
+ event: {
2301
+ canProceed: true,
2302
+ eventData: {
2303
+ webClientDomain: 'whatever',
2304
+ isMercuryConnected: true,
2305
+ },
2306
+ identifiers: {
2307
+ correlationId: 'correlationId',
2308
+ webexConferenceIdStr: 'webexConferenceIdStr1',
2309
+ globalMeetingId: 'globalMeetingId1',
2310
+ sessionCorrelationId: 'sessionCorrelationId1',
2311
+ deviceId: 'deviceUrl',
2312
+ locusId: 'url',
2313
+ locusSessionId: 'locusSessionId',
2314
+ locusStartTime: 'lastActive',
2315
+ locusUrl: 'locus/url',
2316
+ orgId: 'orgId',
2317
+ userId: 'userId',
2318
+ },
2319
+ loginType: 'login-ci',
2320
+ telemetryOptOut: undefined,
2321
+ name: 'client.alert.displayed',
2322
+ userType: 'host',
2323
+ isConvergedArchitectureEnabled: undefined,
2324
+ webexSubServiceType: undefined,
2325
+ webClientPreload: undefined,
2326
+ isVipMeeting: false,
2327
+ isAutomatedUser: false,
2328
+ },
2329
+ eventId: 'my-fake-id',
2330
+ origin: {
2331
+ origin: 'fake-origin',
2332
+ },
2333
+ originTime: {
2334
+ sent: 'not_defined_yet',
2335
+ triggered: now.toISOString(),
2336
+ },
2337
+ senderCountryCode: 'UK',
2338
+ version: 1,
2339
+ });
2340
+ });
2341
+
2342
+ it('should submit client event with isVipMeeting: true when vipMeeting is true', () => {
2343
+ const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
2344
+ const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
2345
+ const generateClientEventErrorPayloadSpy = sinon.spy(cd, 'generateClientEventErrorPayload');
2346
+ sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
2347
+
2348
+ webex.meetings.getBasicMeetingInformation = sinon.stub().returns({
2349
+ ...fakeMeeting,
2350
+ meetingInfo: {
2351
+ vipmeeting: true,
2352
+ },
2353
+ });
2354
+
2355
+ const options = {
2356
+ correlationId: 'correlationId',
2357
+ webexConferenceIdStr: 'webexConferenceIdStr1',
2358
+ globalMeetingId: 'globalMeetingId1',
2359
+ sessionCorrelationId: 'sessionCorrelationId1',
2360
+ meetingId: fakeMeeting.id,
2361
+ };
2362
+ cd.setMercuryConnectedStatus(true);
2363
+ cd.submitClientEvent({
2364
+ name: 'client.alert.displayed',
2365
+ options,
2366
+ });
2367
+
2368
+ assert.notCalled(generateClientEventErrorPayloadSpy);
2369
+ assert.calledWith(
2370
+ prepareDiagnosticEventSpy,
2371
+ {
2372
+ canProceed: true,
2373
+ eventData: {
2374
+ webClientDomain: 'whatever',
2375
+ isMercuryConnected: true,
2376
+ },
2377
+ identifiers: {
2378
+ correlationId: 'correlationId',
2379
+ webexConferenceIdStr: 'webexConferenceIdStr1',
2380
+ globalMeetingId: 'globalMeetingId1',
2381
+ sessionCorrelationId: 'sessionCorrelationId1',
2382
+ deviceId: 'deviceUrl',
2383
+ locusId: 'url',
2384
+ locusSessionId: 'locusSessionId',
2385
+ locusStartTime: 'lastActive',
2386
+ locusUrl: 'locus/url',
2387
+ orgId: 'orgId',
2388
+ userId: 'userId',
2389
+ },
2390
+ loginType: 'login-ci',
2391
+ telemetryOptOut: undefined,
2392
+ name: 'client.alert.displayed',
2393
+ userType: 'host',
2394
+ isConvergedArchitectureEnabled: undefined,
2395
+ webexSubServiceType: undefined,
2396
+ webClientPreload: undefined,
2397
+ isVipMeeting: true,
2398
+ isAutomatedUser: false,
2399
+ },
2400
+ options
2401
+ );
2402
+ assert.calledWith(submitToCallDiagnosticsSpy, {
2403
+ event: {
2404
+ canProceed: true,
2405
+ eventData: {
2406
+ webClientDomain: 'whatever',
2407
+ isMercuryConnected: true,
2408
+ },
2409
+ identifiers: {
2410
+ correlationId: 'correlationId',
2411
+ webexConferenceIdStr: 'webexConferenceIdStr1',
2412
+ globalMeetingId: 'globalMeetingId1',
2413
+ sessionCorrelationId: 'sessionCorrelationId1',
2414
+ deviceId: 'deviceUrl',
2415
+ locusId: 'url',
2416
+ locusSessionId: 'locusSessionId',
2417
+ locusStartTime: 'lastActive',
2418
+ locusUrl: 'locus/url',
2419
+ orgId: 'orgId',
2420
+ userId: 'userId',
2421
+ },
2422
+ loginType: 'login-ci',
2423
+ telemetryOptOut: undefined,
2424
+ name: 'client.alert.displayed',
2425
+ userType: 'host',
2426
+ isConvergedArchitectureEnabled: undefined,
2427
+ webexSubServiceType: undefined,
2428
+ webClientPreload: undefined,
2429
+ isVipMeeting: true,
2430
+ isAutomatedUser: false,
2087
2431
  },
2088
2432
  eventId: 'my-fake-id',
2089
2433
  origin: {
@@ -2153,11 +2497,14 @@ describe('internal-plugin-metrics', () => {
2153
2497
  },
2154
2498
  ],
2155
2499
  loginType: 'login-ci',
2500
+ telemetryOptOut: undefined,
2156
2501
  name: 'client.alert.displayed',
2157
2502
  userType: 'host',
2158
2503
  isConvergedArchitectureEnabled: undefined,
2159
2504
  webexSubServiceType: undefined,
2160
2505
  webClientPreload: undefined,
2506
+ isVipMeeting: false,
2507
+ isAutomatedUser: false,
2161
2508
  },
2162
2509
  eventId: 'my-fake-id',
2163
2510
  origin: {
@@ -2235,11 +2582,14 @@ describe('internal-plugin-metrics', () => {
2235
2582
  },
2236
2583
  ],
2237
2584
  loginType: 'login-ci',
2585
+ telemetryOptOut: undefined,
2238
2586
  name: 'client.alert.displayed',
2239
2587
  userType: 'host',
2240
2588
  isConvergedArchitectureEnabled: undefined,
2241
2589
  webexSubServiceType: undefined,
2242
2590
  webClientPreload: undefined,
2591
+ isVipMeeting: false,
2592
+ isAutomatedUser: false,
2243
2593
  },
2244
2594
  eventId: 'my-fake-id',
2245
2595
  origin: {
@@ -2311,8 +2661,10 @@ describe('internal-plugin-metrics', () => {
2311
2661
  },
2312
2662
  ],
2313
2663
  loginType: 'login-ci',
2664
+ telemetryOptOut: undefined,
2314
2665
  name: 'client.alert.displayed',
2315
2666
  webClientPreload: undefined,
2667
+ isAutomatedUser: false,
2316
2668
  },
2317
2669
  eventId: 'my-fake-id',
2318
2670
  origin: {
@@ -2386,8 +2738,10 @@ describe('internal-plugin-metrics', () => {
2386
2738
  },
2387
2739
  ],
2388
2740
  loginType: 'login-ci',
2741
+ telemetryOptOut: undefined,
2389
2742
  name: 'client.alert.displayed',
2390
2743
  webClientPreload: undefined,
2744
+ isAutomatedUser: false,
2391
2745
  },
2392
2746
  eventId: 'my-fake-id',
2393
2747
  origin: {
@@ -2468,11 +2822,14 @@ describe('internal-plugin-metrics', () => {
2468
2822
  },
2469
2823
  ],
2470
2824
  loginType: 'login-ci',
2825
+ telemetryOptOut: undefined,
2471
2826
  name: 'client.alert.displayed',
2472
2827
  userType: 'host',
2473
2828
  isConvergedArchitectureEnabled: undefined,
2474
2829
  webexSubServiceType: undefined,
2475
2830
  webClientPreload: undefined,
2831
+ isVipMeeting: false,
2832
+ isAutomatedUser: false,
2476
2833
  },
2477
2834
  eventId: 'my-fake-id',
2478
2835
  origin: {
@@ -2563,16 +2920,18 @@ describe('internal-plugin-metrics', () => {
2563
2920
  });
2564
2921
 
2565
2922
  assert.calledThrice(submitToCallDiagnosticsStub);
2566
- });
2923
+ });
2567
2924
 
2568
- ([
2569
- ['client.media.render.start'],
2570
- ['client.media.render.stop'],
2571
- ['client.media.rx.start'],
2572
- ['client.media.rx.stop'],
2573
- ['client.media.tx.start'],
2574
- ['client.media.tx.stop']
2575
- ] as const).forEach(([name]) => {
2925
+ (
2926
+ [
2927
+ ['client.media.render.start'],
2928
+ ['client.media.render.stop'],
2929
+ ['client.media.rx.start'],
2930
+ ['client.media.rx.stop'],
2931
+ ['client.media.tx.start'],
2932
+ ['client.media.tx.stop'],
2933
+ ] as const
2934
+ ).forEach(([name]) => {
2576
2935
  it(`should only send ${name} once per mediaType`, () => {
2577
2936
  const options = {
2578
2937
  meetingId: fakeMeeting.id,
@@ -2616,7 +2975,8 @@ describe('internal-plugin-metrics', () => {
2616
2975
  });
2617
2976
 
2618
2977
  assert.notCalled(submitToCallDiagnosticsStub);
2619
- assert.neverCalledWithMatch(webex.logger.log,
2978
+ assert.neverCalledWithMatch(
2979
+ webex.logger.log,
2620
2980
  'call-diagnostic-events -> ',
2621
2981
  sinon.match(createEventLimitRegex(name, 'mediaType video'))
2622
2982
  );
@@ -2659,7 +3019,7 @@ describe('internal-plugin-metrics', () => {
2659
3019
  // Send event with different shareInstanceId
2660
3020
  cd.submitClientEvent({
2661
3021
  name,
2662
- payload: { ...payload, shareInstanceId: 'instance-2' },
3022
+ payload: {...payload, shareInstanceId: 'instance-2'},
2663
3023
  options,
2664
3024
  });
2665
3025
 
@@ -2667,89 +3027,88 @@ describe('internal-plugin-metrics', () => {
2667
3027
  });
2668
3028
  });
2669
3029
 
2670
- ([
2671
- ['client.roap-message.received'],
2672
- ['client.roap-message.sent']
2673
- ] as const).forEach(([name]) => {
2674
- it(`should not send third event of same type and not log warning again for ${name}`, () => {
2675
- const options = {
2676
- meetingId: fakeMeeting.id,
2677
- };
2678
- const payload = {
2679
- roap: {
2680
- messageType: 'OFFER' as const,
2681
- },
2682
- };
2683
- const submitToCallDiagnosticsStub = sinon.stub(cd, 'submitToCallDiagnostics');
2684
-
2685
- // Clear any existing call history to get accurate counts
2686
- webex.logger.log.resetHistory();
2687
-
2688
- // Send first event
2689
- cd.submitClientEvent({
2690
- name,
2691
- payload,
2692
- options,
2693
- });
2694
-
2695
- assert.calledOnce(submitToCallDiagnosticsStub);
2696
- submitToCallDiagnosticsStub.resetHistory();
2697
-
2698
- // Send second event (should trigger warning)
2699
- cd.submitClientEvent({
2700
- name,
2701
- payload,
2702
- options,
2703
- });
2704
-
2705
- assert.notCalled(submitToCallDiagnosticsStub);
2706
- assert.calledWith(
2707
- webex.logger.log,
2708
- 'call-diagnostic-events -> ',
2709
- sinon.match(createEventLimitRegex(name, 'ROAP type OFFER'))
2710
- );
2711
- webex.logger.log.resetHistory();
2712
-
2713
- cd.submitClientEvent({
2714
- name,
2715
- payload,
2716
- options,
3030
+ ([['client.roap-message.received'], ['client.roap-message.sent']] as const).forEach(
3031
+ ([name]) => {
3032
+ it(`should not send third event of same type and not log warning again for ${name}`, () => {
3033
+ const options = {
3034
+ meetingId: fakeMeeting.id,
3035
+ };
3036
+ const payload = {
3037
+ roap: {
3038
+ messageType: 'OFFER' as const,
3039
+ },
3040
+ };
3041
+ const submitToCallDiagnosticsStub = sinon.stub(cd, 'submitToCallDiagnostics');
3042
+
3043
+ // Clear any existing call history to get accurate counts
3044
+ webex.logger.log.resetHistory();
3045
+
3046
+ // Send first event
3047
+ cd.submitClientEvent({
3048
+ name,
3049
+ payload,
3050
+ options,
3051
+ });
3052
+
3053
+ assert.calledOnce(submitToCallDiagnosticsStub);
3054
+ submitToCallDiagnosticsStub.resetHistory();
3055
+
3056
+ // Send second event (should trigger warning)
3057
+ cd.submitClientEvent({
3058
+ name,
3059
+ payload,
3060
+ options,
3061
+ });
3062
+
3063
+ assert.notCalled(submitToCallDiagnosticsStub);
3064
+ assert.calledWith(
3065
+ webex.logger.log,
3066
+ 'call-diagnostic-events -> ',
3067
+ sinon.match(createEventLimitRegex(name, 'ROAP type OFFER'))
3068
+ );
3069
+ webex.logger.log.resetHistory();
3070
+
3071
+ cd.submitClientEvent({
3072
+ name,
3073
+ payload,
3074
+ options,
3075
+ });
3076
+
3077
+ assert.notCalled(submitToCallDiagnosticsStub);
3078
+ assert.neverCalledWithMatch(
3079
+ webex.logger.log,
3080
+ 'call-diagnostic-events -> ',
3081
+ sinon.match(createEventLimitRegex(name, 'ROAP type OFFER'))
3082
+ );
2717
3083
  });
2718
3084
 
2719
- assert.notCalled(submitToCallDiagnosticsStub);
2720
- assert.neverCalledWithMatch(
2721
- webex.logger.log,
2722
- 'call-diagnostic-events -> ',
2723
- sinon.match(createEventLimitRegex(name, 'ROAP type OFFER'))
2724
- );
2725
- });
3085
+ it(`should handle roap.type instead of roap.messageType for ${name}`, () => {
3086
+ const options = {
3087
+ meetingId: fakeMeeting.id,
3088
+ };
3089
+ const payload = {
3090
+ roap: {
3091
+ type: 'ANSWER' as const,
3092
+ },
3093
+ };
3094
+ const submitToCallDiagnosticsStub = sinon.stub(cd, 'submitToCallDiagnostics');
2726
3095
 
2727
- it(`should handle roap.type instead of roap.messageType for ${name}`, () => {
2728
- const options = {
2729
- meetingId: fakeMeeting.id,
2730
- };
2731
- const payload = {
2732
- roap: {
2733
- type: 'ANSWER' as const,
2734
- },
2735
- };
2736
- const submitToCallDiagnosticsStub = sinon.stub(cd, 'submitToCallDiagnostics');
3096
+ cd.submitClientEvent({
3097
+ name,
3098
+ payload,
3099
+ options,
3100
+ });
2737
3101
 
2738
- cd.submitClientEvent({
2739
- name,
2740
- payload,
2741
- options,
2742
- });
3102
+ cd.submitClientEvent({
3103
+ name,
3104
+ payload,
3105
+ options,
3106
+ });
2743
3107
 
2744
- cd.submitClientEvent({
2745
- name,
2746
- payload,
2747
- options,
3108
+ assert.calledOnce(submitToCallDiagnosticsStub);
2748
3109
  });
2749
-
2750
- assert.calledOnce(submitToCallDiagnosticsStub);
2751
- });
2752
- });
3110
+ }
3111
+ );
2753
3112
  });
2754
3113
  });
2755
3114
 
@@ -2760,7 +3119,11 @@ describe('internal-plugin-metrics', () => {
2760
3119
  cd.callDiagnosticEventsBatcher = {request: requestStub};
2761
3120
  //@ts-ignore
2762
3121
  cd.submitToCallDiagnostics({event: 'test'});
2763
- assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
3122
+ assert.calledWith(requestStub, {
3123
+ eventPayload: {event: 'test'},
3124
+ type: ['diagnostic-event'],
3125
+ markTelemetryOptOutOnResponse: true,
3126
+ });
2764
3127
  });
2765
3128
  });
2766
3129
 
@@ -2829,6 +3192,7 @@ describe('internal-plugin-metrics', () => {
2829
3192
  mediaEngineSoftwareVersion: getOSVersion() || 'unknown',
2830
3193
  startTime: now.toISOString(),
2831
3194
  },
3195
+ webexSubServiceType: undefined,
2832
3196
  },
2833
3197
  options
2834
3198
  );
@@ -2869,6 +3233,7 @@ describe('internal-plugin-metrics', () => {
2869
3233
  mediaEngineSoftwareVersion: getOSVersion() || 'unknown',
2870
3234
  startTime: now.toISOString(),
2871
3235
  },
3236
+ webexSubServiceType: undefined,
2872
3237
  },
2873
3238
  },
2874
3239
  });
@@ -2907,10 +3272,48 @@ describe('internal-plugin-metrics', () => {
2907
3272
  mediaEngineSoftwareVersion: getOSVersion() || 'unknown',
2908
3273
  startTime: now.toISOString(),
2909
3274
  },
3275
+ webexSubServiceType: undefined,
2910
3276
  },
2911
3277
  });
2912
3278
  });
2913
3279
 
3280
+ it('includes webexSubServiceType in the media quality event payload', () => {
3281
+ const meeting = {
3282
+ ...fakeMeeting,
3283
+ meetingInfo: {
3284
+ enableConvergedArchitecture: true,
3285
+ enableEvent: true,
3286
+ enableConvergedWebinarLargeScale: true,
3287
+ },
3288
+ };
3289
+ const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
3290
+ sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
3291
+ webex.meetings.getBasicMeetingInformation = sinon.stub().returns(meeting);
3292
+
3293
+ const options = {
3294
+ networkType: 'wifi' as const,
3295
+ meetingId: fakeMeeting.id,
3296
+ };
3297
+
3298
+ cd.submitMQE({
3299
+ name: 'client.mediaquality.event',
3300
+ payload: {
3301
+ //@ts-ignore
3302
+ intervals: [{}],
3303
+ },
3304
+ options,
3305
+ });
3306
+
3307
+ assert.calledOnceWithExactly(
3308
+ prepareDiagnosticEventSpy,
3309
+ sinon.match({
3310
+ name: 'client.mediaquality.event',
3311
+ webexSubServiceType: 'LargeScaleWebinar',
3312
+ }),
3313
+ options
3314
+ );
3315
+ });
3316
+
2914
3317
  it('throws if meeting id not provided', () => {
2915
3318
  assert.throws(() =>
2916
3319
  cd.submitMQE({
@@ -3631,6 +4034,97 @@ describe('internal-plugin-metrics', () => {
3631
4034
  });
3632
4035
  });
3633
4036
 
4037
+ describe('#getTelemetryOptOut', () => {
4038
+ it('returns "manual" when manual telemetry opt-out is enabled', () => {
4039
+ cd.setIsTelemetryOptOutManual(true);
4040
+ assert.equal(cd.getTelemetryOptOut(), 'manual');
4041
+ });
4042
+
4043
+ it('returns "automatic" when automatic telemetry opt-out is enabled', () => {
4044
+ cd.setIsTelemetryOptOutAutomatic(true);
4045
+ assert.equal(cd.getTelemetryOptOut(), 'automatic');
4046
+ });
4047
+
4048
+ it('returns "manual" when manual opt-out takes precedence over automatic', () => {
4049
+ cd.setIsTelemetryOptOutManual(true);
4050
+ cd.setIsTelemetryOptOutAutomatic(true);
4051
+ assert.equal(cd.getTelemetryOptOut(), 'manual');
4052
+ });
4053
+
4054
+ it('returns undefined when neither manual nor automatic opt-out is set', () => {
4055
+ assert.isUndefined(cd.getTelemetryOptOut());
4056
+ });
4057
+
4058
+ it('returns undefined after disabling manual opt-out', () => {
4059
+ cd.setIsTelemetryOptOutManual(true);
4060
+ cd.setIsTelemetryOptOutManual(false);
4061
+ assert.isUndefined(cd.getTelemetryOptOut());
4062
+ });
4063
+ });
4064
+
4065
+ describe('#setIsTelemetryOptOutManual', () => {
4066
+ it('sets manual telemetry opt-out to true', () => {
4067
+ cd.setIsTelemetryOptOutManual(true);
4068
+ assert.equal(cd.getTelemetryOptOut(), 'manual');
4069
+ });
4070
+
4071
+ it('sets manual telemetry opt-out to false', () => {
4072
+ cd.setIsTelemetryOptOutManual(true);
4073
+ cd.setIsTelemetryOptOutManual(false);
4074
+ assert.isUndefined(cd.getTelemetryOptOut());
4075
+ });
4076
+
4077
+ it('can toggle manual telemetry opt-out multiple times', () => {
4078
+ cd.setIsTelemetryOptOutManual(true);
4079
+ assert.equal(cd.getTelemetryOptOut(), 'manual');
4080
+
4081
+ cd.setIsTelemetryOptOutManual(false);
4082
+ assert.isUndefined(cd.getTelemetryOptOut());
4083
+
4084
+ cd.setIsTelemetryOptOutManual(true);
4085
+ assert.equal(cd.getTelemetryOptOut(), 'manual');
4086
+ });
4087
+
4088
+ it('manual opt-out takes precedence when automatic is also set', () => {
4089
+ cd.setIsTelemetryOptOutAutomatic(true);
4090
+ cd.setIsTelemetryOptOutManual(true);
4091
+ assert.equal(cd.getTelemetryOptOut(), 'manual');
4092
+ });
4093
+ });
4094
+
4095
+ describe('#setIsTelemetryOptOutAutomatic', () => {
4096
+ it('sets automatic telemetry opt-out to true', () => {
4097
+ cd.setIsTelemetryOptOutAutomatic(true);
4098
+ assert.equal(cd.getTelemetryOptOut(), 'automatic');
4099
+ });
4100
+
4101
+ it('sets automatic telemetry opt-out to false', () => {
4102
+ cd.setIsTelemetryOptOutAutomatic(true);
4103
+ cd.setIsTelemetryOptOutAutomatic(false);
4104
+ assert.isUndefined(cd.getTelemetryOptOut());
4105
+ });
4106
+
4107
+ it('can toggle automatic telemetry opt-out multiple times', () => {
4108
+ cd.setIsTelemetryOptOutAutomatic(true);
4109
+ assert.equal(cd.getTelemetryOptOut(), 'automatic');
4110
+
4111
+ cd.setIsTelemetryOptOutAutomatic(false);
4112
+ assert.isUndefined(cd.getTelemetryOptOut());
4113
+
4114
+ cd.setIsTelemetryOptOutAutomatic(true);
4115
+ assert.equal(cd.getTelemetryOptOut(), 'automatic');
4116
+ });
4117
+
4118
+ it('does not override manual opt-out', () => {
4119
+ cd.setIsTelemetryOptOutManual(true);
4120
+ cd.setIsTelemetryOptOutAutomatic(true);
4121
+ assert.equal(cd.getTelemetryOptOut(), 'manual');
4122
+
4123
+ cd.setIsTelemetryOptOutAutomatic(false);
4124
+ assert.equal(cd.getTelemetryOptOut(), 'manual');
4125
+ });
4126
+ });
4127
+
3634
4128
  describe('#getSubServiceType', () => {
3635
4129
  it('returns subServicetype as PMR when PMR meeting', () => {
3636
4130
  fakeMeeting.meetingInfo = {
@@ -3749,12 +4243,15 @@ describe('internal-plugin-metrics', () => {
3749
4243
  userId: 'userId',
3750
4244
  },
3751
4245
  loginType: 'login-ci',
4246
+ telemetryOptOut: undefined,
3752
4247
  name: 'client.exit.app',
3753
4248
  trigger: 'user-interaction',
3754
4249
  userType: 'host',
3755
4250
  isConvergedArchitectureEnabled: undefined,
3756
4251
  webexSubServiceType: undefined,
3757
4252
  webClientPreload: undefined,
4253
+ isVipMeeting: false,
4254
+ isAutomatedUser: false,
3758
4255
  },
3759
4256
  eventId: 'my-fake-id',
3760
4257
  origin: {
@@ -3922,7 +4419,11 @@ describe('internal-plugin-metrics', () => {
3922
4419
  cd.submitToCallDiagnosticsPreLogin({event: 'test'}, preLoginId);
3923
4420
  //@ts-ignore
3924
4421
  assert.calledWith(cd.preLoginMetricsBatcher.savePreLoginId, preLoginId);
3925
- assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
4422
+ assert.calledWith(requestStub, {
4423
+ eventPayload: {event: 'test'},
4424
+ type: ['diagnostic-event'],
4425
+ markTelemetryOptOutOnResponse: true,
4426
+ });
3926
4427
  });
3927
4428
  });
3928
4429
 
@@ -4123,12 +4624,14 @@ describe('internal-plugin-metrics', () => {
4123
4624
  payload: {
4124
4625
  meetingSummaryInfo: {
4125
4626
  featureName: 'syncSystemMuteStatus',
4126
- featureActions: [{
4127
- actionName: 'syncMeetingMicUnmuteStatusToSystem',
4128
- actionId: '14200',
4129
- isInitialValue: false,
4130
- clickCount: '1'
4131
- }]
4627
+ featureActions: [
4628
+ {
4629
+ actionName: 'syncMeetingMicUnmuteStatusToSystem',
4630
+ actionId: '14200',
4631
+ isInitialValue: false,
4632
+ clickCount: '1',
4633
+ },
4634
+ ],
4132
4635
  },
4133
4636
  },
4134
4637
  options,
@@ -4149,22 +4652,27 @@ describe('internal-plugin-metrics', () => {
4149
4652
  locusSessionId: 'locusSessionId',
4150
4653
  locusStartTime: 'lastActive',
4151
4654
  },
4152
- eventData: { webClientDomain: 'whatever'},
4655
+ eventData: {webClientDomain: 'whatever'},
4153
4656
  userType: 'host',
4154
4657
  loginType: 'login-ci',
4658
+ telemetryOptOut: undefined,
4155
4659
  isConvergedArchitectureEnabled: undefined,
4156
4660
  webexSubServiceType: undefined,
4157
4661
  webClientPreload: undefined,
4662
+ isVipMeeting: false,
4663
+ isAutomatedUser: false,
4158
4664
  meetingSummaryInfo: {
4159
4665
  featureName: 'syncSystemMuteStatus',
4160
- featureActions: [{
4161
- actionName: 'syncMeetingMicUnmuteStatusToSystem',
4162
- actionId: '14200',
4163
- isInitialValue: false,
4164
- clickCount: '1'
4165
- }]
4666
+ featureActions: [
4667
+ {
4668
+ actionName: 'syncMeetingMicUnmuteStatusToSystem',
4669
+ actionId: '14200',
4670
+ isInitialValue: false,
4671
+ clickCount: '1',
4672
+ },
4673
+ ],
4166
4674
  },
4167
- key: "UcfFeatureUsage",
4675
+ key: 'UcfFeatureUsage',
4168
4676
  },
4169
4677
  options
4170
4678
  );
@@ -4177,7 +4685,7 @@ describe('internal-plugin-metrics', () => {
4177
4685
  },
4178
4686
  event: {
4179
4687
  canProceed: true,
4180
- eventData: { webClientDomain: 'whatever'},
4688
+ eventData: {webClientDomain: 'whatever'},
4181
4689
  identifiers: {
4182
4690
  correlationId: 'correlationId',
4183
4691
  deviceId: 'deviceUrl',
@@ -4189,21 +4697,26 @@ describe('internal-plugin-metrics', () => {
4189
4697
  userId: 'userId',
4190
4698
  },
4191
4699
  loginType: 'login-ci',
4700
+ telemetryOptOut: undefined,
4192
4701
  name: 'client.feature.meeting.summary',
4193
4702
  userType: 'host',
4194
4703
  isConvergedArchitectureEnabled: undefined,
4195
4704
  webexSubServiceType: undefined,
4196
4705
  webClientPreload: undefined,
4706
+ isVipMeeting: false,
4707
+ isAutomatedUser: false,
4197
4708
  meetingSummaryInfo: {
4198
4709
  featureName: 'syncSystemMuteStatus',
4199
- featureActions: [{
4200
- actionName: 'syncMeetingMicUnmuteStatusToSystem',
4201
- actionId: '14200',
4202
- isInitialValue: false,
4203
- clickCount: '1'
4204
- }]
4710
+ featureActions: [
4711
+ {
4712
+ actionName: 'syncMeetingMicUnmuteStatusToSystem',
4713
+ actionId: '14200',
4714
+ isInitialValue: false,
4715
+ clickCount: '1',
4716
+ },
4717
+ ],
4205
4718
  },
4206
- key: "UcfFeatureUsage",
4719
+ key: 'UcfFeatureUsage',
4207
4720
  },
4208
4721
  originTime: {
4209
4722
  sent: 'not_defined_yet',
@@ -4244,12 +4757,14 @@ describe('internal-plugin-metrics', () => {
4244
4757
  payload: {
4245
4758
  meetingSummaryInfo: {
4246
4759
  featureName: 'syncSystemMuteStatus',
4247
- featureActions: [{
4248
- actionName: 'syncMeetingMicUnmuteStatusToSystem',
4249
- actionId: '14200',
4250
- isInitialValue: false,
4251
- clickCount: '1'
4252
- }]
4760
+ featureActions: [
4761
+ {
4762
+ actionName: 'syncMeetingMicUnmuteStatusToSystem',
4763
+ actionId: '14200',
4764
+ isInitialValue: false,
4765
+ clickCount: '1',
4766
+ },
4767
+ ],
4253
4768
  },
4254
4769
  },
4255
4770
  delaySubmitEvent: true,
@@ -4261,12 +4776,14 @@ describe('internal-plugin-metrics', () => {
4261
4776
  payload: {
4262
4777
  meetingSummaryInfo: {
4263
4778
  featureName: 'syncSystemVideoStatus',
4264
- featureActions: [{
4265
- actionName: 'syncMeetingVideoUnmuteStatusToSystem',
4266
- actionId: '13400',
4267
- isInitialValue: false,
4268
- clickCount: '1'
4269
- }]
4779
+ featureActions: [
4780
+ {
4781
+ actionName: 'syncMeetingVideoUnmuteStatusToSystem',
4782
+ actionId: '13400',
4783
+ isInitialValue: false,
4784
+ clickCount: '1',
4785
+ },
4786
+ ],
4270
4787
  },
4271
4788
  },
4272
4789
  delaySubmitEvent: true,
@@ -4284,12 +4801,14 @@ describe('internal-plugin-metrics', () => {
4284
4801
  payload: {
4285
4802
  meetingSummaryInfo: {
4286
4803
  featureName: 'syncSystemMuteStatus',
4287
- featureActions: [{
4288
- actionName: 'syncMeetingMicUnmuteStatusToSystem',
4289
- actionId: '14200',
4290
- isInitialValue: false,
4291
- clickCount: '1'
4292
- }]
4804
+ featureActions: [
4805
+ {
4806
+ actionName: 'syncMeetingMicUnmuteStatusToSystem',
4807
+ actionId: '14200',
4808
+ isInitialValue: false,
4809
+ clickCount: '1',
4810
+ },
4811
+ ],
4293
4812
  },
4294
4813
  },
4295
4814
  options: {
@@ -4302,12 +4821,14 @@ describe('internal-plugin-metrics', () => {
4302
4821
  payload: {
4303
4822
  meetingSummaryInfo: {
4304
4823
  featureName: 'syncSystemVideoStatus',
4305
- featureActions: [{
4306
- actionName: 'syncMeetingVideoUnmuteStatusToSystem',
4307
- actionId: '13400',
4308
- isInitialValue: false,
4309
- clickCount: '1'
4310
- }]
4824
+ featureActions: [
4825
+ {
4826
+ actionName: 'syncMeetingVideoUnmuteStatusToSystem',
4827
+ actionId: '13400',
4828
+ isInitialValue: false,
4829
+ clickCount: '1',
4830
+ },
4831
+ ],
4311
4832
  },
4312
4833
  },
4313
4834
  options: {
@@ -4331,17 +4852,17 @@ describe('internal-plugin-metrics', () => {
4331
4852
 
4332
4853
  it('should clear event limits for specific correlationId only', () => {
4333
4854
  // Use the actual correlationIds from our fakeMeeting fixtures
4334
- const correlationId1 = fakeMeeting.correlationId; // e.g. 'correlationId1'
4335
- const correlationId2 = fakeMeeting2.correlationId; // e.g. 'correlationId2'
4336
- const options1 = { meetingId: fakeMeeting.id };
4337
- const options2 = { meetingId: fakeMeeting2.id };
4338
- const payload = { mediaType: 'video' as const };
4855
+ const correlationId1 = fakeMeeting.correlationId; // e.g. 'correlationId1'
4856
+ const correlationId2 = fakeMeeting2.correlationId; // e.g. 'correlationId2'
4857
+ const options1 = {meetingId: fakeMeeting.id};
4858
+ const options2 = {meetingId: fakeMeeting2.id};
4859
+ const payload = {mediaType: 'video' as const};
4339
4860
 
4340
4861
  // Set up events for both correlations to trigger limits
4341
- cd.submitClientEvent({ name: 'client.media.render.start', payload, options: options1 });
4342
- cd.submitClientEvent({ name: 'client.media.render.start', payload, options: options2 });
4343
- cd.submitClientEvent({ name: 'client.media.render.start', payload, options: options1 });
4344
- cd.submitClientEvent({ name: 'client.media.render.start', payload, options: options2 });
4862
+ cd.submitClientEvent({name: 'client.media.render.start', payload, options: options1});
4863
+ cd.submitClientEvent({name: 'client.media.render.start', payload, options: options2});
4864
+ cd.submitClientEvent({name: 'client.media.render.start', payload, options: options1});
4865
+ cd.submitClientEvent({name: 'client.media.render.start', payload, options: options2});
4345
4866
  assert.isTrue(cd.eventLimitTracker.size > 0);
4346
4867
  assert.isTrue(cd.eventLimitWarningsLogged.size > 0);
4347
4868
 
@@ -4352,17 +4873,17 @@ describe('internal-plugin-metrics', () => {
4352
4873
  const remainingWarningKeys = Array.from(cd.eventLimitWarningsLogged.keys());
4353
4874
 
4354
4875
  // Should have no keys with correlationId1
4355
- assert.isFalse(remainingTrackerKeys.some(key => key.split(':')[1] === correlationId1));
4356
- assert.isFalse(remainingWarningKeys.some(key => key.split(':')[1] === correlationId1));
4876
+ assert.isFalse(remainingTrackerKeys.some((key) => key.split(':')[1] === correlationId1));
4877
+ assert.isFalse(remainingWarningKeys.some((key) => key.split(':')[1] === correlationId1));
4357
4878
 
4358
4879
  // Should still have keys with correlationId2
4359
- assert.isTrue(remainingTrackerKeys.some(key => key.split(':')[1] === correlationId2));
4360
- assert.isTrue(remainingWarningKeys.some(key => key.split(':')[1] === correlationId2));
4880
+ assert.isTrue(remainingTrackerKeys.some((key) => key.split(':')[1] === correlationId2));
4881
+ assert.isTrue(remainingWarningKeys.some((key) => key.split(':')[1] === correlationId2));
4361
4882
  });
4362
4883
 
4363
4884
  it('should handle empty correlationId gracefully', () => {
4364
- const options = { meetingId: fakeMeeting.id };
4365
- const payload = { mediaType: 'video' as const };
4885
+ const options = {meetingId: fakeMeeting.id};
4886
+ const payload = {mediaType: 'video' as const};
4366
4887
 
4367
4888
  // Set up some tracking data
4368
4889
  cd.submitClientEvent({
@@ -4390,8 +4911,8 @@ describe('internal-plugin-metrics', () => {
4390
4911
  });
4391
4912
 
4392
4913
  it('should handle non-existent correlationId gracefully', () => {
4393
- const options = { meetingId: fakeMeeting.id };
4394
- const payload = { mediaType: 'video' as const };
4914
+ const options = {meetingId: fakeMeeting.id};
4915
+ const payload = {mediaType: 'video' as const};
4395
4916
 
4396
4917
  // Set up some tracking data
4397
4918
  cd.submitClientEvent({
@@ -4412,10 +4933,10 @@ describe('internal-plugin-metrics', () => {
4412
4933
 
4413
4934
  it('should clear multiple event types for the same correlationId', () => {
4414
4935
  const correlationId = fakeMeeting.correlationId;
4415
- const options = { meetingId: fakeMeeting.id };
4416
- const videoPayload = { mediaType: 'video' as const };
4417
- const audioPayload = { mediaType: 'audio' as const };
4418
- const roapPayload = { roap: { messageType: 'OFFER' as const } };
4936
+ const options = {meetingId: fakeMeeting.id};
4937
+ const videoPayload = {mediaType: 'video' as const};
4938
+ const audioPayload = {mediaType: 'audio' as const};
4939
+ const roapPayload = {roap: {messageType: 'OFFER' as const}};
4419
4940
 
4420
4941
  // Set up multiple event types for the same correlation
4421
4942
  cd.submitClientEvent({
@@ -4468,8 +4989,8 @@ describe('internal-plugin-metrics', () => {
4468
4989
 
4469
4990
  it('should allow events to be sent again after clearing limits for correlationId', () => {
4470
4991
  const correlationId = fakeMeeting.correlationId;
4471
- const options = { meetingId: fakeMeeting.id };
4472
- const payload = { mediaType: 'video' as const };
4992
+ const options = {meetingId: fakeMeeting.id};
4993
+ const payload = {mediaType: 'video' as const};
4473
4994
  const submitToCallDiagnosticsStub = sinon.stub(cd, 'submitToCallDiagnostics');
4474
4995
 
4475
4996
  // Send first event (should succeed)