@webex/internal-plugin-metrics 3.0.0-next.9 → 3.1.0-next.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 (32) hide show
  1. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +33 -9
  2. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics.js +1 -0
  4. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +4 -2
  6. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  7. package/dist/client-metrics-prelogin-batcher.js +32 -0
  8. package/dist/client-metrics-prelogin-batcher.js.map +1 -0
  9. package/dist/metrics.js +6 -25
  10. package/dist/metrics.js.map +1 -1
  11. package/dist/metrics.types.js.map +1 -1
  12. package/dist/prelogin-metrics-batcher.js +1 -1
  13. package/dist/prelogin-metrics-batcher.js.map +1 -1
  14. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +18 -7
  15. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +2 -2
  16. package/dist/types/client-metrics-prelogin-batcher.d.ts +2 -0
  17. package/dist/types/metrics.types.d.ts +1 -1
  18. package/package.json +12 -12
  19. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +36 -10
  20. package/src/call-diagnostic/call-diagnostic-metrics.ts +1 -0
  21. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +11 -2
  22. package/src/client-metrics-prelogin-batcher.ts +26 -0
  23. package/src/metrics.js +5 -23
  24. package/src/metrics.types.ts +3 -1
  25. package/src/prelogin-metrics-batcher.ts +1 -1
  26. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +9 -1
  27. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +47 -22
  28. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +57 -23
  29. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +27 -13
  30. package/test/unit/spec/client-metrics-prelogin-batcher.ts +54 -0
  31. package/test/unit/spec/metrics.js +1 -31
  32. package/test/unit/spec/prelogin-metrics-batcher.ts +5 -3
@@ -252,6 +252,7 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
252
252
  joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
253
253
  joinTimes.clickToInterstitial = cdl.getClickToInterstitial();
254
254
  joinTimes.refreshCaptchaServiceReqResp = cdl.getRefreshCaptchaReqResp();
255
+ joinTimes.downloadIntelligenceModelsReqResp = cdl.getDownloadIntelligenceModelsReqResp();
255
256
  break;
256
257
 
257
258
  case 'client.call.initiated':
@@ -259,6 +260,7 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
259
260
  joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();
260
261
  joinTimes.registerWDMDeviceJMT = cdl.getRegisterWDMDeviceJMT();
261
262
  joinTimes.getU2CTime = cdl.getU2CTime();
263
+ joinTimes.getReachabilityClustersReqResp = cdl.getReachabilityClustersReqResp();
262
264
  break;
263
265
 
264
266
  case 'client.locus.join.response':
@@ -381,11 +383,18 @@ export const generateClientErrorCodeForIceFailure = ({
381
383
  errorCode = MISSING_ROAP_ANSWER_CLIENT_CODE;
382
384
  }
383
385
 
384
- if (signalingState === 'stable' && iceConnectionState === 'connected') {
386
+ if (
387
+ signalingState === 'stable' &&
388
+ (iceConnectionState === 'connected' || iceConnectionState === 'disconnected')
389
+ ) {
385
390
  errorCode = DTLS_HANDSHAKE_FAILED_CLIENT_CODE;
386
391
  }
387
392
 
388
- if (signalingState !== 'have-local-offer' && iceConnectionState !== 'connected') {
393
+ if (
394
+ signalingState !== 'have-local-offer' &&
395
+ iceConnectionState !== 'connected' &&
396
+ iceConnectionState !== 'disconnected'
397
+ ) {
389
398
  if (turnServerUsed) {
390
399
  errorCode = ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE;
391
400
  } else {
@@ -0,0 +1,26 @@
1
+ import PreLoginMetricsBatcher from './prelogin-metrics-batcher';
2
+
3
+ const ClientMetricsPreloginBatcher = PreLoginMetricsBatcher.extend({
4
+ namespace: 'Metrics',
5
+
6
+ /**
7
+ * Prepare item
8
+ * @param {any} item
9
+ * @returns {Promise<any>}
10
+ */
11
+ prepareItem(item) {
12
+ // Add more defaults to payload when the clientmetrics endpoint evolves to support richer payloads
13
+ return Promise.resolve(item);
14
+ },
15
+
16
+ /**
17
+ * Prepare request, add time sensitive date etc.
18
+ * @param {any[]} queue
19
+ * @returns {Promise<any[]>}
20
+ */
21
+ prepareRequest(queue) {
22
+ return Promise.resolve(queue);
23
+ },
24
+ });
25
+
26
+ export default ClientMetricsPreloginBatcher;
package/src/metrics.js CHANGED
@@ -10,6 +10,7 @@ import {OS_NAME, OSMap, CLIENT_NAME} from './config';
10
10
 
11
11
  import Batcher from './batcher';
12
12
  import ClientMetricsBatcher from './client-metrics-batcher';
13
+ import ClientMetricsPreloginBatcher from './client-metrics-prelogin-batcher';
13
14
 
14
15
  const {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
15
16
 
@@ -37,6 +38,7 @@ const Metrics = WebexPlugin.extend({
37
38
  children: {
38
39
  batcher: Batcher,
39
40
  clientMetricsBatcher: ClientMetricsBatcher,
41
+ clientMetricsPreloginBatcher: ClientMetricsPreloginBatcher,
40
42
  },
41
43
 
42
44
  namespace: 'Metrics',
@@ -117,14 +119,9 @@ const Metrics = WebexPlugin.extend({
117
119
  const payload = this.getClientMetricsPayload(eventName, props);
118
120
 
119
121
  if (preLoginId) {
120
- const _payload = {
121
- metrics: [payload],
122
- };
123
-
124
- // Do not batch these because pre-login events occur during onboarding, so we will be partially blind
125
- // to users' progress through the reg flow if we wait to persist pre-login metrics for people who drop off because
126
- // their metrics will not post from a queue flush in time
127
- return this.postPreLoginMetric(_payload, preLoginId);
122
+ this.clientMetricsPreloginBatcher.savePreLoginId(preLoginId);
123
+
124
+ return this.clientMetricsPreloginBatcher.request(payload);
128
125
  }
129
126
 
130
127
  return this.clientMetricsBatcher.request(payload);
@@ -149,21 +146,6 @@ const Metrics = WebexPlugin.extend({
149
146
  },
150
147
  });
151
148
  },
152
-
153
- postPreLoginMetric(payload, preLoginId) {
154
- return this.webex.credentials.getClientToken().then((token) =>
155
- this.request({
156
- method: 'POST',
157
- api: 'metrics',
158
- resource: 'clientmetrics-prelogin',
159
- headers: {
160
- authorization: token.toString(),
161
- 'x-prelogin-userid': preLoginId,
162
- },
163
- body: payload,
164
- })
165
- );
166
- },
167
149
  });
168
150
 
169
151
  export default Metrics;
@@ -169,9 +169,11 @@ export type BuildClientEventFetchRequestOptions = (args: {
169
169
  export type PreComputedLatencies =
170
170
  | 'internal.client.pageJMT'
171
171
  | 'internal.download.time'
172
+ | 'internal.get.cluster.time'
172
173
  | 'internal.click.to.interstitial'
173
174
  | 'internal.refresh.captcha.time'
174
175
  | 'internal.exchange.ci.token.time'
175
176
  | 'internal.get.u2c.time'
176
177
  | 'internal.call.init.join.req'
177
- | 'internal.other.app.api.time';
178
+ | 'internal.other.app.api.time'
179
+ | 'internal.api.fetch.intelligence.models';
@@ -48,7 +48,7 @@ const PreLoginMetricsBatcher = Batcher.extend({
48
48
  * @returns {Promise<any>}
49
49
  */
50
50
  submitHttpRequest(payload: any) {
51
- const batchId = uniqueId('prelogin-ca-batch-');
51
+ const batchId = uniqueId('prelogin-batch-');
52
52
  if (this.preLoginId === undefined) {
53
53
  this.webex.logger.error(
54
54
  PRE_LOGIN_METRICS_IDENTIFIER,
@@ -106,6 +106,9 @@ describe('plugin-metrics', () => {
106
106
  webex.internal.newMetrics.callDiagnosticLatencies.getRefreshCaptchaReqResp = sinon
107
107
  .stub()
108
108
  .returns(10);
109
+ webex.internal.newMetrics.callDiagnosticLatencies.getDownloadIntelligenceModelsReqResp =
110
+ sinon.stub().returns(42);
111
+
109
112
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
110
113
  //@ts-ignore
111
114
  {event: {name: 'client.interstitial-window.launched'}}
@@ -123,6 +126,7 @@ describe('plugin-metrics', () => {
123
126
  clickToInterstitial: 10,
124
127
  meetingInfoReqResp: 10,
125
128
  refreshCaptchaServiceReqResp: 10,
129
+ downloadIntelligenceModelsReqResp: 42,
126
130
  },
127
131
  });
128
132
  assert.lengthOf(
@@ -138,6 +142,9 @@ describe('plugin-metrics', () => {
138
142
  webex.internal.newMetrics.callDiagnosticLatencies.getU2CTime = sinon
139
143
  .stub()
140
144
  .returns(20);
145
+ webex.internal.newMetrics.callDiagnosticLatencies.getReachabilityClustersReqResp = sinon
146
+ .stub()
147
+ .returns(10);
141
148
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
142
149
  //@ts-ignore
143
150
  {event: {name: 'client.call.initiated'}}
@@ -154,7 +161,8 @@ describe('plugin-metrics', () => {
154
161
  meetingInfoReqResp: 10,
155
162
  registerWDMDeviceJMT: 10,
156
163
  showInterstitialTime: 10,
157
- getU2CTime: 20
164
+ getU2CTime: 20,
165
+ getReachabilityClustersReqResp: 10
158
166
  },
159
167
  });
160
168
  assert.lengthOf(
@@ -51,29 +51,29 @@ describe('internal-plugin-metrics', () => {
51
51
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
52
52
  });
53
53
 
54
- it('should overwrite latency when overwrite is true', () => {
54
+ it('should overwrite latency when accumulate is false', () => {
55
55
  assert.deepEqual(cdl.precomputedLatencies.size, 0);
56
- cdl.saveLatency('internal.client.pageJMT', 10, true);
56
+ cdl.saveLatency('internal.client.pageJMT', 10, false);
57
57
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
58
58
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
59
- cdl.saveLatency('internal.client.pageJMT', 20, true);
59
+ cdl.saveLatency('internal.client.pageJMT', 20, false);
60
60
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
61
61
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
62
62
  });
63
63
 
64
- it('should save latency correctly when overwrite is false', () => {
64
+ it('should save latency correctly when accumulate is true', () => {
65
65
  assert.deepEqual(cdl.precomputedLatencies.size, 0);
66
- cdl.saveLatency('internal.client.pageJMT', 10, false);
66
+ cdl.saveLatency('internal.client.pageJMT', 10, true);
67
67
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
68
68
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
69
69
  });
70
70
 
71
- it('should save latency correctly when overwrite is false and there is existing value', () => {
71
+ it('should save latency correctly when accumulate is true and there is existing value', () => {
72
72
  assert.deepEqual(cdl.precomputedLatencies.size, 0);
73
73
  cdl.saveLatency('internal.client.pageJMT', 10);
74
74
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
75
75
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
76
- cdl.saveLatency('internal.client.pageJMT', 10, false);
76
+ cdl.saveLatency('internal.client.pageJMT', 10, true);
77
77
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
78
78
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
79
79
  });
@@ -108,8 +108,13 @@ describe('internal-plugin-metrics', () => {
108
108
  cdl.saveTimestamp({key: 'client.alert.displayed'});
109
109
  cdl.saveTimestamp({key: 'client.alert.removed'});
110
110
  assert.deepEqual(cdl.latencyTimestamps.size, 2);
111
+ cdl.saveLatency('internal.api.fetch.intelligence.models', 42);
112
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
113
+
111
114
  cdl.clearTimestamps();
115
+
112
116
  assert.deepEqual(cdl.latencyTimestamps.size, 0);
117
+ assert.deepEqual(cdl.precomputedLatencies.size, 0);
113
118
  });
114
119
 
115
120
  it('should calculate diff between timestamps correctly', () => {
@@ -145,9 +150,9 @@ describe('internal-plugin-metrics', () => {
145
150
  let clock;
146
151
  let saveLatencySpy;
147
152
 
148
- beforeEach(() => {
149
- clock = sinon.useFakeTimers();
150
-
153
+ beforeEach(() => {
154
+ clock = sinon.useFakeTimers();
155
+
151
156
  saveLatencySpy = sinon.stub(cdl, 'saveLatency');
152
157
  });
153
158
 
@@ -155,54 +160,56 @@ describe('internal-plugin-metrics', () => {
155
160
  clock.restore();
156
161
  sinon.restore();
157
162
  });
158
-
159
- it('checks measureLatency with overwrite false', async () => {
163
+
164
+ it('checks measureLatency with accumulate false', async () => {
160
165
  const key = 'internal.client.pageJMT';
161
- const overwrite = false;
166
+ const accumulate = false;
167
+
162
168
  const callbackStub = sinon.stub().callsFake(() => {
163
169
  clock.tick(50);
164
170
  return Promise.resolve('test');
165
171
  });
166
172
 
167
- const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', overwrite);
173
+ // accumulate should be false by default
174
+ const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT');
168
175
 
169
176
  const resolvedValue = await promise;
170
177
  assert.deepEqual(resolvedValue, 'test');
171
178
  assert.calledOnceWithExactly(callbackStub);
172
- assert.calledOnceWithExactly(saveLatencySpy, key, 50, overwrite)
179
+ assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
173
180
  });
174
181
 
175
- it('checks measureLatency with overwrite true', async () => {
182
+ it('checks measureLatency with accumulate true', async () => {
176
183
  const key = 'internal.download.time';
177
- const overwrite = true;
184
+ const accumulate = true;
178
185
  const callbackStub = sinon.stub().callsFake(() => {
179
186
  clock.tick(20);
180
187
  return Promise.resolve('test123');
181
188
  });
182
189
 
183
- const promise = cdl.measureLatency(callbackStub, 'internal.download.time', overwrite);
190
+ const promise = cdl.measureLatency(callbackStub, 'internal.download.time', accumulate);
184
191
 
185
192
  const resolvedValue = await promise;
186
193
  assert.deepEqual(resolvedValue, 'test123');
187
194
  assert.calledOnceWithExactly(callbackStub);
188
- assert.calledOnceWithExactly(saveLatencySpy, key, 20, overwrite)
195
+ assert.calledOnceWithExactly(saveLatencySpy, key, 20, accumulate);
189
196
  });
190
197
 
191
198
  it('checks measureLatency when callBack rejects', async () => {
192
199
  const key = 'internal.client.pageJMT';
193
- const overwrite = true;
200
+ const accumulate = false;
194
201
  const error = new Error('some error');
195
202
  const callbackStub = sinon.stub().callsFake(() => {
196
203
  clock.tick(50);
197
204
  return Promise.reject(error);
198
205
  });
199
206
 
200
- const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', overwrite);
207
+ const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', accumulate);
201
208
 
202
209
  const rejectedValue = await assert.isRejected(promise);
203
210
  assert.deepEqual(rejectedValue, error);
204
211
  assert.calledOnceWithExactly(callbackStub);
205
- assert.calledOnceWithExactly(saveLatencySpy, key, 50, overwrite)
212
+ assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
206
213
  });
207
214
  });
208
215
 
@@ -224,6 +231,24 @@ describe('internal-plugin-metrics', () => {
224
231
  });
225
232
  });
226
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
+
227
252
  describe('getExchangeCITokenJMT', () => {
228
253
  it('returns undefined when no precomputed value available', () => {
229
254
  assert.deepEqual(cdl.getExchangeCITokenJMT(), undefined);
@@ -541,7 +541,10 @@ describe('internal-plugin-metrics', () => {
541
541
  it('should prepare diagnostic event successfully', () => {
542
542
  const options = {meetingId: fakeMeeting.id};
543
543
  const getOriginStub = sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
544
- const clearEmptyKeysRecursivelyStub = sinon.stub(CallDiagnosticUtils, 'clearEmptyKeysRecursively');
544
+ const clearEmptyKeysRecursivelyStub = sinon.stub(
545
+ CallDiagnosticUtils,
546
+ 'clearEmptyKeysRecursively'
547
+ );
545
548
 
546
549
  const res = cd.prepareDiagnosticEvent(
547
550
  {
@@ -896,11 +899,13 @@ describe('internal-plugin-metrics', () => {
896
899
  options
897
900
  );
898
901
  assert.notCalled(submitToCallDiagnosticsSpy);
899
- assert.calledWith(submitToCallDiagnosticsPreLoginSpy, {
902
+ assert.calledWith(
903
+ submitToCallDiagnosticsPreLoginSpy,
904
+ {
900
905
  eventId: 'my-fake-id',
901
906
  version: 1,
902
- origin: { origin: 'fake-origin' },
903
- originTime: { triggered: now.toISOString(), sent: 'not_defined_yet' },
907
+ origin: {origin: 'fake-origin'},
908
+ originTime: {triggered: now.toISOString(), sent: 'not_defined_yet'},
904
909
  senderCountryCode: 'UK',
905
910
  event: {
906
911
  name: 'client.alert.displayed',
@@ -912,12 +917,14 @@ describe('internal-plugin-metrics', () => {
912
917
  orgId: 'orgId',
913
918
  locusUrl: 'locus-url',
914
919
  webexConferenceIdStr: 'webexConferenceIdStr1',
915
- globalMeetingId: 'globalMeetingId1'
920
+ globalMeetingId: 'globalMeetingId1',
916
921
  },
917
- eventData: { webClientDomain: 'whatever' },
918
- loginType: 'login-ci'
922
+ eventData: {webClientDomain: 'whatever'},
923
+ loginType: 'login-ci',
919
924
  },
920
- }, options.preLoginId);
925
+ },
926
+ options.preLoginId
927
+ );
921
928
  });
922
929
 
923
930
  it('should use meeting loginType if present and meetingId provided', () => {
@@ -1382,7 +1389,7 @@ describe('internal-plugin-metrics', () => {
1382
1389
  });
1383
1390
  });
1384
1391
 
1385
- describe("#submitToCallDiagnostics", () => {
1392
+ describe('#submitToCallDiagnostics', () => {
1386
1393
  it('should send request to call diagnostic batcher', () => {
1387
1394
  const requestStub = sinon.stub();
1388
1395
  //@ts-ignore
@@ -1391,7 +1398,7 @@ describe('internal-plugin-metrics', () => {
1391
1398
  cd.submitToCallDiagnostics({event: 'test'});
1392
1399
  assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
1393
1400
  });
1394
- })
1401
+ });
1395
1402
 
1396
1403
  describe('#submitMQE', () => {
1397
1404
  it('submits the event correctly', () => {
@@ -1445,6 +1452,7 @@ describe('internal-plugin-metrics', () => {
1445
1452
  },
1446
1453
  eventData: {webClientDomain: 'whatever'},
1447
1454
  intervals: [{}],
1455
+ callingServiceType: 'LOCUS',
1448
1456
  sourceMetadata: {
1449
1457
  applicationSoftwareType: 'webex-js-sdk',
1450
1458
  applicationSoftwareVersion: 'webex-version',
@@ -1480,6 +1488,7 @@ describe('internal-plugin-metrics', () => {
1480
1488
  },
1481
1489
  eventData: {webClientDomain: 'whatever'},
1482
1490
  intervals: [{}],
1491
+ callingServiceType: 'LOCUS',
1483
1492
  sourceMetadata: {
1484
1493
  applicationSoftwareType: 'webex-js-sdk',
1485
1494
  applicationSoftwareVersion: 'webex-version',
@@ -1513,6 +1522,7 @@ describe('internal-plugin-metrics', () => {
1513
1522
  },
1514
1523
  eventData: {webClientDomain: 'whatever'},
1515
1524
  intervals: [{}],
1525
+ callingServiceType: 'LOCUS',
1516
1526
  sourceMetadata: {
1517
1527
  applicationSoftwareType: 'webex-js-sdk',
1518
1528
  applicationSoftwareVersion: 'webex-version',
@@ -2006,12 +2016,16 @@ describe('internal-plugin-metrics', () => {
2006
2016
 
2007
2017
  describe('httpStatusCode', () => {
2008
2018
  it('should include httpStatusCode for browser media errors', () => {
2009
- const res = cd.generateClientEventErrorPayload({name: 'PermissionDeniedError', message: 'bad times', statusCode: 401});
2019
+ const res = cd.generateClientEventErrorPayload({
2020
+ name: 'PermissionDeniedError',
2021
+ message: 'bad times',
2022
+ statusCode: 401,
2023
+ });
2010
2024
  assert.deepEqual(res, {
2011
2025
  category: 'expected',
2012
2026
  errorCode: 4032,
2013
2027
  errorData: {
2014
- errorName: 'PermissionDeniedError'
2028
+ errorName: 'PermissionDeniedError',
2015
2029
  },
2016
2030
  errorDescription: 'CameraPermissionDenied',
2017
2031
  fatal: true,
@@ -2024,12 +2038,16 @@ describe('internal-plugin-metrics', () => {
2024
2038
  });
2025
2039
 
2026
2040
  it('should include httpStatusCode for SdpOfferCreationErrors', () => {
2027
- const res = cd.generateClientEventErrorPayload({name: 'SdpOfferCreationError', message: 'bad times', statusCode: 404});
2041
+ const res = cd.generateClientEventErrorPayload({
2042
+ name: 'SdpOfferCreationError',
2043
+ message: 'bad times',
2044
+ statusCode: 404,
2045
+ });
2028
2046
  assert.deepEqual(res, {
2029
2047
  category: 'media',
2030
2048
  errorCode: 2050,
2031
2049
  errorData: {
2032
- errorName: 'SdpOfferCreationError'
2050
+ errorName: 'SdpOfferCreationError',
2033
2051
  },
2034
2052
  errorDescription: 'SdpOfferCreationError',
2035
2053
  fatal: true,
@@ -2042,7 +2060,11 @@ describe('internal-plugin-metrics', () => {
2042
2060
  });
2043
2061
 
2044
2062
  it('should include httpStatusCode for service error codes', () => {
2045
- const res = cd.generateClientEventErrorPayload({body: {errorCode: 58400}, message: 'bad times', statusCode: 400});
2063
+ const res = cd.generateClientEventErrorPayload({
2064
+ body: {errorCode: 58400},
2065
+ message: 'bad times',
2066
+ statusCode: 400,
2067
+ });
2046
2068
  assert.deepEqual(res, {
2047
2069
  category: 'signaling',
2048
2070
  errorCode: 4100,
@@ -2057,7 +2079,11 @@ describe('internal-plugin-metrics', () => {
2057
2079
  });
2058
2080
 
2059
2081
  it('should include httpStatusCode for locus service error codes', () => {
2060
- const res = cd.generateClientEventErrorPayload({body: {errorCode: 2403001}, message: 'bad times', statusCode: 400});
2082
+ const res = cd.generateClientEventErrorPayload({
2083
+ body: {errorCode: 2403001},
2084
+ message: 'bad times',
2085
+ statusCode: 400,
2086
+ });
2061
2087
  assert.deepEqual(res, {
2062
2088
  category: 'expected',
2063
2089
  errorCode: 3007,
@@ -2072,7 +2098,11 @@ describe('internal-plugin-metrics', () => {
2072
2098
  });
2073
2099
 
2074
2100
  it('should include httpStatusCode for meetingInfo service error codes', () => {
2075
- const res = cd.generateClientEventErrorPayload({body: {data: {meetingInfo: {}}}, message: 'bad times', statusCode: 400});
2101
+ const res = cd.generateClientEventErrorPayload({
2102
+ body: {data: {meetingInfo: {}}},
2103
+ message: 'bad times',
2104
+ statusCode: 400,
2105
+ });
2076
2106
  assert.deepEqual(res, {
2077
2107
  category: 'signaling',
2078
2108
  errorCode: 4100,
@@ -2087,8 +2117,10 @@ describe('internal-plugin-metrics', () => {
2087
2117
  });
2088
2118
 
2089
2119
  it('should include httpStatusCode for network errors', () => {
2090
- const error = new WebexHttpError.NetworkOrCORSError(
2091
- {statusCode: 400, options: {service: '', headers: {}}});
2120
+ const error = new WebexHttpError.NetworkOrCORSError({
2121
+ statusCode: 400,
2122
+ options: {service: '', headers: {}},
2123
+ });
2092
2124
  const res = cd.generateClientEventErrorPayload(error);
2093
2125
  assert.deepEqual(res, {
2094
2126
  category: 'network',
@@ -2104,8 +2136,10 @@ describe('internal-plugin-metrics', () => {
2104
2136
  });
2105
2137
 
2106
2138
  it('should include httpStatusCode for unauthorized errors', () => {
2107
- const error = new WebexHttpError.Unauthorized(
2108
- {statusCode: 401, options: {service: '', headers: {}}});
2139
+ const error = new WebexHttpError.Unauthorized({
2140
+ statusCode: 401,
2141
+ options: {service: '', headers: {}},
2142
+ });
2109
2143
  const res = cd.generateClientEventErrorPayload(error);
2110
2144
  assert.deepEqual(res, {
2111
2145
  category: 'network',
@@ -2308,7 +2342,7 @@ describe('internal-plugin-metrics', () => {
2308
2342
  });
2309
2343
  });
2310
2344
 
2311
- describe("#submitToCallDiagnosticsPreLogin", () => {
2345
+ describe('#submitToCallDiagnosticsPreLogin', () => {
2312
2346
  it('should send request to call diagnostic batcher and saves preLoginId', () => {
2313
2347
  const requestStub = sinon.stub();
2314
2348
  //@ts-ignore
@@ -2321,7 +2355,7 @@ describe('internal-plugin-metrics', () => {
2321
2355
  assert.calledWith(cd.preLoginMetricsBatcher.savePreLoginId, preLoginId);
2322
2356
  assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
2323
2357
  });
2324
- })
2358
+ });
2325
2359
 
2326
2360
  describe('#isServiceErrorExpected', () => {
2327
2361
  it('returns true for code mapped to "expected"', () => {
@@ -301,17 +301,23 @@ describe('internal-plugin-metrics', () => {
301
301
 
302
302
  [
303
303
  ['client.exit.app', {}],
304
- ['client.login.end', {
305
- joinTimes: {
306
- otherAppApiReqResp: undefined,
307
- exchangeCITokenJMT: undefined,
308
- }
309
- }],
310
- ['client.webexapp.launched', {
311
- joinTimes: {
312
- downloadTime: undefined,
313
- }
314
- }],
304
+ [
305
+ 'client.login.end',
306
+ {
307
+ joinTimes: {
308
+ otherAppApiReqResp: undefined,
309
+ exchangeCITokenJMT: undefined,
310
+ },
311
+ },
312
+ ],
313
+ [
314
+ 'client.webexapp.launched',
315
+ {
316
+ joinTimes: {
317
+ downloadTime: undefined,
318
+ },
319
+ },
320
+ ],
315
321
  [
316
322
  'client.interstitial-window.launched',
317
323
  {
@@ -319,6 +325,7 @@ describe('internal-plugin-metrics', () => {
319
325
  clickToInterstitial: undefined,
320
326
  meetingInfoReqResp: undefined,
321
327
  refreshCaptchaServiceReqResp: undefined,
328
+ downloadIntelligenceModelsReqResp: undefined,
322
329
  },
323
330
  },
324
331
  ],
@@ -329,7 +336,8 @@ describe('internal-plugin-metrics', () => {
329
336
  showInterstitialTime: undefined,
330
337
  meetingInfoReqResp: undefined,
331
338
  registerWDMDeviceJMT: undefined,
332
- getU2CTime: undefined
339
+ getU2CTime: undefined,
340
+ getReachabilityClustersReqResp: undefined,
333
341
  },
334
342
  },
335
343
  ],
@@ -345,7 +353,7 @@ describe('internal-plugin-metrics', () => {
345
353
  interstitialToJoinOK: undefined,
346
354
  totalJmt: undefined,
347
355
  clientJmt: undefined,
348
- downloadTime: undefined
356
+ downloadTime: undefined,
349
357
  },
350
358
  },
351
359
  ],
@@ -607,6 +615,12 @@ describe('internal-plugin-metrics', () => {
607
615
  turnServerUsed: true,
608
616
  errorCode: DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
609
617
  },
618
+ {
619
+ signalingState: 'stable',
620
+ iceConnectionState: 'disconnected',
621
+ turnServerUsed: true,
622
+ errorCode: DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
623
+ },
610
624
  {
611
625
  signalingState: 'stable',
612
626
  iceConnectionState: 'failed',
@@ -0,0 +1,54 @@
1
+ /*!
2
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
+ */
4
+
5
+ import {assert} from '@webex/test-helper-chai';
6
+ import MockWebex from '@webex/test-helper-mock-webex';
7
+ import sinon from 'sinon';
8
+ import Metrics from '@webex/internal-plugin-metrics';
9
+ import PreLoginMetricsBatcher from '@webex/internal-plugin-metrics';
10
+ import ClientMetricsPreloginBatcher from '@webex/internal-plugin-metrics';
11
+
12
+
13
+ describe('internal-plugin-metrics', () => {
14
+ describe('ClientMetricsPreloginBatcher', () => {
15
+ let webex;
16
+
17
+ beforeEach(() => {
18
+ //@ts-ignore
19
+ webex = new MockWebex({
20
+ children: {
21
+ metrics: Metrics,
22
+ },
23
+ });
24
+
25
+ webex.request = (options) =>
26
+ Promise.resolve({body: {items: []}, waitForServiceTimeout: 15, options});
27
+
28
+ sinon.spy(webex, 'request');
29
+ });
30
+
31
+ afterEach(() => {
32
+ sinon.restore();
33
+ });
34
+
35
+ it('should be an instance of PreLoginMetricsBatcher', () => {
36
+ const clientMetricsPreloginBatcher = new ClientMetricsPreloginBatcher();
37
+ assert.instanceOf(clientMetricsPreloginBatcher, PreLoginMetricsBatcher);
38
+ });
39
+
40
+
41
+ it('checks prepareItem', async () => {
42
+ const testItem = {id: 1};
43
+ const resultPromise = await webex.internal.metrics.clientMetricsPreloginBatcher.prepareItem(testItem);
44
+ assert.strictEqual(resultPromise, testItem);
45
+ });
46
+
47
+ it('checks prepareRequest', async () => {
48
+ const testQueue = [];
49
+
50
+ const resultPromise = await webex.internal.metrics.clientMetricsPreloginBatcher.prepareRequest(testQueue);
51
+ assert.strictEqual(resultPromise, testQueue);
52
+ });
53
+ });
54
+ });