@webex/plugin-meetings 3.0.0-beta.162 → 3.0.0-beta.164

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 (64) hide show
  1. package/dist/breakouts/breakout.js +7 -3
  2. package/dist/breakouts/breakout.js.map +1 -1
  3. package/dist/breakouts/events.js +31 -29
  4. package/dist/breakouts/events.js.map +1 -1
  5. package/dist/breakouts/index.js +4 -2
  6. package/dist/breakouts/index.js.map +1 -1
  7. package/dist/constants.js +2 -4
  8. package/dist/constants.js.map +1 -1
  9. package/dist/interpretation/index.js +1 -1
  10. package/dist/interpretation/siLanguage.js +1 -1
  11. package/dist/locus-info/index.js +33 -17
  12. package/dist/locus-info/index.js.map +1 -1
  13. package/dist/meeting/index.js +699 -682
  14. package/dist/meeting/index.js.map +1 -1
  15. package/dist/meeting/util.js +47 -25
  16. package/dist/meeting/util.js.map +1 -1
  17. package/dist/meeting-info/index.js +48 -7
  18. package/dist/meeting-info/index.js.map +1 -1
  19. package/dist/meeting-info/meeting-info-v2.js +24 -10
  20. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  21. package/dist/meetings/index.js +12 -9
  22. package/dist/meetings/index.js.map +1 -1
  23. package/dist/metrics/index.js +1 -487
  24. package/dist/metrics/index.js.map +1 -1
  25. package/dist/reconnection-manager/index.js +27 -17
  26. package/dist/reconnection-manager/index.js.map +1 -1
  27. package/dist/roap/request.js +20 -14
  28. package/dist/roap/request.js.map +1 -1
  29. package/dist/types/breakouts/events.d.ts +7 -1
  30. package/dist/types/constants.d.ts +0 -1
  31. package/dist/types/meeting/index.d.ts +31 -133
  32. package/dist/types/meeting-info/index.d.ts +6 -1
  33. package/dist/types/meetings/index.d.ts +1 -0
  34. package/dist/types/metrics/index.d.ts +4 -128
  35. package/package.json +19 -19
  36. package/src/breakouts/breakout.ts +10 -2
  37. package/src/breakouts/events.ts +51 -32
  38. package/src/breakouts/index.ts +9 -5
  39. package/src/constants.ts +0 -2
  40. package/src/locus-info/index.ts +35 -17
  41. package/src/meeting/index.ts +474 -536
  42. package/src/meeting/util.ts +42 -19
  43. package/src/meeting-info/index.ts +54 -8
  44. package/src/meeting-info/meeting-info-v2.ts +24 -9
  45. package/src/meetings/index.ts +11 -6
  46. package/src/metrics/index.ts +1 -506
  47. package/src/reconnection-manager/index.ts +27 -17
  48. package/src/roap/request.ts +21 -9
  49. package/test/unit/spec/breakouts/breakout.ts +4 -2
  50. package/test/unit/spec/breakouts/events.ts +24 -18
  51. package/test/unit/spec/locus-info/index.js +112 -0
  52. package/test/unit/spec/meeting/index.js +178 -145
  53. package/test/unit/spec/meeting/utils.js +93 -7
  54. package/test/unit/spec/meeting-info/index.js +181 -0
  55. package/test/unit/spec/meeting-info/meetinginfov2.js +68 -68
  56. package/test/unit/spec/meetings/index.js +35 -55
  57. package/test/unit/spec/metrics/index.js +1 -148
  58. package/test/unit/spec/reconnection-manager/index.js +51 -2
  59. package/test/unit/spec/roap/index.ts +8 -2
  60. package/test/unit/spec/roap/request.ts +43 -5
  61. package/dist/metrics/config.js +0 -335
  62. package/dist/metrics/config.js.map +0 -1
  63. package/dist/types/metrics/config.d.ts +0 -195
  64. package/src/metrics/config.ts +0 -534
@@ -3,16 +3,17 @@ import {assert} from '@webex/test-helper-chai';
3
3
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
4
4
  import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
5
5
  import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
6
- import Metrics from '@webex/plugin-meetings/src/metrics/index';
7
6
  import {DISPLAY_HINTS} from '@webex/plugin-meetings/src/constants';
7
+ import MockWebex from '@webex/test-helper-mock-webex';
8
8
 
9
9
  describe('plugin-meetings', () => {
10
+ let webex;
10
11
  describe('Meeting utils function', () => {
11
12
  const sandbox = sinon.createSandbox();
12
13
  const meeting = {};
13
14
 
14
15
  beforeEach(() => {
15
- Metrics.postEvent = sinon.stub();
16
+ webex = new MockWebex({});
16
17
  const logger = {
17
18
  info: sandbox.stub(),
18
19
  log: sandbox.stub(),
@@ -37,11 +38,13 @@ describe('plugin-meetings', () => {
37
38
  meeting.updateLLMConnection = sinon.stub();
38
39
  meeting.breakouts = {cleanUp: sinon.stub()};
39
40
  meeting.annotaion = {cleanUp: sinon.stub()};
41
+ meeting.getWebexObject = sinon.stub().returns(webex);
40
42
  meeting.simultaneousInterpretation = {cleanUp: sinon.stub()};
41
43
  });
42
44
 
43
45
  afterEach(() => {
44
46
  sandbox.restore();
47
+ sinon.restore();
45
48
  });
46
49
 
47
50
  describe('#cleanup', () => {
@@ -175,14 +178,14 @@ describe('plugin-meetings', () => {
175
178
  it('should call onDeltaLocus with the new delta locus', () => {
176
179
  const meeting = {
177
180
  locusInfo: {
178
- onDeltaLocus: sinon.stub(),
179
- }
180
- }
181
+ onDeltaLocus: sinon.stub()
182
+ },
183
+ };
181
184
 
182
185
  const originalResponse = {
183
186
  body: {
184
187
  locus: 'locus'
185
- }
188
+ },
186
189
  };
187
190
 
188
191
  const response = MeetingUtil.updateLocusWithDelta(meeting, originalResponse);
@@ -269,6 +272,7 @@ describe('plugin-meetings', () => {
269
272
  describe('remoteUpdateAudioVideo', () => {
270
273
  it('#Should call meetingRequest.locusMediaRequest with correct parameters', async () => {
271
274
  const meeting = {
275
+ id: 'meeting-id',
272
276
  mediaId: '12345',
273
277
  selfUrl: 'self url',
274
278
  locusInfo: {
@@ -277,6 +281,7 @@ describe('plugin-meetings', () => {
277
281
  locusMediaRequest: {
278
282
  send: sinon.stub().resolves({body: {}, headers: {}}),
279
283
  },
284
+ getWebexObject: sinon.stub().returns(webex)
280
285
  };
281
286
 
282
287
  await MeetingUtil.remoteUpdateAudioVideo(meeting, true, false);
@@ -291,6 +296,16 @@ describe('plugin-meetings', () => {
291
296
  sequence: {},
292
297
  type: 'LocalMute',
293
298
  });
299
+
300
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
301
+ name: 'client.locus.media.request',
302
+ options: {meetingId: meeting.id},
303
+ });
304
+
305
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
306
+ name: 'client.locus.media.response',
307
+ options: {meetingId: meeting.id},
308
+ });
294
309
  });
295
310
  });
296
311
 
@@ -300,8 +315,16 @@ describe('plugin-meetings', () => {
300
315
  meetingJoinUrl: 'meetingJoinUrl',
301
316
  locusUrl: 'locusUrl',
302
317
  meetingRequest: {
303
- joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
318
+ joinMeeting: sinon.stub().returns(
319
+ Promise.resolve({
320
+ body: {mediaConnections: 'mediaConnections'},
321
+ headers: {
322
+ trackingid: 'trackingId',
323
+ },
324
+ })
325
+ ),
304
326
  },
327
+ getWebexObject: sinon.stub().returns(webex)
305
328
  };
306
329
 
307
330
  MeetingUtil.parseLocusJoin = sinon.stub();
@@ -312,6 +335,25 @@ describe('plugin-meetings', () => {
312
335
 
313
336
  assert.equal(parameter.inviteeAddress, 'meetingJoinUrl');
314
337
  assert.equal(parameter.preferTranscoding, true);
338
+
339
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
340
+ name: 'client.locus.join.request',
341
+ options: {meetingId: meeting.id},
342
+ });
343
+
344
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
345
+ name: 'client.locus.join.response',
346
+ payload: {
347
+ trigger: 'loci-update',
348
+ identifiers: {
349
+ trackingId: 'trackingId',
350
+ },
351
+ },
352
+ options: {
353
+ meetingId: meeting.id,
354
+ mediaConnections: 'mediaConnections',
355
+ },
356
+ });
315
357
  });
316
358
 
317
359
  it('#Should call meetingRequest.joinMeeting with breakoutsSupported=true when passed in as true', async () => {
@@ -319,6 +361,7 @@ describe('plugin-meetings', () => {
319
361
  meetingRequest: {
320
362
  joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
321
363
  },
364
+ getWebexObject: sinon.stub().returns(webex)
322
365
  };
323
366
 
324
367
  MeetingUtil.parseLocusJoin = sinon.stub();
@@ -337,6 +380,7 @@ describe('plugin-meetings', () => {
337
380
  meetingRequest: {
338
381
  joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
339
382
  },
383
+ getWebexObject: sinon.stub().returns(webex)
340
384
  };
341
385
 
342
386
  MeetingUtil.parseLocusJoin = sinon.stub();
@@ -355,6 +399,7 @@ describe('plugin-meetings', () => {
355
399
  meetingRequest: {
356
400
  joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
357
401
  },
402
+ getWebexObject: sinon.stub().returns(webex)
358
403
  };
359
404
 
360
405
  MeetingUtil.parseLocusJoin = sinon.stub();
@@ -378,6 +423,7 @@ describe('plugin-meetings', () => {
378
423
  meetingRequest: {
379
424
  joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
380
425
  },
426
+ getWebexObject: sinon.stub().returns(webex)
381
427
  };
382
428
 
383
429
  MeetingUtil.parseLocusJoin = sinon.stub();
@@ -397,6 +443,7 @@ describe('plugin-meetings', () => {
397
443
  meetingRequest: {
398
444
  joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
399
445
  },
446
+ getWebexObject: sinon.stub().returns(webex)
400
447
  };
401
448
 
402
449
  MeetingUtil.parseLocusJoin = sinon.stub();
@@ -415,6 +462,7 @@ describe('plugin-meetings', () => {
415
462
  meetingRequest: {
416
463
  joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
417
464
  },
465
+ getWebexObject: sinon.stub().returns(webex)
418
466
  };
419
467
 
420
468
  MeetingUtil.parseLocusJoin = sinon.stub();
@@ -428,6 +476,44 @@ describe('plugin-meetings', () => {
428
476
  });
429
477
  });
430
478
 
479
+ describe('joinMeetingOptions', () => {
480
+ it('sends client events correctly', async () => {
481
+ MeetingUtil.joinMeeting = sinon.stub().rejects({});
482
+ MeetingUtil.isPinOrGuest = sinon.stub().returns(true);
483
+ const meeting = {
484
+ id: 'meeting-id',
485
+ mediaId: '12345',
486
+ selfUrl: 'self url',
487
+ locusInfo: {
488
+ sequence: {},
489
+ },
490
+ locusMediaRequest: {
491
+ send: sinon.stub().resolves({body: {}, headers: {}}),
492
+ },
493
+ getWebexObject: sinon.stub().returns(webex)
494
+ };
495
+
496
+ try {
497
+ await MeetingUtil.joinMeetingOptions(meeting, {pin: true});
498
+
499
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
500
+ name: 'client.pin.collected',
501
+ options: {
502
+ meetingId: meeting.id,
503
+ },
504
+ });
505
+ } catch (err) {
506
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
507
+ name: 'client.pin.prompt',
508
+ options: {
509
+ meetingId: meeting.id,
510
+ },
511
+ });
512
+ }
513
+ });
514
+
515
+ })
516
+
431
517
  describe('getUserDisplayHintsFromLocusInfo', () => {
432
518
  it('returns display hints', () => {
433
519
  assert.deepEqual(MeetingUtil.getUserDisplayHintsFromLocusInfo(), []);
@@ -0,0 +1,181 @@
1
+ import {assert} from '@webex/test-helper-chai';
2
+ import sinon from 'sinon';
3
+ import MockWebex from '@webex/test-helper-mock-webex';
4
+ import {_MEETING_ID_} from '@webex/plugin-meetings/src/constants';
5
+
6
+ import MeetingInfo from '@webex/plugin-meetings/src/meeting-info/index';
7
+ import MeetingInfoUtil from '@webex/plugin-meetings/src/meeting-info/util';
8
+ import MeetingInfoRequest from '@webex/plugin-meetings/src/meeting-info/request';
9
+
10
+ const flushPromises = () => new Promise(setImmediate);
11
+
12
+ describe('plugin-meetings', () => {
13
+ let webex;
14
+ let meetingInfo = null;
15
+
16
+ afterEach(() => {
17
+ sinon.restore();
18
+ });
19
+
20
+ describe('Meeting Info V1', () => {
21
+ beforeEach(() => {
22
+ webex = new MockWebex({});
23
+
24
+ meetingInfo = new MeetingInfo(webex);
25
+ });
26
+
27
+ describe('#fetchMeetingInfo', () => {
28
+ it('should send ca events if meetingId present', async () => {
29
+ const body = {meetingKey: '1234323'};
30
+
31
+ sinon
32
+ .stub(MeetingInfoUtil, 'generateOptions')
33
+ .resolves({type: 'MEETING_ID', destination: '123456'});
34
+ sinon.stub(MeetingInfoRequest.prototype, 'fetchMeetingInfo').returns(Promise.resolve(body));
35
+
36
+ await meetingInfo.fetchMeetingInfo('1234323', _MEETING_ID_, null, null, null, null, null, {
37
+ meetingId: 'meetingId',
38
+ });
39
+
40
+ const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
41
+
42
+ assert.deepEqual(submitInternalEventCalls[0].args[0], {
43
+ name: 'internal.client.meetinginfo.request',
44
+ });
45
+ assert.deepEqual(submitInternalEventCalls[1].args[0], {
46
+ name: 'internal.client.meetinginfo.response',
47
+ });
48
+ });
49
+
50
+ it('should not send ca events if meetingId not present', async () => {
51
+ const body = {meetingKey: '1234323'};
52
+
53
+ sinon
54
+ .stub(MeetingInfoUtil, 'generateOptions')
55
+ .resolves({type: 'MEETING_ID', destination: '123456'});
56
+ sinon.stub(MeetingInfoRequest.prototype, 'fetchMeetingInfo').returns(Promise.resolve(body));
57
+
58
+ await meetingInfo.fetchMeetingInfo('1234323', _MEETING_ID_, null, null, null, null, null);
59
+
60
+ assert.notCalled(webex.internal.newMetrics.submitInternalEvent);
61
+ });
62
+
63
+ it('should send ca events when fails and if meetingId present', async () => {
64
+ const reject = {
65
+ statusCode: 403,
66
+ body: {message: 'msg', code: 403102, data: {meetingInfo: {}}},
67
+ url: 'http://api-url.com',
68
+ };
69
+
70
+ sinon
71
+ .stub(MeetingInfoUtil, 'generateOptions')
72
+ .returns(Promise.resolve({type: 'MEETING_ID', destination: '123456'}));
73
+ sinon
74
+ .stub(MeetingInfoRequest.prototype, 'fetchMeetingInfo')
75
+ .returns(Promise.reject(reject));
76
+
77
+ try {
78
+ await meetingInfo.fetchMeetingInfo(
79
+ '1234323',
80
+ _MEETING_ID_,
81
+ null,
82
+ null,
83
+ null,
84
+ null,
85
+ null,
86
+ {
87
+ meetingId: 'meetingId',
88
+ }
89
+ );
90
+ } catch (err) {
91
+ const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
92
+
93
+ assert.deepEqual(submitInternalEventCalls[0].args[0], {
94
+ name: 'internal.client.meetinginfo.request',
95
+ });
96
+
97
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
98
+ name: 'client.meetinginfo.response',
99
+ payload: {
100
+ identifiers: {
101
+ meetingLookupUrl: 'http://api-url.com',
102
+ },
103
+ },
104
+ options: {
105
+ meetingId: 'meetingId',
106
+ rawError: err,
107
+ },
108
+ });
109
+ }
110
+ });
111
+
112
+ it('should send ca events when in the retry as well if meetingId present', async () => {
113
+ const reject = {
114
+ statusCode: 403,
115
+ body: {message: 'msg', code: 403102, data: {meetingInfo: {}}},
116
+ url: 'http://api-url.com',
117
+ };
118
+
119
+ sinon
120
+ .stub(MeetingInfoUtil, 'generateOptions')
121
+ .resolves({type: 'MEETING_LINK', destination: '123456'});
122
+ const requestStub = sinon
123
+ .stub(MeetingInfoRequest.prototype, 'fetchMeetingInfo')
124
+ .rejects(reject);
125
+
126
+ try {
127
+ await meetingInfo.fetchMeetingInfo(
128
+ '1234323',
129
+ _MEETING_ID_,
130
+ null,
131
+ null,
132
+ null,
133
+ null,
134
+ null,
135
+ {
136
+ meetingId: 'meetingId',
137
+ }
138
+ );
139
+ assert.fail('fetchMeetingInfo should have thrown, but has not done that');
140
+ } catch (err) {
141
+ let submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
142
+
143
+ assert.deepEqual(submitInternalEventCalls[0].args[0], {
144
+ name: 'internal.client.meetinginfo.request',
145
+ });
146
+
147
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
148
+ name: 'client.meetinginfo.response',
149
+ payload: {
150
+ identifiers: {
151
+ meetingLookupUrl: 'http://api-url.com',
152
+ },
153
+ },
154
+ options: {
155
+ meetingId: 'meetingId',
156
+ rawError: err,
157
+ },
158
+ });
159
+
160
+ assert.deepEqual(submitInternalEventCalls[1].args[0], {
161
+ name: 'internal.client.meetinginfo.response',
162
+ });
163
+
164
+ assert.deepEqual(submitInternalEventCalls[2].args[0], {
165
+ name: 'internal.client.meetinginfo.request',
166
+ });
167
+
168
+ requestStub.resolves({});
169
+
170
+ await flushPromises();
171
+
172
+ submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
173
+
174
+ assert.deepEqual(submitInternalEventCalls[3].args[0], {
175
+ name: 'internal.client.meetinginfo.response',
176
+ });
177
+ }
178
+ });
179
+ });
180
+ });
181
+ });
@@ -382,7 +382,6 @@ describe('plugin-meetings', () => {
382
382
  ],
383
383
  ({errorCode}) => {
384
384
  it(`should throw a MeetingInfoV2PolicyError for error code ${errorCode}`, async () => {
385
- Metrics.postEvent = sinon.stub();
386
385
  const message = 'a message';
387
386
  const meetingInfoData = 'meeting info';
388
387
 
@@ -407,34 +406,29 @@ describe('plugin-meetings', () => {
407
406
  );
408
407
  assert.fail('fetchMeetingInfo should have thrown, but has not done that');
409
408
  } catch (err) {
410
- assert(Metrics.postEvent.calledOnce);
411
- assert.calledWith(Metrics.postEvent, {
412
- event: 'client.meetinginfo.response',
413
- meetingId: 'meeting-id',
414
- data: {
415
- errors: [
416
- {
417
- category: 'signaling',
418
- errorCode: 4100,
419
- errorData: {
420
- error: {
421
- code: errorCode,
422
- data: {
423
- meetingInfo: 'meeting info',
424
- },
425
- message: 'a message',
426
- }
427
- },
428
- errorDescription: 'MeetingInfoLookupError',
429
- fatal: true,
430
- httpCode: 403,
431
- name: 'other',
432
- serviceErrorCode: errorCode,
433
- shownToUser: true,
434
- },
435
- ],
436
- meetingLookupUrl: 'http://api-url.com',
437
- }
409
+ assert(webex.internal.newMetrics.submitClientEvent.calledOnce);
410
+ const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
411
+ assert.deepEqual(submitInternalEventCalls[0].args[0], {
412
+ name: 'internal.client.meetinginfo.request',
413
+ });
414
+ assert.deepEqual(submitInternalEventCalls[1].args[0], {
415
+ name: 'internal.client.meetinginfo.response',
416
+ });
417
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
418
+ name: 'client.meetinginfo.response',
419
+ payload: {
420
+ identifiers: {
421
+ meetingLookupUrl: 'http://api-url.com',
422
+ },
423
+ },
424
+ options: {
425
+ meetingId: 'meeting-id',
426
+ rawError: {
427
+ statusCode: 403,
428
+ body: {message, code: errorCode, data: {meetingInfo: meetingInfoData}},
429
+ url: 'http://api-url.com',
430
+ },
431
+ },
438
432
  });
439
433
 
440
434
  assert.instanceOf(err, MeetingInfoV2PolicyError);
@@ -452,44 +446,57 @@ describe('plugin-meetings', () => {
452
446
  }
453
447
  );
454
448
 
455
- it('should not send CA metric if meetingId is not provided', async () => {
456
- Metrics.postEvent = sinon.stub();
457
- const message = 'a message';
458
- const meetingInfoData = 'meeting info';
449
+ it('should send internal CA metric if meetingId is provided', async () => {
450
+ const requestResponse = {statusCode: 200, body: {meetingKey: '1234323'}};
451
+ const extraParams = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'}
459
452
 
460
- webex.request = sinon.stub().rejects({
461
- statusCode: 403,
462
- body: {message, code: 403102, data: {meetingInfo: meetingInfoData}},
463
- url: 'http://api-url.com',
453
+ webex.request.resolves(requestResponse);
454
+
455
+ const result = await meetingInfo.fetchMeetingInfo(
456
+ '1234323',
457
+ _MEETING_ID_,
458
+ null,
459
+ null,
460
+ null,
461
+ null,
462
+ extraParams,
463
+ {meetingId: 'meetingId'}
464
+ );
465
+
466
+ assert.calledWith(webex.request, {
467
+ method: 'POST',
468
+ service: WBXAPPAPI_SERVICE,
469
+ resource: 'meetingInfo',
470
+ body: {
471
+ supportHostKey: true,
472
+ supportCountryList: true,
473
+ meetingKey: '1234323',
474
+ ...extraParams,
475
+ },
476
+ });
477
+ assert.deepEqual(result, requestResponse);
478
+ assert(Metrics.sendBehavioralMetric.calledOnce);
479
+ assert.calledWith(
480
+ Metrics.sendBehavioralMetric,
481
+ BEHAVIORAL_METRICS.FETCH_MEETING_INFO_V1_SUCCESS
482
+ );
483
+
484
+ const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
485
+ assert.deepEqual(submitInternalEventCalls[0].args[0], {
486
+ name: 'internal.client.meetinginfo.request',
487
+ });
488
+ assert.deepEqual(submitInternalEventCalls[1].args[0], {
489
+ name: 'internal.client.meetinginfo.response',
464
490
  });
465
- try {
466
- await meetingInfo.fetchMeetingInfo(
467
- '1234323',
468
- _MEETING_ID_,
469
- 'abc',
470
- {
471
- id: '999',
472
- code: 'aabbcc11',
473
- },
474
- null,
475
- null,
476
- undefined
477
- );
478
- assert.fail('fetchMeetingInfo should have thrown, but has not done that');
479
- } catch (err) {
480
- assert.notCalled(Metrics.postEvent);
481
- }
482
491
  });
483
492
 
484
- it('should not have errors if parsing error returns null', async () => {
485
- Metrics.postEvent = sinon.stub();
486
- sinon.stub(Metrics, 'parseWebexApiError').returns(null);
493
+ it('should not send CA metric if meetingId is not provided', async () => {
487
494
  const message = 'a message';
488
495
  const meetingInfoData = 'meeting info';
489
496
 
490
497
  webex.request = sinon.stub().rejects({
491
498
  statusCode: 403,
492
- body: {message, code: 1000000, data: {meetingInfo: meetingInfoData}},
499
+ body: {message, code: 403102, data: {meetingInfo: meetingInfoData}},
493
500
  url: 'http://api-url.com',
494
501
  });
495
502
  try {
@@ -503,19 +510,12 @@ describe('plugin-meetings', () => {
503
510
  },
504
511
  null,
505
512
  null,
506
- {},
507
- {meetingId: 'meeting-id'}
513
+ undefined
508
514
  );
509
515
  assert.fail('fetchMeetingInfo should have thrown, but has not done that');
510
516
  } catch (err) {
511
- assert.calledWith(Metrics.postEvent, {
512
- event: 'client.meetinginfo.response',
513
- meetingId: 'meeting-id',
514
- data: {
515
- errors: undefined,
516
- meetingLookupUrl: 'http://api-url.com',
517
- }
518
- });
517
+ assert.notCalled(webex.internal.newMetrics.submitClientEvent);
518
+ assert.notCalled(webex.internal.newMetrics.submitInternalEvent);
519
519
  }
520
520
  });
521
521
 
@@ -71,7 +71,7 @@ describe('plugin-meetings', () => {
71
71
  describe('meetings index', () => {
72
72
  beforeEach(() => {
73
73
  MeetingsUtil.checkH264Support = sinon.stub();
74
- uuid1 = uuid.v4();
74
+ uuid1 = uuid.v4();
75
75
  url1 = `https://example.com/${uuid.v4()}`;
76
76
  uri1 = `test-${uuid.v4()}@example.com`;
77
77
  test1 = `test-${uuid.v4()}`;
@@ -834,6 +834,7 @@ describe('plugin-meetings', () => {
834
834
  webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
835
835
  webex.meetings.create = sinon.stub().returns(
836
836
  Promise.resolve({
837
+ id: 'meeting-id',
837
838
  locusInfo: {
838
839
  ...locusInfo,
839
840
  initialSetup,
@@ -915,6 +916,39 @@ describe('plugin-meetings', () => {
915
916
  },
916
917
  });
917
918
  });
919
+
920
+ it('sends client event correctly on finally', async () => {
921
+ webex.meetings.getMeetingByType = sinon.stub().returns(true);
922
+
923
+ await webex.meetings.handleLocusEvent({
924
+ locus: {
925
+ id: uuid1,
926
+ self: {
927
+ callBackInfo: {
928
+ callbackAddress: uri1,
929
+ },
930
+ },
931
+ info: {
932
+ webExMeetingId,
933
+ },
934
+ },
935
+ eventType: 'locus.difference',
936
+ locusUrl: url1,
937
+ });
938
+
939
+ await testUtils.flushPromises();
940
+
941
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
942
+ name: 'client.call.remote-started',
943
+ payload: {
944
+ trigger: 'mercury-event',
945
+ },
946
+ options: {
947
+ meetingId: 'meeting-id',
948
+ },
949
+ });
950
+ });
951
+
918
952
  it('should setup the meeting by a not difference event', async () => {
919
953
  await webex.meetings.handleLocusEvent({
920
954
  locus: {
@@ -2059,59 +2093,5 @@ describe('plugin-meetings', () => {
2059
2093
  assert.calledWith(webex.meetings.handleLocusEvent, {locus: breakoutLocus, locusUrl: breakoutLocus.url});
2060
2094
  });
2061
2095
  });
2062
-
2063
- describe('#getAnalyzerMetricsPrePayload', () => {
2064
- it('userType & userLogin & environment testing for CA data', async () => {
2065
- const FAKE_LOCUS_MEETING = {
2066
- conversationUrl: 'locusConvURL',
2067
- url: 'locusUrl',
2068
- info: {
2069
- webExMeetingId: 'locusMeetingId',
2070
- sipUri: 'locusSipUri',
2071
- owner: 'locusOwner',
2072
- },
2073
- meeting: {
2074
- startTime: "",
2075
- },
2076
- fullState: {
2077
- active: false,
2078
- },
2079
- };
2080
-
2081
- const meeting = await webex.meetings.createMeeting(
2082
- FAKE_LOCUS_MEETING,
2083
- 'test type',
2084
- true
2085
- );
2086
- meeting.roles = ['MODERATOR','COHOST','ATTENDEE'];
2087
- meeting.guest = true;
2088
- const options = {
2089
- event: 'event',
2090
- trackingId: 'trackingId',
2091
- locus: {},
2092
- mediaConnections: null,
2093
- errors: {}
2094
- };
2095
- webex.internal.services.get = sinon.stub();
2096
- webex.canAuthorize = true;
2097
- webex.credentials = {isUnverifiedGuest: true};
2098
- meeting.getAnalyzerMetricsPrePayload(options);
2099
- assert.equal(options.userType, 'host');
2100
- assert.equal(options.loginType, 'unverified-guest');
2101
- meeting.roles = ['COHOST','ATTENDEE'];
2102
- meeting.guest = false;
2103
- webex.canAuthorize = true;
2104
- webex.credentials = {isUnverifiedGuest: false};
2105
- meeting.getAnalyzerMetricsPrePayload(options);
2106
- assert.equal(options.userType, 'cohost');
2107
- assert.equal(options.loginType, 'login-ci');
2108
- meeting.roles = ['ATTENDEE'];
2109
- meeting.getAnalyzerMetricsPrePayload(options);
2110
- assert.equal(options.userType, 'attendee');
2111
- meeting.environment = "prod";
2112
- meeting.getAnalyzerMetricsPrePayload(options);
2113
- assert.equal(options.environment, 'prod');
2114
- });
2115
- });
2116
2096
  });
2117
2097
  });