@webex/internal-plugin-metrics 3.0.0-next.1 → 3.0.0-next.10

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 (31) hide show
  1. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +90 -14
  2. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics.js +38 -29
  4. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +8 -1
  6. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/metrics.js +5 -1
  9. package/dist/metrics.js.map +1 -1
  10. package/dist/metrics.types.js.map +1 -1
  11. package/dist/new-metrics.js +5 -4
  12. package/dist/new-metrics.js.map +1 -1
  13. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +41 -8
  14. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +8 -10
  15. package/dist/types/index.d.ts +2 -2
  16. package/dist/types/metrics.types.d.ts +3 -1
  17. package/package.json +13 -13
  18. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +89 -13
  19. package/src/call-diagnostic/call-diagnostic-metrics.ts +13 -0
  20. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +8 -1
  21. package/src/index.ts +2 -0
  22. package/src/metrics.js +3 -0
  23. package/src/metrics.types.ts +12 -1
  24. package/src/new-metrics.ts +2 -2
  25. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +18 -7
  26. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +199 -1
  27. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +119 -24
  28. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +11 -2
  29. package/test/unit/spec/metrics.js +8 -0
  30. package/test/unit/spec/new-metrics.ts +29 -31
  31. package/test/unit/spec/prelogin-metrics-batcher.ts +5 -2
@@ -16,6 +16,10 @@ export type ClientLaunchMethodType = NonNullable<
16
16
  RawEvent['origin']['clientInfo']
17
17
  >['clientLaunchMethod'];
18
18
 
19
+ export type BrowserLaunchMethodType = NonNullable<
20
+ RawEvent['origin']['clientInfo']
21
+ >['browserLaunchMethod'];
22
+
19
23
  export type SubmitClientEventOptions = {
20
24
  meetingId?: string;
21
25
  mediaConnections?: any[];
@@ -25,6 +29,7 @@ export type SubmitClientEventOptions = {
25
29
  environment?: EnvironmentType;
26
30
  newEnvironmentType?: NewEnvironmentType;
27
31
  clientLaunchMethod?: ClientLaunchMethodType;
32
+ browserLaunchMethod?: BrowserLaunchMethodType;
28
33
  webexConferenceIdStr?: string;
29
34
  globalMeetingId?: string;
30
35
  };
@@ -164,5 +169,11 @@ export type BuildClientEventFetchRequestOptions = (args: {
164
169
  export type PreComputedLatencies =
165
170
  | 'internal.client.pageJMT'
166
171
  | 'internal.download.time'
172
+ | 'internal.get.cluster.time'
167
173
  | 'internal.click.to.interstitial'
168
- | 'internal.call.init.join.req';
174
+ | 'internal.refresh.captcha.time'
175
+ | 'internal.exchange.ci.token.time'
176
+ | 'internal.get.u2c.time'
177
+ | 'internal.call.init.join.req'
178
+ | 'internal.other.app.api.time'
179
+ | 'internal.api.fetch.intelligence.models';
@@ -43,6 +43,8 @@ class Metrics extends WebexPlugin {
43
43
  constructor(...args) {
44
44
  super(...args);
45
45
 
46
+ // @ts-ignore
47
+ this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});
46
48
  this.onReady();
47
49
  }
48
50
 
@@ -54,8 +56,6 @@ class Metrics extends WebexPlugin {
54
56
  this.webex.once('ready', () => {
55
57
  // @ts-ignore
56
58
  this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});
57
- // @ts-ignore
58
- this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});
59
59
  });
60
60
  }
61
61
 
@@ -103,6 +103,12 @@ describe('plugin-metrics', () => {
103
103
  webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
104
104
  .stub()
105
105
  .returns(10);
106
+ webex.internal.newMetrics.callDiagnosticLatencies.getRefreshCaptchaReqResp = sinon
107
+ .stub()
108
+ .returns(10);
109
+ webex.internal.newMetrics.callDiagnosticLatencies.getDownloadIntelligenceModelsReqResp =
110
+ sinon.stub().returns(42);
111
+
106
112
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
107
113
  //@ts-ignore
108
114
  {event: {name: 'client.interstitial-window.launched'}}
@@ -119,6 +125,8 @@ describe('plugin-metrics', () => {
119
125
  joinTimes: {
120
126
  clickToInterstitial: 10,
121
127
  meetingInfoReqResp: 10,
128
+ refreshCaptchaServiceReqResp: 10,
129
+ downloadIntelligenceModelsReqResp: 42,
122
130
  },
123
131
  });
124
132
  assert.lengthOf(
@@ -131,6 +139,12 @@ describe('plugin-metrics', () => {
131
139
  webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
132
140
  .stub()
133
141
  .returns(10);
142
+ webex.internal.newMetrics.callDiagnosticLatencies.getU2CTime = sinon
143
+ .stub()
144
+ .returns(20);
145
+ webex.internal.newMetrics.callDiagnosticLatencies.getReachabilityClustersReqResp = sinon
146
+ .stub()
147
+ .returns(10);
134
148
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
135
149
  //@ts-ignore
136
150
  {event: {name: 'client.call.initiated'}}
@@ -147,6 +161,8 @@ describe('plugin-metrics', () => {
147
161
  meetingInfoReqResp: 10,
148
162
  registerWDMDeviceJMT: 10,
149
163
  showInterstitialTime: 10,
164
+ getU2CTime: 20,
165
+ getReachabilityClustersReqResp: 10
150
166
  },
151
167
  });
152
168
  assert.lengthOf(
@@ -159,9 +175,6 @@ describe('plugin-metrics', () => {
159
175
  webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
160
176
  .stub()
161
177
  .returns(10);
162
- webex.internal.newMetrics.callDiagnosticLatencies.getJoinRespSentReceived = sinon
163
- .stub()
164
- .returns(20);
165
178
  webex.internal.newMetrics.callDiagnosticLatencies.getPageJMT = sinon.stub().returns(30);
166
179
  webex.internal.newMetrics.callDiagnosticLatencies.getClientJMT = sinon.stub().returns(5);
167
180
  webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
@@ -191,7 +204,6 @@ describe('plugin-metrics', () => {
191
204
  clickToInterstitial: 10,
192
205
  interstitialToJoinOK: 10,
193
206
  joinReqResp: 10,
194
- joinReqSentReceived: 20,
195
207
  meetingInfoReqResp: 10,
196
208
  pageJmt: 30,
197
209
  totalJmt: 20,
@@ -357,9 +369,8 @@ describe('plugin-metrics', () => {
357
369
  });
358
370
  });
359
371
 
360
- //TODO: The following two skipped tests needs investigation: https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-485382
361
372
  describe('when the request fails', () => {
362
- it.skip('does not clear the queue', async () => {
373
+ it('does not clear the queue', async () => {
363
374
  // avoid setting .sent timestamp
364
375
  webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.prepareRequest =
365
376
  (q) => Promise.resolve(q);
@@ -406,7 +417,7 @@ describe('plugin-metrics', () => {
406
417
  });
407
418
 
408
419
  describe('prepareItem', () => {
409
- it.skip('calls prepareDiagnosticMetricItem correctly', async () => {
420
+ it('calls prepareDiagnosticMetricItem correctly', async () => {
410
421
  // avoid setting .sent timestamp
411
422
  webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.prepareRequest =
412
423
  (q) => Promise.resolve(q);
@@ -41,11 +41,41 @@ describe('internal-plugin-metrics', () => {
41
41
  assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), now.getTime());
42
42
  });
43
43
 
44
- it('should save latency correctly', () => {
44
+ it('should save latency correctly by default and overwrites', () => {
45
45
  assert.deepEqual(cdl.precomputedLatencies.size, 0);
46
46
  cdl.saveLatency('internal.client.pageJMT', 10);
47
47
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
48
48
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
49
+ cdl.saveLatency('internal.client.pageJMT', 20);
50
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
51
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
52
+ });
53
+
54
+ it('should overwrite latency when accumulate is false', () => {
55
+ assert.deepEqual(cdl.precomputedLatencies.size, 0);
56
+ cdl.saveLatency('internal.client.pageJMT', 10, false);
57
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
58
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
59
+ cdl.saveLatency('internal.client.pageJMT', 20, false);
60
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
61
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
62
+ });
63
+
64
+ it('should save latency correctly when accumulate is true', () => {
65
+ assert.deepEqual(cdl.precomputedLatencies.size, 0);
66
+ cdl.saveLatency('internal.client.pageJMT', 10, true);
67
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
68
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
69
+ });
70
+
71
+ it('should save latency correctly when accumulate is true and there is existing value', () => {
72
+ assert.deepEqual(cdl.precomputedLatencies.size, 0);
73
+ cdl.saveLatency('internal.client.pageJMT', 10);
74
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
75
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
76
+ cdl.saveLatency('internal.client.pageJMT', 10, true);
77
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
78
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
49
79
  });
50
80
 
51
81
  it('should save only first timestamp correctly', () => {
@@ -78,8 +108,13 @@ describe('internal-plugin-metrics', () => {
78
108
  cdl.saveTimestamp({key: 'client.alert.displayed'});
79
109
  cdl.saveTimestamp({key: 'client.alert.removed'});
80
110
  assert.deepEqual(cdl.latencyTimestamps.size, 2);
111
+ cdl.saveLatency('internal.api.fetch.intelligence.models', 42);
112
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
113
+
81
114
  cdl.clearTimestamps();
115
+
82
116
  assert.deepEqual(cdl.latencyTimestamps.size, 0);
117
+ assert.deepEqual(cdl.precomputedLatencies.size, 0);
83
118
  });
84
119
 
85
120
  it('should calculate diff between timestamps correctly', () => {
@@ -111,6 +146,127 @@ describe('internal-plugin-metrics', () => {
111
146
  assert.deepEqual(cdl.getMeetingInfoReqResp(), 10);
112
147
  });
113
148
 
149
+ describe('measureLatency', () => {
150
+ let clock;
151
+ let saveLatencySpy;
152
+
153
+ beforeEach(() => {
154
+ clock = sinon.useFakeTimers();
155
+
156
+ saveLatencySpy = sinon.stub(cdl, 'saveLatency');
157
+ });
158
+
159
+ afterEach(() => {
160
+ clock.restore();
161
+ sinon.restore();
162
+ });
163
+
164
+ it('checks measureLatency with accumulate false', async () => {
165
+ const key = 'internal.client.pageJMT';
166
+ const accumulate = false;
167
+
168
+ const callbackStub = sinon.stub().callsFake(() => {
169
+ clock.tick(50);
170
+ return Promise.resolve('test');
171
+ });
172
+
173
+ // accumulate should be false by default
174
+ const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT');
175
+
176
+ const resolvedValue = await promise;
177
+ assert.deepEqual(resolvedValue, 'test');
178
+ assert.calledOnceWithExactly(callbackStub);
179
+ assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
180
+ });
181
+
182
+ it('checks measureLatency with accumulate true', async () => {
183
+ const key = 'internal.download.time';
184
+ const accumulate = true;
185
+ const callbackStub = sinon.stub().callsFake(() => {
186
+ clock.tick(20);
187
+ return Promise.resolve('test123');
188
+ });
189
+
190
+ const promise = cdl.measureLatency(callbackStub, 'internal.download.time', accumulate);
191
+
192
+ const resolvedValue = await promise;
193
+ assert.deepEqual(resolvedValue, 'test123');
194
+ assert.calledOnceWithExactly(callbackStub);
195
+ assert.calledOnceWithExactly(saveLatencySpy, key, 20, accumulate);
196
+ });
197
+
198
+ it('checks measureLatency when callBack rejects', async () => {
199
+ const key = 'internal.client.pageJMT';
200
+ const accumulate = false;
201
+ const error = new Error('some error');
202
+ const callbackStub = sinon.stub().callsFake(() => {
203
+ clock.tick(50);
204
+ return Promise.reject(error);
205
+ });
206
+
207
+ const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', accumulate);
208
+
209
+ const rejectedValue = await assert.isRejected(promise);
210
+ assert.deepEqual(rejectedValue, error);
211
+ assert.calledOnceWithExactly(callbackStub);
212
+ assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
213
+ });
214
+ });
215
+
216
+ describe('getRefreshCaptchaReqResp', () => {
217
+ it('returns undefined when no precomputed value available', () => {
218
+ assert.deepEqual(cdl.getRefreshCaptchaReqResp(), undefined);
219
+ });
220
+
221
+ it('returns the correct value', () => {
222
+ cdl.saveLatency('internal.refresh.captcha.time', 123);
223
+
224
+ assert.deepEqual(cdl.getRefreshCaptchaReqResp(), 123);
225
+ });
226
+
227
+ it('returns the correct whole number', () => {
228
+ cdl.saveLatency('internal.refresh.captcha.time', 321.44);
229
+
230
+ assert.deepEqual(cdl.getRefreshCaptchaReqResp(), 321);
231
+ });
232
+ });
233
+
234
+ describe('getReachabilityClustersReqResp', () => {
235
+ it('returns undefined when no precomputed value available', () => {
236
+ assert.deepEqual(cdl.getReachabilityClustersReqResp(), undefined);
237
+ });
238
+
239
+ it('returns the correct value', () => {
240
+ cdl.saveLatency('internal.get.cluster.time', 123);
241
+
242
+ assert.deepEqual(cdl.getReachabilityClustersReqResp(), 123);
243
+ });
244
+
245
+ it('returns the correct whole number', () => {
246
+ cdl.saveLatency('internal.get.cluster.time', 321.44);
247
+
248
+ assert.deepEqual(cdl.getReachabilityClustersReqResp(), 321);
249
+ });
250
+ });
251
+
252
+ describe('getExchangeCITokenJMT', () => {
253
+ it('returns undefined when no precomputed value available', () => {
254
+ assert.deepEqual(cdl.getExchangeCITokenJMT(), undefined);
255
+ });
256
+
257
+ it('returns the correct value', () => {
258
+ cdl.saveLatency('internal.exchange.ci.token.time', 123);
259
+
260
+ assert.deepEqual(cdl.getExchangeCITokenJMT(), 123);
261
+ });
262
+
263
+ it('returns the correct whole number', () => {
264
+ cdl.saveLatency('internal.exchange.ci.token.time', 321.44);
265
+
266
+ assert.deepEqual(cdl.getExchangeCITokenJMT(), 321);
267
+ });
268
+ });
269
+
114
270
  describe('saveTimestamp', () => {
115
271
  afterEach(() => {
116
272
  sinon.restore();
@@ -512,9 +668,51 @@ describe('internal-plugin-metrics', () => {
512
668
  assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
513
669
  });
514
670
 
671
+ it('calculates getU2CTime correctly', () => {
672
+ it('returns undefined when no precomputed value available', () => {
673
+ assert.deepEqual(cdl.getU2CTime(), undefined);
674
+ });
675
+
676
+ it('returns the correct value', () => {
677
+ cdl.saveLatency('internal.get.u2c.time', 123);
678
+
679
+ assert.deepEqual(cdl.getU2CTime(), 123);
680
+ });
681
+
682
+ it('returns the correct whole number', () => {
683
+ cdl.saveLatency('internal.get.u2c.time', 321.44);
684
+
685
+ assert.deepEqual(cdl.getU2CTime(), 321);
686
+ });
687
+ });
688
+
515
689
  it('calculates getDownloadTimeJMT correctly', () => {
516
690
  cdl.saveLatency('internal.download.time', 1000);
517
691
  assert.deepEqual(cdl.getDownloadTimeJMT(), 1000);
518
692
  });
693
+
694
+ describe('getOtherAppApiReqResp', () => {
695
+ it('returns undefined when no precomputed value available', () => {
696
+ assert.deepEqual(cdl.getOtherAppApiReqResp(), undefined);
697
+ });
698
+
699
+ it('returns undefined if it is less than 0', () => {
700
+ cdl.saveLatency('internal.other.app.api.time', 0);
701
+
702
+ assert.deepEqual(cdl.getOtherAppApiReqResp(), undefined);
703
+ });
704
+
705
+ it('returns the correct value', () => {
706
+ cdl.saveLatency('internal.other.app.api.time', 123);
707
+
708
+ assert.deepEqual(cdl.getOtherAppApiReqResp(), 123);
709
+ });
710
+
711
+ it('returns the correct whole number', () => {
712
+ cdl.saveLatency('internal.other.app.api.time', 321.44);
713
+
714
+ assert.deepEqual(cdl.getOtherAppApiReqResp(), 321);
715
+ });
716
+ });
519
717
  });
520
718
  });
@@ -223,6 +223,43 @@ describe('internal-plugin-metrics', () => {
223
223
  });
224
224
  });
225
225
 
226
+ it('should build origin correctly with browserLaunchMethod', () => {
227
+ sinon.stub(CallDiagnosticUtils, 'anonymizeIPAddress').returns('1.1.1.1');
228
+
229
+ //@ts-ignore
230
+ const res = cd.getOrigin(
231
+ {
232
+ subClientType: 'WEB_APP',
233
+ clientType: 'TEAMS_CLIENT',
234
+ newEnvironment: 'test-new-env',
235
+ clientLaunchMethod: 'url-handler',
236
+ browserLaunchMethod: 'thinclient',
237
+ },
238
+ fakeMeeting.id
239
+ );
240
+
241
+ assert.deepEqual(res, {
242
+ clientInfo: {
243
+ browser: getBrowserName(),
244
+ browserVersion: getBrowserVersion(),
245
+ clientType: 'TEAMS_CLIENT',
246
+ clientVersion: 'webex-js-sdk/webex-version',
247
+ publicNetworkPrefix: '1.1.1.1',
248
+ localNetworkPrefix: '1.1.1.1',
249
+ os: getOSNameInternal(),
250
+ osVersion: getOSVersion(),
251
+ subClientType: 'WEB_APP',
252
+ clientLaunchMethod: 'url-handler',
253
+ browserLaunchMethod: 'thinclient',
254
+ },
255
+ environment: 'meeting_evn',
256
+ newEnvironment: 'test-new-env',
257
+ name: 'endpoint',
258
+ networkType: 'unknown',
259
+ userAgent,
260
+ });
261
+ });
262
+
226
263
  it('should build origin correctly with no meeting', () => {
227
264
  sinon.stub(CallDiagnosticUtils, 'anonymizeIPAddress').returns('1.1.1.1');
228
265
 
@@ -302,6 +339,11 @@ describe('internal-plugin-metrics', () => {
302
339
 
303
340
  describe('#getIdentifiers', () => {
304
341
  it('should build identifiers correctly', () => {
342
+ webex.internal.device = {
343
+ ...webex.internal.device,
344
+ config: {installationId: 'installationId'},
345
+ };
346
+
305
347
  const res = cd.getIdentifiers({
306
348
  mediaConnections: [
307
349
  {mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
@@ -315,6 +357,7 @@ describe('internal-plugin-metrics', () => {
315
357
  locusId: 'url',
316
358
  locusStartTime: 'lastActive',
317
359
  locusUrl: 'locus/url',
360
+ machineId: 'installationId',
318
361
  mediaAgentAlias: 'mediaAgentAlias',
319
362
  mediaAgentGroupId: 'mediaAgentGroupId',
320
363
  orgId: 'orgId',
@@ -498,7 +541,10 @@ describe('internal-plugin-metrics', () => {
498
541
  it('should prepare diagnostic event successfully', () => {
499
542
  const options = {meetingId: fakeMeeting.id};
500
543
  const getOriginStub = sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
501
- const clearEmptyKeysRecursivelyStub = sinon.stub(CallDiagnosticUtils, 'clearEmptyKeysRecursively');
544
+ const clearEmptyKeysRecursivelyStub = sinon.stub(
545
+ CallDiagnosticUtils,
546
+ 'clearEmptyKeysRecursively'
547
+ );
502
548
 
503
549
  const res = cd.prepareDiagnosticEvent(
504
550
  {
@@ -715,7 +761,7 @@ describe('internal-plugin-metrics', () => {
715
761
  ]);
716
762
  });
717
763
 
718
- it('should submit client event successfully with correlationId, webexConferenceIdStr and globalMeetingId', async () => {
764
+ it('should submit client event successfully with correlationId, webexConferenceIdStr and globalMeetingId', () => {
719
765
  const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
720
766
  const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
721
767
  const generateClientEventErrorPayloadSpy = sinon.spy(cd, 'generateClientEventErrorPayload');
@@ -853,11 +899,13 @@ describe('internal-plugin-metrics', () => {
853
899
  options
854
900
  );
855
901
  assert.notCalled(submitToCallDiagnosticsSpy);
856
- assert.calledWith(submitToCallDiagnosticsPreLoginSpy, {
902
+ assert.calledWith(
903
+ submitToCallDiagnosticsPreLoginSpy,
904
+ {
857
905
  eventId: 'my-fake-id',
858
906
  version: 1,
859
- origin: { origin: 'fake-origin' },
860
- originTime: { triggered: now.toISOString(), sent: 'not_defined_yet' },
907
+ origin: {origin: 'fake-origin'},
908
+ originTime: {triggered: now.toISOString(), sent: 'not_defined_yet'},
861
909
  senderCountryCode: 'UK',
862
910
  event: {
863
911
  name: 'client.alert.displayed',
@@ -869,12 +917,14 @@ describe('internal-plugin-metrics', () => {
869
917
  orgId: 'orgId',
870
918
  locusUrl: 'locus-url',
871
919
  webexConferenceIdStr: 'webexConferenceIdStr1',
872
- globalMeetingId: 'globalMeetingId1'
920
+ globalMeetingId: 'globalMeetingId1',
873
921
  },
874
- eventData: { webClientDomain: 'whatever' },
875
- loginType: 'login-ci'
922
+ eventData: {webClientDomain: 'whatever'},
923
+ loginType: 'login-ci',
876
924
  },
877
- }, options.preLoginId);
925
+ },
926
+ options.preLoginId
927
+ );
878
928
  });
879
929
 
880
930
  it('should use meeting loginType if present and meetingId provided', () => {
@@ -1339,7 +1389,7 @@ describe('internal-plugin-metrics', () => {
1339
1389
  });
1340
1390
  });
1341
1391
 
1342
- describe("#submitToCallDiagnostics", () => {
1392
+ describe('#submitToCallDiagnostics', () => {
1343
1393
  it('should send request to call diagnostic batcher', () => {
1344
1394
  const requestStub = sinon.stub();
1345
1395
  //@ts-ignore
@@ -1348,7 +1398,7 @@ describe('internal-plugin-metrics', () => {
1348
1398
  cd.submitToCallDiagnostics({event: 'test'});
1349
1399
  assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
1350
1400
  });
1351
- })
1401
+ });
1352
1402
 
1353
1403
  describe('#submitMQE', () => {
1354
1404
  it('submits the event correctly', () => {
@@ -1801,6 +1851,27 @@ describe('internal-plugin-metrics', () => {
1801
1851
  });
1802
1852
  });
1803
1853
 
1854
+ it('should override custom properties for an unknown error', () => {
1855
+ const error = new Error('bad times');
1856
+
1857
+ (error as any).payloadOverrides = {
1858
+ shownToUser: true,
1859
+ category: 'expected',
1860
+ };
1861
+
1862
+ const res = cd.generateClientEventErrorPayload(error);
1863
+ assert.deepEqual(res, {
1864
+ category: 'expected',
1865
+ errorDescription: 'UnknownError',
1866
+ fatal: true,
1867
+ name: 'other',
1868
+ shownToUser: true,
1869
+ serviceErrorCode: 9999,
1870
+ errorCode: 9999,
1871
+ rawErrorMessage: 'bad times',
1872
+ });
1873
+ });
1874
+
1804
1875
  it('should override custom properties for a NetworkOrCORSError', () => {
1805
1876
  const error = new WebexHttpError.NetworkOrCORSError({
1806
1877
  url: 'https://example.com',
@@ -1942,12 +2013,16 @@ describe('internal-plugin-metrics', () => {
1942
2013
 
1943
2014
  describe('httpStatusCode', () => {
1944
2015
  it('should include httpStatusCode for browser media errors', () => {
1945
- const res = cd.generateClientEventErrorPayload({name: 'PermissionDeniedError', message: 'bad times', statusCode: 401});
2016
+ const res = cd.generateClientEventErrorPayload({
2017
+ name: 'PermissionDeniedError',
2018
+ message: 'bad times',
2019
+ statusCode: 401,
2020
+ });
1946
2021
  assert.deepEqual(res, {
1947
2022
  category: 'expected',
1948
2023
  errorCode: 4032,
1949
2024
  errorData: {
1950
- errorName: 'PermissionDeniedError'
2025
+ errorName: 'PermissionDeniedError',
1951
2026
  },
1952
2027
  errorDescription: 'CameraPermissionDenied',
1953
2028
  fatal: true,
@@ -1960,12 +2035,16 @@ describe('internal-plugin-metrics', () => {
1960
2035
  });
1961
2036
 
1962
2037
  it('should include httpStatusCode for SdpOfferCreationErrors', () => {
1963
- const res = cd.generateClientEventErrorPayload({name: 'SdpOfferCreationError', message: 'bad times', statusCode: 404});
2038
+ const res = cd.generateClientEventErrorPayload({
2039
+ name: 'SdpOfferCreationError',
2040
+ message: 'bad times',
2041
+ statusCode: 404,
2042
+ });
1964
2043
  assert.deepEqual(res, {
1965
2044
  category: 'media',
1966
2045
  errorCode: 2050,
1967
2046
  errorData: {
1968
- errorName: 'SdpOfferCreationError'
2047
+ errorName: 'SdpOfferCreationError',
1969
2048
  },
1970
2049
  errorDescription: 'SdpOfferCreationError',
1971
2050
  fatal: true,
@@ -1978,7 +2057,11 @@ describe('internal-plugin-metrics', () => {
1978
2057
  });
1979
2058
 
1980
2059
  it('should include httpStatusCode for service error codes', () => {
1981
- const res = cd.generateClientEventErrorPayload({body: {errorCode: 58400}, message: 'bad times', statusCode: 400});
2060
+ const res = cd.generateClientEventErrorPayload({
2061
+ body: {errorCode: 58400},
2062
+ message: 'bad times',
2063
+ statusCode: 400,
2064
+ });
1982
2065
  assert.deepEqual(res, {
1983
2066
  category: 'signaling',
1984
2067
  errorCode: 4100,
@@ -1993,7 +2076,11 @@ describe('internal-plugin-metrics', () => {
1993
2076
  });
1994
2077
 
1995
2078
  it('should include httpStatusCode for locus service error codes', () => {
1996
- const res = cd.generateClientEventErrorPayload({body: {errorCode: 2403001}, message: 'bad times', statusCode: 400});
2079
+ const res = cd.generateClientEventErrorPayload({
2080
+ body: {errorCode: 2403001},
2081
+ message: 'bad times',
2082
+ statusCode: 400,
2083
+ });
1997
2084
  assert.deepEqual(res, {
1998
2085
  category: 'expected',
1999
2086
  errorCode: 3007,
@@ -2008,7 +2095,11 @@ describe('internal-plugin-metrics', () => {
2008
2095
  });
2009
2096
 
2010
2097
  it('should include httpStatusCode for meetingInfo service error codes', () => {
2011
- const res = cd.generateClientEventErrorPayload({body: {data: {meetingInfo: {}}}, message: 'bad times', statusCode: 400});
2098
+ const res = cd.generateClientEventErrorPayload({
2099
+ body: {data: {meetingInfo: {}}},
2100
+ message: 'bad times',
2101
+ statusCode: 400,
2102
+ });
2012
2103
  assert.deepEqual(res, {
2013
2104
  category: 'signaling',
2014
2105
  errorCode: 4100,
@@ -2023,8 +2114,10 @@ describe('internal-plugin-metrics', () => {
2023
2114
  });
2024
2115
 
2025
2116
  it('should include httpStatusCode for network errors', () => {
2026
- const error = new WebexHttpError.NetworkOrCORSError(
2027
- {statusCode: 400, options: {service: '', headers: {}}});
2117
+ const error = new WebexHttpError.NetworkOrCORSError({
2118
+ statusCode: 400,
2119
+ options: {service: '', headers: {}},
2120
+ });
2028
2121
  const res = cd.generateClientEventErrorPayload(error);
2029
2122
  assert.deepEqual(res, {
2030
2123
  category: 'network',
@@ -2040,8 +2133,10 @@ describe('internal-plugin-metrics', () => {
2040
2133
  });
2041
2134
 
2042
2135
  it('should include httpStatusCode for unauthorized errors', () => {
2043
- const error = new WebexHttpError.Unauthorized(
2044
- {statusCode: 401, options: {service: '', headers: {}}});
2136
+ const error = new WebexHttpError.Unauthorized({
2137
+ statusCode: 401,
2138
+ options: {service: '', headers: {}},
2139
+ });
2045
2140
  const res = cd.generateClientEventErrorPayload(error);
2046
2141
  assert.deepEqual(res, {
2047
2142
  category: 'network',
@@ -2244,7 +2339,7 @@ describe('internal-plugin-metrics', () => {
2244
2339
  });
2245
2340
  });
2246
2341
 
2247
- describe("#submitToCallDiagnosticsPreLogin", () => {
2342
+ describe('#submitToCallDiagnosticsPreLogin', () => {
2248
2343
  it('should send request to call diagnostic batcher and saves preLoginId', () => {
2249
2344
  const requestStub = sinon.stub();
2250
2345
  //@ts-ignore
@@ -2257,7 +2352,7 @@ describe('internal-plugin-metrics', () => {
2257
2352
  assert.calledWith(cd.preLoginMetricsBatcher.savePreLoginId, preLoginId);
2258
2353
  assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
2259
2354
  });
2260
- })
2355
+ });
2261
2356
 
2262
2357
  describe('#isServiceErrorExpected', () => {
2263
2358
  it('returns true for code mapped to "expected"', () => {