@webex/internal-plugin-metrics 3.3.1 → 3.4.0-next.2

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 (49) hide show
  1. package/dist/behavioral-metrics.js +63 -0
  2. package/dist/behavioral-metrics.js.map +1 -0
  3. package/dist/business-metrics.js +62 -0
  4. package/dist/business-metrics.js.map +1 -0
  5. package/dist/call-diagnostic/call-diagnostic-metrics.js +3 -0
  6. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  7. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +14 -11
  8. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  9. package/dist/call-diagnostic/config.js +19 -13
  10. package/dist/call-diagnostic/config.js.map +1 -1
  11. package/dist/generic-metrics.js +184 -0
  12. package/dist/generic-metrics.js.map +1 -0
  13. package/dist/index.js +21 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/metrics.js +1 -1
  16. package/dist/metrics.types.js.map +1 -1
  17. package/dist/new-metrics.js +116 -23
  18. package/dist/new-metrics.js.map +1 -1
  19. package/dist/operational-metrics.js +56 -0
  20. package/dist/operational-metrics.js.map +1 -0
  21. package/dist/types/behavioral-metrics.d.ts +25 -0
  22. package/dist/types/business-metrics.d.ts +19 -0
  23. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +2 -2
  24. package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +3 -2
  25. package/dist/types/call-diagnostic/config.d.ts +2 -0
  26. package/dist/types/generic-metrics.d.ts +63 -0
  27. package/dist/types/index.d.ts +4 -1
  28. package/dist/types/metrics.types.d.ts +47 -15
  29. package/dist/types/new-metrics.d.ts +39 -11
  30. package/dist/types/operational-metrics.d.ts +19 -0
  31. package/package.json +11 -11
  32. package/src/behavioral-metrics.ts +40 -0
  33. package/src/business-metrics.ts +30 -0
  34. package/src/call-diagnostic/call-diagnostic-metrics.ts +3 -0
  35. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +16 -17
  36. package/src/call-diagnostic/config.ts +9 -2
  37. package/src/generic-metrics.ts +146 -0
  38. package/src/index.ts +6 -0
  39. package/src/metrics.types.ts +82 -18
  40. package/src/new-metrics.ts +95 -18
  41. package/src/operational-metrics.ts +24 -0
  42. package/test/unit/spec/behavioral/behavioral-metrics.ts +205 -0
  43. package/test/unit/spec/business/business-metrics.ts +120 -0
  44. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +48 -52
  45. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +1 -1
  46. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +9 -0
  47. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +41 -22
  48. package/test/unit/spec/operational/operational-metrics.ts +115 -0
  49. package/test/unit/spec/prelogin-metrics-batcher.ts +1 -1
@@ -0,0 +1,205 @@
1
+ import sinon from 'sinon';
2
+ import {assert} from '@webex/test-helper-chai';
3
+ import {BrowserDetection} from '@webex/common';
4
+ import {BehavioralMetrics, config, getOSNameInternal} from '@webex/internal-plugin-metrics';
5
+ import uuid from 'uuid';
6
+ import {merge} from 'lodash';
7
+
8
+ //@ts-ignore
9
+ global.window = {location: {hostname: 'whatever'}, navigator: {language: 'language'}};
10
+ process.env.NODE_ENV = 'test';
11
+
12
+ const {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
13
+
14
+ describe('internal-plugin-metrics', () => {
15
+ describe('BehavioralMetrics', () => {
16
+ let webex;
17
+ let now;
18
+ let behavioralMetrics: BehavioralMetrics;
19
+
20
+ const tags = {key: 'val'};
21
+
22
+ beforeEach(() => {
23
+ now = new Date();
24
+
25
+ webex = {
26
+ canAuthorize: true,
27
+ version: 'webex-version',
28
+ internal: {
29
+ services: {
30
+ get: () => 'locus-url',
31
+ },
32
+ metrics: {
33
+ submitClientMetrics: sinon.stub(),
34
+ config: {...config.metrics},
35
+ },
36
+ newMetrics: {},
37
+ device: {
38
+ userId: 'userId',
39
+ url: 'https://wdm-intb.ciscospark.com/wdm/api/v1/devices/deviceId',
40
+ orgId: 'orgId',
41
+ },
42
+ },
43
+ meetings: {
44
+ config: {
45
+ metrics: {
46
+ clientType: 'TEAMS_CLIENT',
47
+ subClientType: 'WEB_APP',
48
+ clientName: 'Cantina',
49
+ },
50
+ },
51
+ geoHintInfo: {
52
+ clientAddress: '1.3.4.5',
53
+ countryCode: 'UK',
54
+ },
55
+ },
56
+ credentials: {
57
+ isUnverifiedGuest: false,
58
+ },
59
+ prepareFetchOptions: sinon.stub().callsFake((opts: any) => ({...opts, foo: 'bar'})),
60
+ request: sinon.stub().resolves({body: {}}),
61
+ logger: {
62
+ log: sinon.stub(),
63
+ error: sinon.stub(),
64
+ },
65
+ };
66
+
67
+ sinon.createSandbox();
68
+ sinon.useFakeTimers(now.getTime());
69
+ behavioralMetrics = new BehavioralMetrics({}, {parent: webex});
70
+ sinon.stub(uuid, 'v4').returns('my-fake-id');
71
+ });
72
+
73
+ afterEach(() => {
74
+ sinon.restore();
75
+ });
76
+
77
+ describe('#sendEvent', () => {
78
+ it('should send correctly shaped behavioral event (check name building and internal tagged event building)', () => {
79
+ // For some reasons `jest` isn't available when testing form build server - so can't use `jest.fn()` here...
80
+ const requestCalls = [];
81
+ const request = function(arg) { requestCalls.push(arg) }
82
+
83
+ behavioralMetrics.clientMetricsBatcher.request = request;
84
+
85
+ assert.equal(requestCalls.length, 0)
86
+ behavioralMetrics.submitBehavioralEvent({ product: "webex", agent: "user", target: "foo", verb: "get", payload: {bar:"gee"} })
87
+ assert.equal(requestCalls.length, 1)
88
+ assert.deepEqual(requestCalls[0], {
89
+ context: {
90
+ app: {version: 'webex-version'},
91
+ device: {id: 'deviceId'},
92
+ locale: 'language',
93
+ os: {
94
+ name: getOSNameInternal(),
95
+ version: getOSVersion(),
96
+ },
97
+ },
98
+ metricName: 'webex.user.foo.get',
99
+ tags: {
100
+ browser: getBrowserName(),
101
+ browserHeight: window.innerHeight,
102
+ browserVersion: getBrowserVersion(),
103
+ browserWidth: window.innerWidth,
104
+ domain: window.location.hostname,
105
+ inIframe: false,
106
+ locale: window.navigator.language,
107
+ os: getOSNameInternal(),
108
+ bar:"gee"
109
+ },
110
+ timestamp: requestCalls[0].timestamp, // This is to bypass time check, which is correctly tested below.
111
+ type: ['behavioral'],
112
+ });
113
+ })
114
+ })
115
+
116
+ describe('#getContext', () => {
117
+ it('should build context correctly', () => {
118
+ const res = behavioralMetrics.getContext();
119
+
120
+ assert.deepEqual(res, {
121
+ app: {
122
+ version: 'webex-version',
123
+ },
124
+ device: {
125
+ id: 'deviceId',
126
+ },
127
+ locale: 'language',
128
+ os: {
129
+ name: getOSNameInternal(),
130
+ version: getOSVersion(),
131
+ },
132
+ });
133
+ });
134
+ });
135
+
136
+ describe('#getDefaultTags', () => {
137
+ it('should build tags correctly', () => {
138
+ const res = behavioralMetrics.getBrowserDetails();
139
+
140
+ assert.deepEqual(res, {
141
+ browser: getBrowserName(),
142
+ browserHeight: window.innerHeight,
143
+ browserVersion: getBrowserVersion(),
144
+ browserWidth: window.innerWidth,
145
+ domain: window.location.hostname,
146
+ inIframe: false,
147
+ locale: window.navigator.language,
148
+ os: getOSNameInternal(),
149
+ });
150
+ });
151
+ });
152
+
153
+ describe('#isReadyToSubmitEvents', () => {
154
+ it('should return true when we have a deviceId, false when deviceId is empty or undefined', async () => {
155
+ let deviceIdUrl = webex.internal.device.url;
156
+
157
+ // testing case w/o device id url first, as the internal deviceId cache would bypass that flow.
158
+ webex.internal.device.url = "";
159
+ assert.equal(false, behavioralMetrics.isReadyToSubmitEvents());
160
+
161
+ delete webex.internal.device.url;
162
+ assert.equal(false, behavioralMetrics.isReadyToSubmitEvents());
163
+
164
+ webex.internal.device.url = deviceIdUrl;
165
+ assert.equal(true, behavioralMetrics.isReadyToSubmitEvents());
166
+ });
167
+ });
168
+
169
+ describe('#createEventObject', () => {
170
+ it('should build event object correctly', async () => {
171
+ const res = behavioralMetrics.createTaggedEventObject({
172
+ type:['behavioral'],
173
+ name:'webex.user.target.create',
174
+ payload: tags,
175
+ });
176
+
177
+ assert.deepEqual(res, {
178
+ context: {
179
+ app: {
180
+ version: 'webex-version',
181
+ },
182
+ device: {
183
+ id: 'deviceId',
184
+ },
185
+ locale: 'language',
186
+ os: {
187
+ name: getOSNameInternal(),
188
+ version: getOSVersion(),
189
+ },
190
+ },
191
+ metricName: 'webex.user.target.create',
192
+ tags: merge(tags, {
193
+ browser: getBrowserName(),
194
+ browserVersion: getBrowserVersion(),
195
+ domain: window.location.hostname,
196
+ locale: window.navigator.language,
197
+ os: getOSNameInternal(),
198
+ }),
199
+ timestamp: res.timestamp,
200
+ type: ['behavioral'],
201
+ });
202
+ });
203
+ });
204
+ });
205
+ });
@@ -0,0 +1,120 @@
1
+ import sinon from 'sinon';
2
+ import {assert} from '@webex/test-helper-chai';
3
+ import {BrowserDetection} from '@webex/common';
4
+ import {BusinessMetrics, config, getOSNameInternal} from '@webex/internal-plugin-metrics';
5
+ import uuid from 'uuid';
6
+
7
+ //@ts-ignore
8
+ global.window = {location: {hostname: 'whatever'}, navigator: {language: 'language'}};
9
+ process.env.NODE_ENV = 'test';
10
+
11
+ const {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
12
+
13
+ describe('internal-plugin-metrics', () => {
14
+ describe('BusinessMetrics', () => {
15
+ let webex;
16
+ let now;
17
+ let businessMetrics: BusinessMetrics;
18
+
19
+ const tags = {key: 'val'};
20
+
21
+ beforeEach(() => {
22
+ now = new Date();
23
+
24
+ webex = {
25
+ canAuthorize: true,
26
+ version: 'webex-version',
27
+ internal: {
28
+ services: {
29
+ get: () => 'locus-url',
30
+ },
31
+ metrics: {
32
+ submitClientMetrics: sinon.stub(),
33
+ config: {...config.metrics},
34
+ },
35
+ newMetrics: {},
36
+ device: {
37
+ userId: 'userId',
38
+ url: 'https://wdm-intb.ciscospark.com/wdm/api/v1/devices/deviceId',
39
+ orgId: 'orgId',
40
+ },
41
+ },
42
+ meetings: {
43
+ config: {
44
+ metrics: {
45
+ clientType: 'TEAMS_CLIENT',
46
+ subClientType: 'WEB_APP',
47
+ clientName: 'Cantina',
48
+ },
49
+ },
50
+ geoHintInfo: {
51
+ clientAddress: '1.3.4.5',
52
+ countryCode: 'UK',
53
+ },
54
+ },
55
+ credentials: {
56
+ isUnverifiedGuest: false,
57
+ },
58
+ prepareFetchOptions: sinon.stub().callsFake((opts: any) => ({...opts, foo: 'bar'})),
59
+ request: sinon.stub().resolves({body: {}}),
60
+ logger: {
61
+ log: sinon.stub(),
62
+ error: sinon.stub(),
63
+ },
64
+ };
65
+
66
+ sinon.createSandbox();
67
+ sinon.useFakeTimers(now.getTime());
68
+ businessMetrics = new BusinessMetrics({}, {parent: webex});
69
+ sinon.stub(uuid, 'v4').returns('my-fake-id');
70
+ });
71
+
72
+ afterEach(() => {
73
+ sinon.restore();
74
+ });
75
+
76
+ describe('#sendEvent', () => {
77
+ it('should send correctly shaped business event (check name building and internal tagged event building)', () => {
78
+ // For some reasons `jest` isn't available when testing form build server - so can't use `jest.fn()` here...
79
+ const requestCalls = [];
80
+ const request = function(arg) { requestCalls.push(arg) }
81
+
82
+ businessMetrics.clientMetricsBatcher.request = request;
83
+
84
+ assert.equal(requestCalls.length, 0)
85
+ businessMetrics.submitBusinessEvent({ name: "foobar", payload: {bar:"gee"} })
86
+ assert.equal(requestCalls.length, 1)
87
+ assert.deepEqual(requestCalls[0], {
88
+ eventPayload: {
89
+ context: {
90
+ app: {version: 'webex-version'},
91
+ device: {id: 'deviceId'},
92
+ locale: 'language',
93
+ os: {
94
+ name: getOSNameInternal(),
95
+ version: getOSVersion(),
96
+ },
97
+ },
98
+ metricName: 'foobar',
99
+ browserDetails: {
100
+ browser: getBrowserName(),
101
+ browserHeight: window.innerHeight,
102
+ browserVersion: getBrowserVersion(),
103
+ browserWidth: window.innerWidth,
104
+ domain: window.location.hostname,
105
+ inIframe: false,
106
+ locale: window.navigator.language,
107
+ os: getOSNameInternal(),
108
+ },
109
+ timestamp: requestCalls[0].eventPayload.timestamp, // This is to bypass time check, which is checked below.
110
+ value: {
111
+ bar: "gee"
112
+ }
113
+ },
114
+ type: ['business'],
115
+ });
116
+ assert.isNumber(requestCalls[0].eventPayload.timestamp)
117
+ })
118
+ })
119
+ });
120
+ });
@@ -248,9 +248,15 @@ describe('plugin-metrics', () => {
248
248
  });
249
249
 
250
250
  it('appends the correct join times to the request for client.media.rx.start', async () => {
251
- webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
251
+ webex.internal.newMetrics.callDiagnosticLatencies.getLocalSDPGenRemoteSDPRecv = sinon
252
+ .stub()
253
+ .returns(5);
254
+ webex.internal.newMetrics.callDiagnosticLatencies.getAudioJoinRespRxStart = sinon
252
255
  .stub()
253
256
  .returns(10);
257
+ webex.internal.newMetrics.callDiagnosticLatencies.getVideoJoinRespRxStart = sinon
258
+ .stub()
259
+ .returns(20);
254
260
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
255
261
  //@ts-ignore
256
262
  {event: {name: 'client.media.rx.start'}}
@@ -265,7 +271,13 @@ describe('plugin-metrics', () => {
265
271
  assert.deepEqual(webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event, {
266
272
  name: 'client.media.rx.start',
267
273
  joinTimes: {
268
- localSDPGenRemoteSDPRecv: 10,
274
+ localSDPGenRemoteSDPRecv: 5,
275
+ },
276
+ audioSetupDelay: {
277
+ joinRespRxStart: 10,
278
+ },
279
+ videoSetupDelay: {
280
+ joinRespRxStart: 20,
269
281
  },
270
282
  });
271
283
  assert.lengthOf(
@@ -274,19 +286,16 @@ describe('plugin-metrics', () => {
274
286
  );
275
287
  });
276
288
 
277
- it('appends the correct join times to the request for client.media-engine.ready', async () => {
278
- webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
279
- .stub()
280
- .returns(10);
281
- webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToMediaOKJMT = sinon
289
+ it('appends the correct join times to the request for client.media.tx.start', async () => {
290
+ webex.internal.newMetrics.callDiagnosticLatencies.getAudioJoinRespTxStart = sinon
282
291
  .stub()
283
292
  .returns(10);
284
- webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
293
+ webex.internal.newMetrics.callDiagnosticLatencies.getVideoJoinRespTxStart = sinon
285
294
  .stub()
286
- .returns(10);
295
+ .returns(20);
287
296
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
288
297
  //@ts-ignore
289
- {event: {name: 'client.media-engine.ready'}}
298
+ {event: {name: 'client.media.tx.start'}}
290
299
  );
291
300
  await flushPromises();
292
301
  clock.tick(config.metrics.batcherWait);
@@ -296,12 +305,12 @@ describe('plugin-metrics', () => {
296
305
  //@ts-ignore
297
306
  assert.calledOnce(webex.request);
298
307
  assert.deepEqual(webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event, {
299
- name: 'client.media-engine.ready',
300
- joinTimes: {
301
- totalMediaJMT: 30,
302
- interstitialToMediaOKJMT: 10,
303
- callInitMediaEngineReady: 10,
304
- stayLobbyTime: 10,
308
+ name: 'client.media.tx.start',
309
+ audioSetupDelay: {
310
+ joinRespTxStart: 10,
311
+ },
312
+ videoSetupDelay: {
313
+ joinRespTxStart: 20,
305
314
  },
306
315
  });
307
316
  assert.lengthOf(
@@ -310,13 +319,28 @@ describe('plugin-metrics', () => {
310
319
  );
311
320
  });
312
321
 
313
- it('appends the correct audio and video setup delays to the request for client.mediaquality.event', async () => {
322
+ it('appends the correct join times to the request for client.media-engine.ready', async () => {
314
323
  webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
315
324
  .stub()
316
325
  .returns(10);
326
+ webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToMediaOKJMT = sinon
327
+ .stub()
328
+ .returns(22);
329
+ webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
330
+ .stub()
331
+ .returns(35);
332
+ webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToJoinOK = sinon
333
+ .stub()
334
+ .returns(5);
335
+ webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToJoinOK = sinon
336
+ .stub()
337
+ .returns(7);
338
+ webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTime = sinon
339
+ .stub()
340
+ .returns(1);
317
341
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
318
342
  //@ts-ignore
319
- {event: {name: 'client.mediaquality.event'}}
343
+ {event: {name: 'client.media-engine.ready'}}
320
344
  );
321
345
  await flushPromises();
322
346
  clock.tick(config.metrics.batcherWait);
@@ -326,14 +350,12 @@ describe('plugin-metrics', () => {
326
350
  //@ts-ignore
327
351
  assert.calledOnce(webex.request);
328
352
  assert.deepEqual(webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event, {
329
- name: 'client.mediaquality.event',
330
- audioSetupDelay: {
331
- joinRespRxStart: 10,
332
- joinRespTxStart: 10,
333
- },
334
- videoSetupDelay: {
335
- joinRespRxStart: 10,
336
- joinRespTxStart: 10,
353
+ name: 'client.media-engine.ready',
354
+ joinTimes: {
355
+ totalMediaJMT: 61,
356
+ interstitialToMediaOKJMT: 22,
357
+ callInitMediaEngineReady: 10,
358
+ stayLobbyTime: 1,
337
359
  },
338
360
  });
339
361
  assert.lengthOf(
@@ -341,32 +363,6 @@ describe('plugin-metrics', () => {
341
363
  0
342
364
  );
343
365
  });
344
-
345
- it('doesnt include audioSetup and videoSetup delays for other events', async () => {
346
- const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
347
- //@ts-ignore
348
- {event: {name: 'client.alert.displayed'}}
349
- );
350
- await flushPromises();
351
- clock.tick(config.metrics.batcherWait);
352
-
353
- await promise;
354
-
355
- //@ts-ignore
356
- assert.calledOnce(webex.request);
357
- assert.deepEqual(
358
- webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event.audioSetupDelay,
359
- undefined
360
- );
361
- assert.deepEqual(
362
- webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event.videoSetupDelay,
363
- undefined
364
- );
365
- assert.lengthOf(
366
- webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
367
- 0
368
- );
369
- });
370
366
  });
371
367
 
372
368
  describe('when the request fails', () => {
@@ -668,7 +668,7 @@ describe('internal-plugin-metrics', () => {
668
668
  assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
669
669
  });
670
670
 
671
- it('calculates getU2CTime correctly', () => {
671
+ describe('calculates getU2CTime correctly', () => {
672
672
  it('returns undefined when no precomputed value available', () => {
673
673
  assert.deepEqual(cdl.getU2CTime(), undefined);
674
674
  });
@@ -1454,6 +1454,9 @@ describe('internal-plugin-metrics', () => {
1454
1454
  eventData: {webClientDomain: 'whatever'},
1455
1455
  intervals: [{}],
1456
1456
  callingServiceType: 'LOCUS',
1457
+ meetingJoinInfo: {
1458
+ clientSignallingProtocol: 'WebRTC',
1459
+ },
1457
1460
  sourceMetadata: {
1458
1461
  applicationSoftwareType: 'webex-js-sdk',
1459
1462
  applicationSoftwareVersion: 'webex-version',
@@ -1490,6 +1493,9 @@ describe('internal-plugin-metrics', () => {
1490
1493
  eventData: {webClientDomain: 'whatever'},
1491
1494
  intervals: [{}],
1492
1495
  callingServiceType: 'LOCUS',
1496
+ meetingJoinInfo: {
1497
+ clientSignallingProtocol: 'WebRTC',
1498
+ },
1493
1499
  sourceMetadata: {
1494
1500
  applicationSoftwareType: 'webex-js-sdk',
1495
1501
  applicationSoftwareVersion: 'webex-version',
@@ -1524,6 +1530,9 @@ describe('internal-plugin-metrics', () => {
1524
1530
  eventData: {webClientDomain: 'whatever'},
1525
1531
  intervals: [{}],
1526
1532
  callingServiceType: 'LOCUS',
1533
+ meetingJoinInfo: {
1534
+ clientSignallingProtocol: 'WebRTC',
1535
+ },
1527
1536
  sourceMetadata: {
1528
1537
  applicationSoftwareType: 'webex-js-sdk',
1529
1538
  applicationSoftwareVersion: 'webex-version',
@@ -7,6 +7,7 @@ import CallDiagnosticLatencies from '../../../../src/call-diagnostic/call-diagno
7
7
  import {
8
8
  DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
9
9
  ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE,
10
+ ICE_AND_REACHABILITY_FAILED_CLIENT_CODE,
10
11
  ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE,
11
12
  MISSING_ROAP_ANSWER_CLIENT_CODE,
12
13
  } from '../../../../src/call-diagnostic/config';
@@ -374,6 +375,12 @@ describe('internal-plugin-metrics', () => {
374
375
  joinTimes: {
375
376
  localSDPGenRemoteSDPRecv: undefined,
376
377
  },
378
+ audioSetupDelay: {
379
+ joinRespRxStart: undefined,
380
+ },
381
+ videoSetupDelay: {
382
+ joinRespRxStart: undefined,
383
+ },
377
384
  },
378
385
  ],
379
386
  [
@@ -388,14 +395,12 @@ describe('internal-plugin-metrics', () => {
388
395
  },
389
396
  ],
390
397
  [
391
- 'client.mediaquality.event',
398
+ 'client.media.tx.start',
392
399
  {
393
400
  audioSetupDelay: {
394
- joinRespRxStart: undefined,
395
401
  joinRespTxStart: undefined,
396
402
  },
397
403
  videoSetupDelay: {
398
- joinRespRxStart: undefined,
399
404
  joinRespTxStart: undefined,
400
405
  },
401
406
  },
@@ -406,20 +411,28 @@ describe('internal-plugin-metrics', () => {
406
411
  });
407
412
  });
408
413
 
409
- it('calls getBuildType correctly', () => {
410
- const getBuildTypeSpy = sinon.spy(CallDiagnosticUtils, 'getBuildType');
411
- const markAsTestEvent = true;
412
- const webClientDomain = 'https://web.webex.com';
413
-
414
- // just submit any event
415
- prepareDiagnosticMetricItem(webex, {
414
+ it('getBuildType returns correct value', () => {
415
+ const item: any = {
416
416
  eventPayload: {
417
- event: {name: 'client.exit.app', eventData: {markAsTestEvent, webClientDomain}},
417
+ event: {
418
+ name: 'client.exit.app',
419
+ eventData: {
420
+ markAsTestEvent: true,
421
+ webClientDomain: 'https://web.webex.com'
422
+ }
423
+ },
418
424
  },
419
425
  type: ['diagnostic-event'],
420
- });
426
+ };
421
427
 
422
- assert.calledOnceWithExactly(getBuildTypeSpy, webClientDomain, markAsTestEvent);
428
+ // just submit any event
429
+ prepareDiagnosticMetricItem(webex, item);
430
+ assert.deepEqual(item.eventPayload.origin.buildType, 'test');
431
+
432
+ delete item.eventPayload.origin.buildType;
433
+ item.eventPayload.event.eventData.markAsTestEvent = false;
434
+ prepareDiagnosticMetricItem(webex, item);
435
+ assert.deepEqual(item.eventPayload.origin.buildType, 'prod');
423
436
  });
424
437
  });
425
438
 
@@ -605,41 +618,47 @@ describe('internal-plugin-metrics', () => {
605
618
  [
606
619
  {
607
620
  signalingState: 'have-local-offer',
608
- iceConnectionState: 'connected',
621
+ iceConnected: false,
609
622
  turnServerUsed: true,
610
623
  errorCode: MISSING_ROAP_ANSWER_CLIENT_CODE,
624
+ unreachable: false,
611
625
  },
612
626
  {
613
627
  signalingState: 'stable',
614
- iceConnectionState: 'connected',
628
+ iceConnected: true,
615
629
  turnServerUsed: true,
616
630
  errorCode: DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
631
+ unreachable: false,
617
632
  },
618
633
  {
619
634
  signalingState: 'stable',
620
- iceConnectionState: 'disconnected',
635
+ iceConnected: false,
621
636
  turnServerUsed: true,
622
- errorCode: DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
637
+ errorCode: ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE,
638
+ unreachable: false,
623
639
  },
624
640
  {
625
641
  signalingState: 'stable',
626
- iceConnectionState: 'failed',
642
+ iceConnected: false,
627
643
  turnServerUsed: true,
628
- errorCode: ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE,
644
+ errorCode: ICE_AND_REACHABILITY_FAILED_CLIENT_CODE,
645
+ unreachable: true,
629
646
  },
630
647
  {
631
648
  signalingState: 'stable',
632
- iceConnectionState: 'failed',
649
+ iceConnected: false,
633
650
  turnServerUsed: false,
634
651
  errorCode: ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE,
652
+ unreachable: false,
635
653
  },
636
- ].forEach(({signalingState, iceConnectionState, turnServerUsed, errorCode}: any) => {
654
+ ].forEach(({signalingState, iceConnected, turnServerUsed, errorCode, unreachable}: any) => {
637
655
  it('returns expected result', () => {
638
656
  assert.deepEqual(
639
657
  generateClientErrorCodeForIceFailure({
640
658
  signalingState,
641
- iceConnectionState,
659
+ iceConnected,
642
660
  turnServerUsed,
661
+ unreachable,
643
662
  }),
644
663
  errorCode
645
664
  );