@webex/internal-plugin-metrics 3.0.0-beta.4 → 3.0.0-beta.400

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 (74) hide show
  1. package/README.md +1 -3
  2. package/dist/batcher.js +42 -22
  3. package/dist/batcher.js.map +1 -1
  4. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +65 -0
  5. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -0
  6. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +508 -0
  7. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -0
  8. package/dist/call-diagnostic/call-diagnostic-metrics.js +860 -0
  9. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -0
  10. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +367 -0
  11. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -0
  12. package/dist/call-diagnostic/config.js +627 -0
  13. package/dist/call-diagnostic/config.js.map +1 -0
  14. package/dist/client-metrics-batcher.js +3 -8
  15. package/dist/client-metrics-batcher.js.map +1 -1
  16. package/dist/config.js +23 -6
  17. package/dist/config.js.map +1 -1
  18. package/dist/index.js +46 -10
  19. package/dist/index.js.map +1 -1
  20. package/dist/metrics.js +47 -80
  21. package/dist/metrics.js.map +1 -1
  22. package/dist/metrics.types.js +7 -0
  23. package/dist/metrics.types.js.map +1 -0
  24. package/dist/new-metrics.js +300 -0
  25. package/dist/new-metrics.js.map +1 -0
  26. package/dist/prelogin-metrics-batcher.js +82 -0
  27. package/dist/prelogin-metrics-batcher.js.map +1 -0
  28. package/dist/types/batcher.d.ts +7 -0
  29. package/dist/types/call-diagnostic/call-diagnostic-metrics-batcher.d.ts +2 -0
  30. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +218 -0
  31. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +421 -0
  32. package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +103 -0
  33. package/dist/types/call-diagnostic/config.d.ts +178 -0
  34. package/dist/types/client-metrics-batcher.d.ts +2 -0
  35. package/dist/types/config.d.ts +36 -0
  36. package/dist/types/index.d.ts +15 -0
  37. package/dist/types/metrics.d.ts +3 -0
  38. package/dist/types/metrics.types.d.ts +105 -0
  39. package/dist/types/new-metrics.d.ts +131 -0
  40. package/dist/types/prelogin-metrics-batcher.d.ts +2 -0
  41. package/dist/types/utils.d.ts +6 -0
  42. package/dist/utils.js +27 -0
  43. package/dist/utils.js.map +1 -0
  44. package/package.json +16 -8
  45. package/src/batcher.js +71 -26
  46. package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +72 -0
  47. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +467 -0
  48. package/src/call-diagnostic/call-diagnostic-metrics.ts +919 -0
  49. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +395 -0
  50. package/src/call-diagnostic/config.ts +685 -0
  51. package/src/client-metrics-batcher.js +4 -4
  52. package/src/config.js +26 -5
  53. package/src/index.ts +56 -0
  54. package/src/metrics.js +47 -58
  55. package/src/metrics.types.ts +170 -0
  56. package/src/new-metrics.ts +278 -0
  57. package/src/prelogin-metrics-batcher.ts +95 -0
  58. package/src/utils.ts +17 -0
  59. package/test/unit/spec/batcher.js +28 -15
  60. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +457 -0
  61. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +657 -0
  62. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +2303 -0
  63. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +634 -0
  64. package/test/unit/spec/client-metrics-batcher.js +28 -15
  65. package/test/unit/spec/metrics.js +94 -116
  66. package/test/unit/spec/new-metrics.ts +231 -0
  67. package/test/unit/spec/prelogin-metrics-batcher.ts +250 -0
  68. package/test/unit/spec/utils.ts +22 -0
  69. package/tsconfig.json +6 -0
  70. package/dist/call-diagnostic-events-batcher.js +0 -70
  71. package/dist/call-diagnostic-events-batcher.js.map +0 -1
  72. package/src/call-diagnostic-events-batcher.js +0 -62
  73. package/src/index.js +0 -17
  74. package/test/unit/spec/call-diagnostic-events-batcher.js +0 -180
@@ -27,8 +27,8 @@ describe('plugin-metrics', () => {
27
27
  beforeEach(() => {
28
28
  webex = new MockWebex({
29
29
  children: {
30
- metrics: Metrics
31
- }
30
+ metrics: Metrics,
31
+ },
32
32
  });
33
33
 
34
34
  webex.config.metrics = config.metrics;
@@ -37,7 +37,8 @@ describe('plugin-metrics', () => {
37
37
  return Promise.resolve({
38
38
  statusCode: 204,
39
39
  body: undefined,
40
- options
40
+ waitForServiceTimeout: 30,
41
+ options,
41
42
  });
42
43
  };
43
44
  sinon.spy(webex, 'request');
@@ -58,9 +59,10 @@ describe('plugin-metrics', () => {
58
59
  it('clears the queue', () => {
59
60
  clock.uninstall();
60
61
 
61
- return webex.internal.metrics.clientMetricsBatcher.request({
62
- key: 'testMetric'
63
- })
62
+ return webex.internal.metrics.clientMetricsBatcher
63
+ .request({
64
+ key: 'testMetric',
65
+ })
64
66
  .then(() => {
65
67
  assert.calledOnce(webex.request);
66
68
  assert.lengthOf(webex.internal.metrics.clientMetricsBatcher.queue, 0);
@@ -80,26 +82,29 @@ describe('plugin-metrics', () => {
80
82
 
81
83
  sinon.stub(webex, 'request').callsFake((options) => {
82
84
  options.headers = {
83
- trackingid: count
85
+ trackingid: count,
84
86
  };
85
87
 
86
88
  count += 1;
87
89
  if (count < 9) {
88
- return Promise.reject(new WebexHttpError.NetworkOrCORSError({
89
- statusCode: 0,
90
- options
91
- }));
90
+ return Promise.reject(
91
+ new WebexHttpError.NetworkOrCORSError({
92
+ statusCode: 0,
93
+ options,
94
+ })
95
+ );
92
96
  }
93
97
 
94
98
  return Promise.resolve({
95
99
  statusCode: 204,
96
100
  body: undefined,
97
- options
101
+ waitForServiceTimeout: 30,
102
+ options,
98
103
  });
99
104
  });
100
105
 
101
106
  const promise = webex.internal.metrics.clientMetricsBatcher.request({
102
- key: 'testMetric'
107
+ key: 'testMetric',
103
108
  });
104
109
 
105
110
  return promiseTick(50)
@@ -159,8 +164,16 @@ describe('plugin-metrics', () => {
159
164
  .then(() => assert.lengthOf(webex.internal.metrics.clientMetricsBatcher.queue, 0))
160
165
  .then(() => promise)
161
166
  .then(() => {
162
- assert.lengthOf(webex.request.args[1][0].body.metrics, 1, 'Reenqueuing the metric once did not increase the number of metrics to be submitted');
163
- assert.lengthOf(webex.request.args[2][0].body.metrics, 1, 'Reenqueuing the metric twice did not increase the number of metrics to be submitted');
167
+ assert.lengthOf(
168
+ webex.request.args[1][0].body.metrics,
169
+ 1,
170
+ 'Reenqueuing the metric once did not increase the number of metrics to be submitted'
171
+ );
172
+ assert.lengthOf(
173
+ webex.request.args[2][0].body.metrics,
174
+ 1,
175
+ 'Reenqueuing the metric twice did not increase the number of metrics to be submitted'
176
+ );
164
177
  assert.lengthOf(webex.internal.metrics.clientMetricsBatcher.queue, 0);
165
178
  });
166
179
  });
@@ -8,6 +8,9 @@ import {Token, Credentials} from '@webex/webex-core';
8
8
  import FakeTimers from '@sinonjs/fake-timers';
9
9
  import sinon from 'sinon';
10
10
  import Metrics, {config} from '@webex/internal-plugin-metrics';
11
+ import {BrowserDetection} from '@webex/common';
12
+
13
+ const {getOSVersion} = BrowserDetection();
11
14
 
12
15
  function promiseTick(count) {
13
16
  let promise = Promise.resolve();
@@ -29,35 +32,35 @@ describe('plugin-metrics', () => {
29
32
  const eventName = 'test_event';
30
33
  const mockPayload = {
31
34
  fields: {
32
- testField: 123
35
+ testField: 123,
33
36
  },
34
37
  tags: {
35
- testTag: 'tag value'
38
+ testTag: 'tag value',
36
39
  },
37
40
  metricName: eventName,
38
41
  test: 'this field should not be included in final payload',
39
42
  type: 'behavioral',
40
- eventPayload: {value: 'splunk business metric payload'}
43
+ eventPayload: {value: 'splunk business metric payload'},
41
44
  };
42
45
  const transformedProps = {
43
46
  fields: {
44
- testField: 123
47
+ testField: 123,
45
48
  },
46
49
  tags: {
47
- testTag: 'tag value'
50
+ testTag: 'tag value',
48
51
  },
49
52
  metricName: eventName,
50
53
  type: 'behavioral',
51
- timestamp: Date.now()
54
+ timestamp: Date.now(),
52
55
  };
53
56
  const preLoginId = '1b90cf5e-27a6-41aa-a208-1f6eb6b9e6b6';
54
57
  const preLoginProps = {
55
- metrics: [transformedProps]
58
+ metrics: [transformedProps],
56
59
  };
57
60
  const mockCallDiagnosticEvent = {
58
61
  originTime: {
59
- triggered: 'mock triggered timestamp'
60
- }
62
+ triggered: 'mock triggered timestamp',
63
+ },
61
64
  };
62
65
 
63
66
  beforeEach(() => {
@@ -71,8 +74,8 @@ describe('plugin-metrics', () => {
71
74
  beforeEach(() => {
72
75
  webex = new MockWebex({
73
76
  children: {
74
- metrics: Metrics
75
- }
77
+ metrics: Metrics,
78
+ },
76
79
  });
77
80
 
78
81
  webex.config.metrics = config.metrics;
@@ -82,7 +85,8 @@ describe('plugin-metrics', () => {
82
85
  return Promise.resolve({
83
86
  statusCode: 204,
84
87
  body: undefined,
85
- options
88
+ waitForServiceTimeout: 30,
89
+ options,
86
90
  });
87
91
  };
88
92
 
@@ -94,16 +98,21 @@ describe('plugin-metrics', () => {
94
98
  ...webex.config,
95
99
  appName: 'appName',
96
100
  appPlatform: 'appPlatform',
97
- appVersion: 'appVersion'
98
-
101
+ appVersion: 'appVersion',
99
102
  };
100
103
  webex.config.metrics.type = ['operational'];
101
104
  webex.config.metrics.appType = 'sdk';
105
+ webex.meetings = {
106
+ config: {
107
+ metrics: {
108
+ clientVersion: '43.0.105'
109
+ }
110
+ }
111
+ }
102
112
 
103
113
  sinon.spy(webex, 'request');
104
114
  sinon.spy(metrics, 'postPreLoginMetric');
105
115
  sinon.spy(metrics, 'aliasUser');
106
- sinon.spy(metrics, 'submitCallDiagnosticEvents');
107
116
  });
108
117
 
109
118
  describe('#submit()', () => {
@@ -132,6 +141,68 @@ describe('plugin-metrics', () => {
132
141
  });
133
142
  });
134
143
 
144
+ describe('#getClientMetricsPayload()', () => {
145
+ it('returns the expected payload', () => {
146
+ webex.credentials.supertoken = new Token(
147
+ {
148
+ access_token: 'a_b_orgid',
149
+ },
150
+ {parent: webex}
151
+ );
152
+
153
+ const testPayload = {
154
+ tags: {success: true},
155
+ fields: {perceivedDurationInMillis: 314},
156
+ context: {},
157
+ eventPayload: {value: 'splunk business metric payload'},
158
+ };
159
+ const date = clock.now;
160
+
161
+ const result = metrics.getClientMetricsPayload('test', testPayload);
162
+
163
+ assert.deepEqual(result, {
164
+ context: {
165
+ app: {
166
+ version: undefined,
167
+ },
168
+ locale: 'en-US',
169
+ os: {
170
+ name: 'other',
171
+ version: getOSVersion(),
172
+ },
173
+ },
174
+ eventPayload: {
175
+ value: 'splunk business metric payload',
176
+ },
177
+ fields: {
178
+ browser_version: '',
179
+ client_id: 'fake',
180
+ os_version: getOSVersion(),
181
+ perceivedDurationInMillis: 314,
182
+ platform: 'Web',
183
+ sdk_version: undefined,
184
+ spark_user_agent: 'webex-js-sdk appName/appVersion appPlatform',
185
+ },
186
+ metricName: 'test',
187
+ tags: {
188
+ appVersion: '43.0.105',
189
+ browser: '',
190
+ domain: 'whatever',
191
+ os: 'other',
192
+ success: true,
193
+ },
194
+ timestamp: 0,
195
+ type: ['operational'],
196
+ });
197
+ });
198
+
199
+ it('throws when no event name is specified', () => {
200
+ assert.throws(() => {
201
+ metrics.getClientMetricsPayload();
202
+ }, 'Missing behavioral metric name. Please provide one');
203
+ });
204
+ });
205
+
135
206
  describe('#submitClientMetrics()', () => {
136
207
  describe('before login', () => {
137
208
  it('posts pre-login metric', () => {
@@ -167,15 +238,18 @@ describe('plugin-metrics', () => {
167
238
  });
168
239
  describe('after login', () => {
169
240
  it('submits a metric to clientmetrics', () => {
170
- webex.credentials.supertoken = new Token({
171
- access_token: 'a_b_orgid'
172
- }, {parent: webex});
241
+ webex.credentials.supertoken = new Token(
242
+ {
243
+ access_token: 'a_b_orgid',
244
+ },
245
+ {parent: webex}
246
+ );
173
247
 
174
248
  const testPayload = {
175
249
  tags: {success: true},
176
250
  fields: {perceivedDurationInMillis: 314},
177
251
  context: {},
178
- eventPayload: {value: 'splunk business metric payload'}
252
+ eventPayload: {value: 'splunk business metric payload'},
179
253
  };
180
254
  const date = clock.now;
181
255
 
@@ -197,23 +271,20 @@ describe('plugin-metrics', () => {
197
271
  assert.property(metric, 'eventPayload');
198
272
 
199
273
  assert.property(metric.tags, 'browser');
200
- assert.property(metric.tags, 'org_id');
201
274
  assert.property(metric.tags, 'os');
202
275
  assert.property(metric.tags, 'domain');
203
- assert.property(metric.tags, 'client_id');
204
- assert.property(metric.tags, 'user_id');
205
276
 
206
277
  assert.property(metric.fields, 'browser_version');
207
278
  assert.property(metric.fields, 'os_version');
208
279
  assert.property(metric.fields, 'sdk_version');
209
280
  assert.property(metric.fields, 'platform');
210
281
  assert.property(metric.fields, 'spark_user_agent');
282
+ assert.property(metric.fields, 'client_id');
211
283
 
212
284
  assert.property(metric.context, 'app');
213
285
  assert.property(metric.context, 'locale');
214
286
  assert.property(metric.context, 'os');
215
287
 
216
-
217
288
  assert.equal(metric.timestamp, date);
218
289
  assert.equal(metric.metricName, 'test');
219
290
  assert.equal(metric.tags.success, true);
@@ -268,98 +339,5 @@ describe('plugin-metrics', () => {
268
339
  assert.match(params, {alias: true});
269
340
  }));
270
341
  });
271
-
272
- describe('#submitCallDiagnosticEvents()', () => {
273
- it('submits a call diagnostic event', () => {
274
- const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
275
-
276
- return promiseTick(50)
277
- .then(() => clock.tick(config.metrics.batcherWait))
278
- .then(() => promise)
279
- .then(() => {
280
- assert.calledOnce(webex.request);
281
- const req = webex.request.args[0][0];
282
- const metric = req.body.metrics[0];
283
-
284
- assert.property(metric.eventPayload, 'origin');
285
- assert.property(metric.eventPayload, 'originTime');
286
- assert.property(metric.eventPayload.origin, 'buildType');
287
- assert.property(metric.eventPayload.origin, 'networkType');
288
- assert.property(metric.eventPayload.originTime, 'sent');
289
- assert.equal(metric.eventPayload.origin.buildType, 'test');
290
- });
291
- });
292
-
293
- it('submits a call diagnostic event with buildType set in the payload', () => {
294
- const promise = metrics.submitCallDiagnosticEvents({
295
- ...mockCallDiagnosticEvent,
296
- origin: {
297
- buildType: 'prod'
298
- }
299
- });
300
-
301
- return promiseTick(50)
302
- .then(() => clock.tick(config.metrics.batcherWait))
303
- .then(() => promise)
304
- .then(() => {
305
- assert.calledOnce(webex.request);
306
- const req = webex.request.args[0][0];
307
- const metric = req.body.metrics[0];
308
-
309
- assert.property(metric.eventPayload, 'origin');
310
- assert.property(metric.eventPayload, 'originTime');
311
- assert.property(metric.eventPayload.origin, 'buildType');
312
- assert.property(metric.eventPayload.origin, 'networkType');
313
- assert.property(metric.eventPayload.originTime, 'sent');
314
- assert.equal(metric.eventPayload.origin.buildType, 'prod');
315
- });
316
- });
317
-
318
- xit('submits a call diagnostic event with a test domain', () => {
319
- global.window.location.hostname = 'test.webex.com';
320
-
321
- const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
322
-
323
- return promiseTick(50)
324
- .then(() => clock.tick(config.metrics.batcherWait))
325
- .then(() => promise)
326
- .then(() => {
327
- assert.calledOnce(webex.request);
328
- const req = webex.request.args[0][0];
329
- const metric = req.body.metrics[0];
330
-
331
- assert.property(metric.eventPayload, 'origin');
332
- assert.property(metric.eventPayload, 'originTime');
333
- assert.property(metric.eventPayload.origin, 'buildType');
334
- assert.property(metric.eventPayload.origin, 'networkType');
335
- assert.property(metric.eventPayload.originTime, 'sent');
336
- assert.equal(metric.eventPayload.origin.buildType, 'test');
337
- });
338
- });
339
-
340
- // Skip because it's current unable to overwrite NODE_ENV
341
- // However doing `NODE_ENV=test npm run test ...` will get this test case to pass
342
- xit('submits a call diagnostic event with a NODE_ENV=production', () => {
343
- process.env.NODE_ENV = 'production';
344
-
345
- const promise = metrics.submitCallDiagnosticEvents(mockCallDiagnosticEvent);
346
-
347
- return promiseTick(50)
348
- .then(() => clock.tick(config.metrics.batcherWait))
349
- .then(() => promise)
350
- .then(() => {
351
- assert.calledOnce(webex.request);
352
- const req = webex.request.args[0][0];
353
- const metric = req.body.metrics[0];
354
-
355
- assert.property(metric.eventPayload, 'origin');
356
- assert.property(metric.eventPayload, 'originTime');
357
- assert.property(metric.eventPayload.origin, 'buildType');
358
- assert.property(metric.eventPayload.origin, 'networkType');
359
- assert.property(metric.eventPayload.originTime, 'sent');
360
- assert.equal(metric.eventPayload.origin.buildType, 'prod');
361
- });
362
- });
363
- });
364
342
  });
365
343
  });
@@ -0,0 +1,231 @@
1
+ import {assert} from '@webex/test-helper-chai';
2
+ import {NewMetrics, CallDiagnosticLatencies} from '@webex/internal-plugin-metrics';
3
+ import MockWebex from '@webex/test-helper-mock-webex';
4
+ import sinon from 'sinon';
5
+ import {Utils} from '@webex/internal-plugin-metrics';
6
+
7
+ describe('internal-plugin-metrics', () => {
8
+
9
+ const mockWebex = () => new MockWebex({
10
+ children: {
11
+ newMetrics: NewMetrics,
12
+ },
13
+ meetings: {
14
+ meetingCollection: {
15
+ get: sinon.stub(),
16
+ },
17
+ },
18
+ request: sinon.stub().resolves({}),
19
+ logger: {
20
+ log: sinon.stub(),
21
+ error: sinon.stub(),
22
+ }
23
+ });
24
+
25
+ describe('check submitClientEvent when webex is not ready', () => {
26
+ let webex;
27
+ //@ts-ignore
28
+ webex = mockWebex();
29
+
30
+ it('checks the log', () => {
31
+ webex.internal.newMetrics.submitClientEvent({
32
+ name: 'client.alert.displayed',
33
+ options: {
34
+ meetingId: '123',
35
+ },
36
+ });
37
+ assert.calledWith(
38
+ webex.logger.log,
39
+ 'NewMetrics: @submitClientEvent. Attempted to submit before webex.ready. Event name: client.alert.displayed'
40
+ );
41
+ });
42
+ });
43
+
44
+ describe('new-metrics contstructor', () => {
45
+ it('checks callDiagnosticLatencies is defined before ready emit', () => {
46
+
47
+ const webex = mockWebex();
48
+
49
+ assert.instanceOf(webex.internal.newMetrics.callDiagnosticLatencies, CallDiagnosticLatencies);
50
+ });
51
+ });
52
+
53
+ describe('new-metrics', () => {
54
+ let webex;
55
+
56
+ beforeEach(() => {
57
+ //@ts-ignore
58
+ webex = mockWebex();
59
+
60
+ webex.emit('ready');
61
+
62
+ webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp = sinon.stub();
63
+ webex.internal.newMetrics.callDiagnosticLatencies.clearTimestamps = sinon.stub();
64
+ webex.internal.newMetrics.callDiagnosticMetrics.submitClientEvent = sinon.stub();
65
+ webex.internal.newMetrics.callDiagnosticMetrics.submitMQE = sinon.stub();
66
+ webex.internal.newMetrics.callDiagnosticMetrics.clientMetricsAliasUser = sinon.stub();
67
+ webex.internal.newMetrics.callDiagnosticMetrics.buildClientEventFetchRequestOptions =
68
+ sinon.stub();
69
+ webex.setTimingsAndFetch = sinon.stub();
70
+ });
71
+
72
+ afterEach(() => {
73
+ sinon.restore();
74
+ })
75
+
76
+ it('submits Client Event successfully', () => {
77
+ webex.internal.newMetrics.submitClientEvent({
78
+ name: 'client.alert.displayed',
79
+ options: {
80
+ meetingId: '123',
81
+ },
82
+ });
83
+
84
+ assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
85
+ key: 'client.alert.displayed',
86
+ options: {meetingId: '123'},
87
+ });
88
+ assert.calledWith(webex.internal.newMetrics.callDiagnosticMetrics.submitClientEvent, {
89
+ name: 'client.alert.displayed',
90
+ payload: undefined,
91
+ options: {meetingId: '123'},
92
+ });
93
+ });
94
+
95
+
96
+ it('submits MQE successfully', () => {
97
+ webex.internal.newMetrics.submitMQE({
98
+ name: 'client.mediaquality.event',
99
+ //@ts-ignore
100
+ payload: {intervals: [{}]},
101
+ options: {
102
+ meetingId: '123',
103
+ networkType: 'wifi',
104
+ },
105
+ });
106
+
107
+ assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
108
+ key: 'client.mediaquality.event',
109
+ });
110
+ assert.calledWith(webex.internal.newMetrics.callDiagnosticMetrics.submitMQE, {
111
+ name: 'client.mediaquality.event',
112
+ //@ts-ignore
113
+ payload: {intervals: [{}]},
114
+ options: {
115
+ meetingId: '123',
116
+ networkType: 'wifi',
117
+ },
118
+ });
119
+ });
120
+
121
+ it('submits Internal Event successfully', () => {
122
+ webex.internal.newMetrics.submitInternalEvent({
123
+ name: 'client.mediaquality.event',
124
+ });
125
+
126
+ assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
127
+ key: 'client.mediaquality.event',
128
+ });
129
+ assert.notCalled(webex.internal.newMetrics.callDiagnosticLatencies.clearTimestamps);
130
+ });
131
+
132
+ it('submits Internal Event successfully for clearing the join latencies', () => {
133
+ webex.internal.newMetrics.submitInternalEvent({
134
+ name: 'internal.reset.join.latencies',
135
+ });
136
+
137
+ assert.notCalled(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp);
138
+ assert.calledOnce(webex.internal.newMetrics.callDiagnosticLatencies.clearTimestamps);
139
+ });
140
+
141
+ describe('#clientMetricsAliasUser', () => {
142
+ it('aliases the user correctly', async () => {
143
+ webex.request.resolves({response: 'abc'});
144
+ await webex.internal.newMetrics.clientMetricsAliasUser('my-id');
145
+ assert.calledWith(webex.request, {
146
+ method: 'POST',
147
+ api: 'metrics',
148
+ resource: 'clientmetrics',
149
+ headers: { 'x-prelogin-userid': 'my-id' },
150
+ body: {},
151
+ qs: { alias: true },
152
+ });
153
+ assert.calledWith(
154
+ webex.logger.log,
155
+ 'NewMetrics: @clientMetricsAliasUser. Request successful.'
156
+ );
157
+ });
158
+
159
+ it('handles failed request correctly', async () => {
160
+ webex.request.rejects(new Error("test error"));
161
+ sinon.stub(Utils, 'generateCommonErrorMetadata').returns('formattedError')
162
+ try {
163
+ await webex.internal.newMetrics.clientMetricsAliasUser({event: 'test'}, 'my-id');
164
+ } catch (err) {
165
+ assert.calledWith(
166
+ webex.logger.error,
167
+ 'NewMetrics: @clientMetricsAliasUser. Request failed:',
168
+ `err: formattedError`
169
+ );
170
+ }
171
+ });
172
+ });
173
+
174
+ describe('#buildClientEventFetchRequestOptions', () => {
175
+ it('builds client event fetch options successfully', () => {
176
+ webex.internal.newMetrics.buildClientEventFetchRequestOptions({
177
+ name: 'client.alert.displayed',
178
+ options: {
179
+ meetingId: '123',
180
+ },
181
+ });
182
+
183
+ assert.calledWith(
184
+ webex.internal.newMetrics.callDiagnosticMetrics.buildClientEventFetchRequestOptions,
185
+ {
186
+ name: 'client.alert.displayed',
187
+ payload: undefined,
188
+ options: {meetingId: '123'},
189
+ }
190
+ );
191
+ });
192
+ });
193
+
194
+ describe('#setMetricTimingsAndFetch', () => {
195
+ beforeEach(() => {
196
+ global.fetch = sinon.stub();
197
+ });
198
+
199
+ it('calls fetch with the expected options', () => {
200
+ const now = new Date();
201
+ sinon.useFakeTimers(now.getTime());
202
+
203
+ webex.internal.newMetrics.setMetricTimingsAndFetch({
204
+ json: true,
205
+ body: JSON.stringify({metrics: [{eventPayload: {}}]}),
206
+ });
207
+
208
+ const expected = {
209
+ json: true,
210
+ body: JSON.stringify({
211
+ metrics: [
212
+ {
213
+ eventPayload: {
214
+ originTime: {
215
+ triggered: now.toISOString(),
216
+ sent: now.toISOString(),
217
+ },
218
+ },
219
+ },
220
+ ],
221
+ }),
222
+ };
223
+
224
+ sinon.assert.calledOnce(webex.setTimingsAndFetch);
225
+ sinon.assert.calledWith(webex.setTimingsAndFetch, expected);
226
+
227
+ sinon.restore();
228
+ });
229
+ });
230
+ });
231
+ });