@webex/internal-plugin-metrics 3.9.0-webinar5k.1 → 3.10.0-multi-llms.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.
@@ -75,6 +75,7 @@ type GetOriginOptions = {
75
75
  browserLaunchMethod?: BrowserLaunchMethodType;
76
76
  environment?: EnvironmentType;
77
77
  newEnvironment?: NewEnvironmentType;
78
+ vendorId?: string;
78
79
  };
79
80
 
80
81
  type GetIdentifiersOptions = {
@@ -105,6 +106,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
105
106
  private delayedClientFeatureEvents: DelayedClientFeatureEvent[] = [];
106
107
  private eventErrorCache: WeakMap<any, any> = new WeakMap();
107
108
  private isMercuryConnected = false;
109
+ private eventLimitTracker: Map<string, number> = new Map();
110
+ private eventLimitWarningsLogged: Set<string> = new Set();
108
111
 
109
112
  // the default validator before piping an event to the batcher
110
113
  // this function can be overridden by the user
@@ -295,6 +298,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
295
298
  origin.clientInfo.browserLaunchMethod = options.browserLaunchMethod;
296
299
  }
297
300
 
301
+ if (options?.vendorId) {
302
+ origin.clientInfo.vendorId = options.vendorId;
303
+ }
304
+
298
305
  return origin;
299
306
  }
300
307
 
@@ -665,6 +672,144 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
665
672
  this.eventErrorCache = new WeakMap();
666
673
  }
667
674
 
675
+ /**
676
+ * Checks if an event should be limited based on criteria defined in the event dictionary.
677
+ * Returns true if the event should be sent, false if it has reached its limit.
678
+ * @param event - The diagnostic event object
679
+ * @returns boolean indicating whether the event should be sent
680
+ */
681
+ private shouldSendEvent({event}: Event): boolean {
682
+ const eventName = event?.name as string;
683
+ const correlationId = event?.identifiers?.correlationId;
684
+
685
+ if (!correlationId || correlationId === 'unknown') {
686
+ return true;
687
+ }
688
+
689
+ const limitKeyPrefix = `${eventName}:${correlationId}`;
690
+
691
+ switch (eventName) {
692
+ case 'client.media.render.start':
693
+ case 'client.media.render.stop':
694
+ case 'client.media.rx.start':
695
+ case 'client.media.rx.stop':
696
+ case 'client.media.tx.start':
697
+ case 'client.media.tx.stop': {
698
+ // Send only once per mediaType-correlationId pair (or mediaType-correlationId-shareInstanceId for share/share_audio)
699
+ const mediaType = event?.mediaType;
700
+ if (mediaType) {
701
+ if (mediaType === 'share' || mediaType === 'share_audio') {
702
+ const shareInstanceId = event?.shareInstanceId;
703
+ if (shareInstanceId) {
704
+ const limitKey = `${limitKeyPrefix}:${mediaType}:${shareInstanceId}`;
705
+
706
+ return this.checkAndIncrementEventCount(
707
+ limitKey,
708
+ 1,
709
+ `${eventName} for ${mediaType} instance ${shareInstanceId}`
710
+ );
711
+ }
712
+ } else {
713
+ const limitKey = `${limitKeyPrefix}:${mediaType}`;
714
+
715
+ return this.checkAndIncrementEventCount(
716
+ limitKey,
717
+ 1,
718
+ `${eventName} for mediaType ${mediaType}`
719
+ );
720
+ }
721
+ }
722
+ break;
723
+ }
724
+
725
+ case 'client.roap-message.received':
726
+ case 'client.roap-message.sent': {
727
+ // Send only once per correlationId and roap.messageType/roap.type
728
+ const roapMessageType = event?.roap?.messageType || event?.roap?.type;
729
+ if (roapMessageType) {
730
+ const limitKey = `${limitKeyPrefix}:${roapMessageType}`;
731
+
732
+ return this.checkAndIncrementEventCount(
733
+ limitKey,
734
+ 1,
735
+ `${eventName} for ROAP type ${roapMessageType}`
736
+ );
737
+ }
738
+ break;
739
+ }
740
+
741
+ default:
742
+ return true;
743
+ }
744
+
745
+ return true;
746
+ }
747
+
748
+ /**
749
+ * Checks the current count for a limit key and increments if under limit.
750
+ * @param limitKey - The unique key for this limit combination
751
+ * @param maxCount - Maximum allowed count
752
+ * @param eventDescription - Description for logging
753
+ * @returns true if under limit and incremented, false if at/over limit
754
+ */
755
+ private checkAndIncrementEventCount(
756
+ limitKey: string,
757
+ maxCount: number,
758
+ eventDescription: string
759
+ ): boolean {
760
+ const currentCount = this.eventLimitTracker.get(limitKey) || 0;
761
+
762
+ if (currentCount >= maxCount) {
763
+ // Log warning only once per limit key
764
+ if (!this.eventLimitWarningsLogged.has(limitKey)) {
765
+ this.logger.log(
766
+ CALL_DIAGNOSTIC_LOG_IDENTIFIER,
767
+ `CallDiagnosticMetrics: Event limit reached for ${eventDescription}. ` +
768
+ `Max count ${maxCount} exceeded. Event will not be sent.`,
769
+ `limitKey: ${limitKey}`
770
+ );
771
+ this.eventLimitWarningsLogged.add(limitKey);
772
+ }
773
+
774
+ return false;
775
+ }
776
+
777
+ // Increment count and allow event
778
+ this.eventLimitTracker.set(limitKey, currentCount + 1);
779
+
780
+ return true;
781
+ }
782
+
783
+ /**
784
+ * Clears event limit tracking
785
+ */
786
+ public clearEventLimits(): void {
787
+ this.eventLimitTracker.clear();
788
+ this.eventLimitWarningsLogged.clear();
789
+ }
790
+
791
+ /**
792
+ * Clears event limit tracking for a specific correlationId only.
793
+ * Keeps limits for other meetings intact.
794
+ */
795
+ public clearEventLimitsForCorrelationId(correlationId: string): void {
796
+ if (!correlationId) {
797
+ return;
798
+ }
799
+ // Keys are formatted as "eventName:correlationId:..." across all limiters.
800
+ const hasCorrIdAtSecondToken = (key: string) => key.split(':')[1] === correlationId;
801
+ for (const key of Array.from(this.eventLimitTracker.keys())) {
802
+ if (hasCorrIdAtSecondToken(key)) {
803
+ this.eventLimitTracker.delete(key);
804
+ }
805
+ }
806
+ for (const key of Array.from(this.eventLimitWarningsLogged.values())) {
807
+ if (hasCorrIdAtSecondToken(key)) {
808
+ this.eventLimitWarningsLogged.delete(key);
809
+ }
810
+ }
811
+ }
812
+
668
813
  /**
669
814
  * Generate error payload for Client Event
670
815
  * @param rawError
@@ -1099,6 +1244,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
1099
1244
  );
1100
1245
  const diagnosticEvent = this.prepareClientEvent({name, payload, options});
1101
1246
 
1247
+ if (!this.shouldSendEvent(diagnosticEvent)) {
1248
+ return Promise.resolve();
1249
+ }
1250
+
1102
1251
  if (options?.preLoginId) {
1103
1252
  return this.submitToCallDiagnosticsPreLogin(diagnosticEvent, options?.preLoginId);
1104
1253
  }
@@ -1266,8 +1415,11 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
1266
1415
  */
1267
1416
  public setDeviceInfo(device: any): void {
1268
1417
  // This was created to fix the circular dependency between internal-plugin-device and internal-plugin-metrics
1269
- this.logger.log('CallDiagnosticMetrics: @setDeviceInfo called', device);
1270
-
1418
+ this.logger.log('CallDiagnosticMetrics: @setDeviceInfo called', {
1419
+ userId: device?.userId,
1420
+ deviceId: device?.url,
1421
+ orgId: device?.orgId,
1422
+ });
1271
1423
  this.device = device;
1272
1424
  }
1273
1425
  }
@@ -239,6 +239,20 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
239
239
 
240
240
  // Set upgradeChannel to 'gold' if buildType is 'prod', otherwise to the buildType value
241
241
  const upgradeChannel = buildType === 'prod' ? 'gold' : buildType;
242
+ if (webex.devicemanager) {
243
+ const pairedDevice = webex.devicemanager.getPairedDevice();
244
+ if (pairedDevice) {
245
+ const devicePayload = {
246
+ deviceId: pairedDevice.deviceInfo?.id,
247
+ devicePairingType: webex.devicemanager.getPairedMethod(),
248
+ deviceURL: pairedDevice.url,
249
+ isPersonalDevice: pairedDevice.mode === 'personal',
250
+ productName: pairedDevice.devices[0]?.productName,
251
+ };
252
+ item.eventPayload.event.pairingState = 'paired';
253
+ item.eventPayload.event.pairedDevice = devicePayload;
254
+ }
255
+ }
242
256
 
243
257
  const origin: Partial<Event['origin']> = {
244
258
  buildType,
@@ -138,6 +138,7 @@ export type SubmitClientEventOptions = {
138
138
  triggeredTime?: string;
139
139
  emailInput?: ClientEmailInput;
140
140
  userNameInput?: ClientUserNameInput;
141
+ vendorId?: string;
141
142
  };
142
143
 
143
144
  export type SubmitMQEOptions = {
@@ -160,7 +161,9 @@ export type InternalEvent = {
160
161
  | 'internal.client.meeting.interstitial-window.showed'
161
162
  | 'internal.client.interstitial-window.click.joinbutton'
162
163
  | 'internal.client.add-media.turn-discovery.start'
163
- | 'internal.client.add-media.turn-discovery.end';
164
+ | 'internal.client.add-media.turn-discovery.end'
165
+ | 'internal.client.share.initiated'
166
+ | 'internal.client.share.stopped';
164
167
 
165
168
  payload?: never;
166
169
  options?: never;
@@ -130,6 +130,96 @@ describe('internal-plugin-metrics', () => {
130
130
  assert.deepEqual(res2, undefined);
131
131
  });
132
132
 
133
+ describe('getDiffBetweenTimestamps with clamping', () => {
134
+ it('should apply default clamping (min: 0, max: 2147483647) when no clampValues provided', () => {
135
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
136
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
137
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed');
138
+ assert.deepEqual(res, 40);
139
+ });
140
+
141
+ it('should return diff without clamping when value is within range', () => {
142
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
143
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
144
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
145
+ minimum: 0,
146
+ maximum: 100
147
+ });
148
+ assert.deepEqual(res, 40);
149
+ });
150
+
151
+ it('should clamp to minimum when diff is below minimum', () => {
152
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 50});
153
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 45});
154
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
155
+ minimum: 10,
156
+ maximum: 100
157
+ });
158
+ assert.deepEqual(res, 10);
159
+ });
160
+
161
+ it('should clamp to maximum when diff is above maximum', () => {
162
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
163
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 210});
164
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
165
+ minimum: 0,
166
+ maximum: 100
167
+ });
168
+ assert.deepEqual(res, 100);
169
+ });
170
+
171
+ it('should use default minimum of 0 when only maximum is specified', () => {
172
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 50});
173
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 45});
174
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
175
+ maximum: 100
176
+ });
177
+ assert.deepEqual(res, 0);
178
+ });
179
+
180
+ it('should not clamp maximum when maximum is undefined', () => {
181
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
182
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 2000});
183
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
184
+ minimum: 5
185
+ });
186
+ assert.deepEqual(res, 1990);
187
+ });
188
+
189
+ it('should handle negative differences correctly with clamping', () => {
190
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 100});
191
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
192
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
193
+ minimum: 10,
194
+ maximum: 1000
195
+ });
196
+ assert.deepEqual(res, 10);
197
+ });
198
+
199
+ it('should return undefined when timestamps are missing even with clamping', () => {
200
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
201
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
202
+ minimum: 0,
203
+ maximum: 100
204
+ });
205
+ assert.deepEqual(res, undefined);
206
+ });
207
+
208
+ it('should apply default minimum clamping (0) when no clampValues provided and diff is negative', () => {
209
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 100});
210
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
211
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed');
212
+ assert.deepEqual(res, 0);
213
+ });
214
+
215
+ it('should clamp the value when a number greater than 2147483647', () => {
216
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 0});
217
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 2147483648});
218
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed');
219
+ assert.deepEqual(res, 2147483647);
220
+ });
221
+ });
222
+
133
223
  it('calculates getMeetingInfoReqResp correctly', () => {
134
224
  cdl.saveTimestamp({key: 'internal.client.meetinginfo.request', value: 10});
135
225
  cdl.saveTimestamp({key: 'internal.client.meetinginfo.response', value: 20});
@@ -227,6 +317,12 @@ describe('internal-plugin-metrics', () => {
227
317
 
228
318
  assert.deepEqual(cdl.getRefreshCaptchaReqResp(), 321);
229
319
  });
320
+
321
+ it('returns the correct number when it is greater than 2147483647', () => {
322
+ cdl.saveLatency('internal.refresh.captcha.time', 4294967400);
323
+
324
+ assert.deepEqual(cdl.getRefreshCaptchaReqResp(), 2147483647);
325
+ });
230
326
  });
231
327
 
232
328
  describe('getReachabilityClustersReqResp', () => {
@@ -245,6 +341,12 @@ describe('internal-plugin-metrics', () => {
245
341
 
246
342
  assert.deepEqual(cdl.getReachabilityClustersReqResp(), 321);
247
343
  });
344
+
345
+ it('returns the correct number when it is greater than 2147483647', () => {
346
+ cdl.saveLatency('internal.get.cluster.time', 4294967400);
347
+
348
+ assert.deepEqual(cdl.getReachabilityClustersReqResp(), 2147483647);
349
+ });
248
350
  });
249
351
 
250
352
  describe('getExchangeCITokenJMT', () => {
@@ -263,6 +365,12 @@ describe('internal-plugin-metrics', () => {
263
365
 
264
366
  assert.deepEqual(cdl.getExchangeCITokenJMT(), 321);
265
367
  });
368
+
369
+ it('returns the correct number when it is greater than 2147483647', () => {
370
+ cdl.saveLatency('internal.exchange.ci.token.time', 4294967400);
371
+
372
+ assert.deepEqual(cdl.getExchangeCITokenJMT(), 2147483647);
373
+ });
266
374
  });
267
375
 
268
376
  describe('saveTimestamp', () => {
@@ -416,6 +524,11 @@ describe('internal-plugin-metrics', () => {
416
524
  assert.deepEqual(cdl.getPageJMT(), 10);
417
525
  });
418
526
 
527
+ it('calculates getPageJMT correctly when it is greater than MAX_INTEGER', () => {
528
+ cdl.saveLatency('internal.client.pageJMT', 2147483648);
529
+ assert.deepEqual(cdl.getPageJMT(), 2147483647);
530
+ });
531
+
419
532
  it('calculates getClickToInterstitial correctly', () => {
420
533
  cdl.saveTimestamp({
421
534
  key: 'internal.client.meeting.click.joinbutton',
@@ -446,6 +559,11 @@ describe('internal-plugin-metrics', () => {
446
559
  assert.deepEqual(cdl.getClickToInterstitial(), 0);
447
560
  });
448
561
 
562
+ it('calculates getClickToInterstitial without join button timestamp when it is greater than MAX_INTEGER', () => {
563
+ cdl.saveLatency('internal.click.to.interstitial', 2147483648);
564
+ assert.deepEqual(cdl.getClickToInterstitial(), 2147483647);
565
+ });
566
+
449
567
  it('calculates getClickToInterstitialWithUserDelay correctly', () => {
450
568
  cdl.saveTimestamp({
451
569
  key: 'internal.client.meeting.click.joinbutton',
@@ -476,6 +594,11 @@ describe('internal-plugin-metrics', () => {
476
594
  assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 0);
477
595
  });
478
596
 
597
+ it('calculates getClickToInterstitialWithUserDelay without join button timestamp when it is greater than MAX_INTEGER', () => {
598
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 2147483648);
599
+ assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 2147483647);
600
+ });
601
+
479
602
  it('calculates getInterstitialToJoinOK correctly', () => {
480
603
  cdl.saveTimestamp({
481
604
  key: 'internal.client.interstitial-window.click.joinbutton',
@@ -584,6 +707,19 @@ describe('internal-plugin-metrics', () => {
584
707
  assert.deepEqual(cdl.getTotalJMT(), undefined);
585
708
  });
586
709
 
710
+ it('calculates getTotalJMT correctly when it is greater than MAX_INTEGER', () => {
711
+ cdl.saveTimestamp({
712
+ key: 'internal.client.interstitial-window.click.joinbutton',
713
+ value: 5,
714
+ });
715
+ cdl.saveTimestamp({
716
+ key: 'client.locus.join.response',
717
+ value: 40,
718
+ });
719
+ cdl.saveLatency('internal.click.to.interstitial', 2147483648);
720
+ assert.deepEqual(cdl.getTotalJMT(), 2147483647);
721
+ });
722
+
587
723
  it('calculates getTotalJMTWithUserDelay correctly', () => {
588
724
  cdl.saveTimestamp({
589
725
  key: 'internal.client.interstitial-window.click.joinbutton',
@@ -656,6 +792,19 @@ describe('internal-plugin-metrics', () => {
656
792
  assert.deepEqual(cdl.getTotalJMTWithUserDelay(), undefined);
657
793
  });
658
794
 
795
+ it('calculates getTotalJMTWithUserDelay correctly when it is greater than MAX_INTEGER', () => {
796
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 2147483648);
797
+ cdl.saveTimestamp({
798
+ key: 'internal.client.interstitial-window.click.joinbutton',
799
+ value: 20,
800
+ });
801
+ cdl.saveTimestamp({
802
+ key: 'client.locus.join.response',
803
+ value: 40,
804
+ });
805
+ assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 2147483647);
806
+ });
807
+
659
808
  it('calculates getTotalMediaJMT correctly', () => {
660
809
  cdl.saveTimestamp({
661
810
  key: 'internal.client.meeting.click.joinbutton',
@@ -692,6 +841,42 @@ describe('internal-plugin-metrics', () => {
692
841
  assert.deepEqual(cdl.getTotalMediaJMT(), 27);
693
842
  });
694
843
 
844
+ it('calculates getTotalMediaJMT correctly when it is greater than MAX_INTEGER', () => {
845
+ cdl.saveTimestamp({
846
+ key: 'internal.client.meeting.click.joinbutton',
847
+ value: 5,
848
+ });
849
+ cdl.saveTimestamp({
850
+ key: 'internal.client.meeting.interstitial-window.showed',
851
+ value: 8,
852
+ });
853
+ cdl.saveTimestamp({
854
+ key: 'internal.client.interstitial-window.click.joinbutton',
855
+ value: 10,
856
+ });
857
+ cdl.saveTimestamp({
858
+ key: 'client.locus.join.request',
859
+ value: 12,
860
+ });
861
+ cdl.saveTimestamp({
862
+ key: 'client.locus.join.response',
863
+ value: 2147483700,
864
+ });
865
+ cdl.saveTimestamp({
866
+ key: 'internal.host.meeting.participant.admitted',
867
+ value: 2147483800,
868
+ });
869
+ cdl.saveTimestamp({
870
+ key: 'client.ice.start',
871
+ value: 30,
872
+ });
873
+ cdl.saveTimestamp({
874
+ key: 'client.ice.end',
875
+ value: 100,
876
+ });
877
+ assert.deepEqual(cdl.getTotalMediaJMT(), 2147483647);
878
+ });
879
+
695
880
  it('calculates getTotalMediaJMT correctly with allowMediaInLobby true', () => {
696
881
  cdl.saveTimestamp({
697
882
  key: 'internal.client.meeting.click.joinbutton',
@@ -729,6 +914,43 @@ describe('internal-plugin-metrics', () => {
729
914
  assert.deepEqual(cdl.getTotalMediaJMT(), 31);
730
915
  });
731
916
 
917
+ it('calculates getTotalMediaJMT correctly with allowMediaInLobby true and it is greater than MAX_INTEGER', () => {
918
+ cdl.saveTimestamp({
919
+ key: 'internal.client.meeting.click.joinbutton',
920
+ value: 5,
921
+ options: {meetingId: 'meeting-id'},
922
+ });
923
+ cdl.saveTimestamp({
924
+ key: 'internal.client.meeting.interstitial-window.showed',
925
+ value: 100,
926
+ });
927
+ cdl.saveTimestamp({
928
+ key: 'internal.client.interstitial-window.click.joinbutton',
929
+ value: 1000,
930
+ });
931
+ cdl.saveTimestamp({
932
+ key: 'client.locus.join.request',
933
+ value: 2000,
934
+ });
935
+ cdl.saveTimestamp({
936
+ key: 'client.locus.join.response',
937
+ value: 2147483700,
938
+ });
939
+ cdl.saveTimestamp({
940
+ key: 'internal.host.meeting.participant.admitted',
941
+ value: 2147483800,
942
+ });
943
+ cdl.saveTimestamp({
944
+ key: 'client.ice.start',
945
+ value: 2147483900,
946
+ });
947
+ cdl.saveTimestamp({
948
+ key: 'client.ice.end',
949
+ value: 4294967400,
950
+ });
951
+ assert.deepEqual(cdl.getTotalMediaJMT(), 2147483647);
952
+ });
953
+
732
954
  it('calculates getTotalMediaJMTWithUserDelay correctly', () => {
733
955
  cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 7);
734
956
  cdl.saveTimestamp({
@@ -814,6 +1036,28 @@ describe('internal-plugin-metrics', () => {
814
1036
  assert.deepEqual(cdl.getJoinConfJMT(), 20);
815
1037
  });
816
1038
 
1039
+ it('calculates getJoinConfJMT correctly when it is greater than MAX_INTEGER', () => {
1040
+ // Since both getJoinReqResp and getICESetupTime are individually clamped to 1200000,
1041
+ // the maximum possible sum is 2400000, which is less than MAX_INTEGER (2147483647).
1042
+ // This test should verify that the final clamping works by mocking the intermediate methods
1043
+ // to return values that would sum to more than MAX_INTEGER.
1044
+
1045
+ const originalGetJoinReqResp = cdl.getJoinReqResp;
1046
+ const originalGetICESetupTime = cdl.getICESetupTime;
1047
+
1048
+ // Mock the methods to return large values that would exceed MAX_INTEGER when summed
1049
+ cdl.getJoinReqResp = () => 1500000000;
1050
+ cdl.getICESetupTime = () => 1000000000;
1051
+
1052
+ const result = cdl.getJoinConfJMT();
1053
+
1054
+ // Restore original methods
1055
+ cdl.getJoinReqResp = originalGetJoinReqResp;
1056
+ cdl.getICESetupTime = originalGetICESetupTime;
1057
+
1058
+ assert.deepEqual(result, 2147483647);
1059
+ });
1060
+
817
1061
  it('calculates getClientJMT correctly', () => {
818
1062
  cdl.saveTimestamp({
819
1063
  key: 'internal.client.interstitial-window.click.joinbutton',
@@ -906,6 +1150,26 @@ describe('internal-plugin-metrics', () => {
906
1150
  assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 8);
907
1151
  });
908
1152
 
1153
+ it('calculates getInterstitialToMediaOKJMT correctly when it is greater than MAX_INTEGER', () => {
1154
+ cdl.saveTimestamp({
1155
+ key: 'internal.client.interstitial-window.click.joinbutton',
1156
+ value: 4,
1157
+ });
1158
+ cdl.saveTimestamp({
1159
+ key: 'client.locus.join.response',
1160
+ value: 10,
1161
+ });
1162
+ cdl.saveTimestamp({
1163
+ key: 'internal.host.meeting.participant.admitted',
1164
+ value: 12,
1165
+ });
1166
+ cdl.saveTimestamp({
1167
+ key: 'client.ice.end',
1168
+ value: 2147483700,
1169
+ });
1170
+ assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 2147483647);
1171
+ });
1172
+
909
1173
  it('calculates getInterstitialToMediaOKJMT correctly without lobby', () => {
910
1174
  cdl.saveTimestamp({
911
1175
  key: 'internal.client.interstitial-window.click.joinbutton',
@@ -918,6 +1182,18 @@ describe('internal-plugin-metrics', () => {
918
1182
  assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
919
1183
  });
920
1184
 
1185
+ it('calculates getShareDuration correctly', () => {
1186
+ cdl.saveTimestamp({
1187
+ key: 'internal.client.share.initiated',
1188
+ value: 5,
1189
+ });
1190
+ cdl.saveTimestamp({
1191
+ key: 'internal.client.share.stopped',
1192
+ value: 7,
1193
+ });
1194
+ assert.deepEqual(cdl.getShareDuration(), 2);
1195
+ });
1196
+
921
1197
  describe('calculates getU2CTime correctly', () => {
922
1198
  it('returns undefined when no precomputed value available', () => {
923
1199
  assert.deepEqual(cdl.getU2CTime(), undefined);
@@ -941,6 +1217,11 @@ describe('internal-plugin-metrics', () => {
941
1217
  assert.deepEqual(cdl.getDownloadTimeJMT(), 1000);
942
1218
  });
943
1219
 
1220
+ it('calculates getDownloadTimeJMT correctly when it is greater than MAX_INTEGER', () => {
1221
+ cdl.saveLatency('internal.download.time', 2147483648);
1222
+ assert.deepEqual(cdl.getDownloadTimeJMT(), 2147483647);
1223
+ });
1224
+
944
1225
  describe('getOtherAppApiReqResp', () => {
945
1226
  it('returns undefined when no precomputed value available', () => {
946
1227
  assert.deepEqual(cdl.getOtherAppApiReqResp(), undefined);
@@ -963,6 +1244,12 @@ describe('internal-plugin-metrics', () => {
963
1244
 
964
1245
  assert.deepEqual(cdl.getOtherAppApiReqResp(), 321);
965
1246
  });
1247
+
1248
+ it('returns the correct number when it is greater than 2147483647', () => {
1249
+ cdl.saveLatency('internal.other.app.api.time', 4294967400);
1250
+
1251
+ assert.deepEqual(cdl.getOtherAppApiReqResp(), 2147483647);
1252
+ });
966
1253
  });
967
1254
  });
968
1255
  });