@webex/plugin-meetings 3.3.1-next.31 → 3.3.1-next.32

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.
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
62
62
  updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
63
63
  this.set('canManageWebcast', canManageWebcast);
64
64
  },
65
- version: "3.3.1-next.31"
65
+ version: "3.3.1-next.32"
66
66
  });
67
67
  var _default = exports.default = Webinar;
68
68
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -43,13 +43,13 @@
43
43
  "@webex/eslint-config-legacy": "0.0.0",
44
44
  "@webex/jest-config-legacy": "0.0.0",
45
45
  "@webex/legacy-tools": "0.0.0",
46
- "@webex/plugin-meetings": "3.3.1-next.31",
47
- "@webex/plugin-rooms": "3.3.1-next.8",
48
- "@webex/test-helper-chai": "3.3.1-next.7",
49
- "@webex/test-helper-mocha": "3.3.1-next.7",
50
- "@webex/test-helper-mock-webex": "3.3.1-next.7",
51
- "@webex/test-helper-retry": "3.3.1-next.7",
52
- "@webex/test-helper-test-users": "3.3.1-next.7",
46
+ "@webex/plugin-meetings": "3.3.1-next.32",
47
+ "@webex/plugin-rooms": "3.3.1-next.9",
48
+ "@webex/test-helper-chai": "3.3.1-next.8",
49
+ "@webex/test-helper-mocha": "3.3.1-next.8",
50
+ "@webex/test-helper-mock-webex": "3.3.1-next.8",
51
+ "@webex/test-helper-retry": "3.3.1-next.8",
52
+ "@webex/test-helper-test-users": "3.3.1-next.8",
53
53
  "chai": "^4.3.4",
54
54
  "chai-as-promised": "^7.1.1",
55
55
  "eslint": "^8.24.0",
@@ -61,21 +61,21 @@
61
61
  "typescript": "^4.7.4"
62
62
  },
63
63
  "dependencies": {
64
- "@webex/common": "3.3.1-next.7",
64
+ "@webex/common": "3.3.1-next.8",
65
65
  "@webex/internal-media-core": "2.7.3",
66
- "@webex/internal-plugin-conversation": "3.3.1-next.8",
67
- "@webex/internal-plugin-device": "3.3.1-next.7",
68
- "@webex/internal-plugin-llm": "3.3.1-next.9",
69
- "@webex/internal-plugin-mercury": "3.3.1-next.8",
70
- "@webex/internal-plugin-metrics": "3.3.1-next.7",
71
- "@webex/internal-plugin-support": "3.3.1-next.8",
72
- "@webex/internal-plugin-user": "3.3.1-next.7",
73
- "@webex/internal-plugin-voicea": "3.3.1-next.31",
74
- "@webex/media-helpers": "3.3.1-next.12",
75
- "@webex/plugin-people": "3.3.1-next.8",
76
- "@webex/plugin-rooms": "3.3.1-next.8",
66
+ "@webex/internal-plugin-conversation": "3.3.1-next.9",
67
+ "@webex/internal-plugin-device": "3.3.1-next.8",
68
+ "@webex/internal-plugin-llm": "3.3.1-next.10",
69
+ "@webex/internal-plugin-mercury": "3.3.1-next.9",
70
+ "@webex/internal-plugin-metrics": "3.3.1-next.8",
71
+ "@webex/internal-plugin-support": "3.3.1-next.9",
72
+ "@webex/internal-plugin-user": "3.3.1-next.8",
73
+ "@webex/internal-plugin-voicea": "3.3.1-next.32",
74
+ "@webex/media-helpers": "3.3.1-next.13",
75
+ "@webex/plugin-people": "3.3.1-next.9",
76
+ "@webex/plugin-rooms": "3.3.1-next.9",
77
77
  "@webex/web-capabilities": "^1.4.0",
78
- "@webex/webex-core": "3.3.1-next.7",
78
+ "@webex/webex-core": "3.3.1-next.8",
79
79
  "ampersand-collection": "^2.0.2",
80
80
  "bowser": "^2.11.0",
81
81
  "btoa": "^1.2.1",
@@ -91,5 +91,5 @@
91
91
  "//": [
92
92
  "TODO: upgrade jwt-decode when moving to node 18"
93
93
  ],
94
- "version": "3.3.1-next.31"
94
+ "version": "3.3.1-next.32"
95
95
  }
@@ -9,6 +9,7 @@ import {
9
9
  ClientEvent,
10
10
  ClientEventLeaveReason,
11
11
  CallDiagnosticUtils,
12
+ CALL_DIAGNOSTIC_CONFIG,
12
13
  } from '@webex/internal-plugin-metrics';
13
14
  import {ClientEvent as RawClientEvent} from '@webex/event-dictionary-ts';
14
15
 
@@ -5779,7 +5780,24 @@ export default class Meeting extends StatelessWebexPlugin {
5779
5780
  {
5780
5781
  logText: `${LOG_HEADER} Roap Offer`,
5781
5782
  }
5782
- ).catch(() => {
5783
+ ).catch((error) => {
5784
+ // @ts-ignore
5785
+ this.webex.internal.newMetrics.submitClientEvent({
5786
+ name: 'client.media-engine.remote-sdp-received',
5787
+ payload: {
5788
+ canProceed: false,
5789
+ errors: [
5790
+ // @ts-ignore
5791
+ this.webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode(
5792
+ {
5793
+ clientErrorCode: CALL_DIAGNOSTIC_CONFIG.MISSING_ROAP_ANSWER_CLIENT_CODE,
5794
+ }
5795
+ ),
5796
+ ],
5797
+ },
5798
+ options: {meetingId: this.id, rawError: error},
5799
+ });
5800
+
5783
5801
  this.deferSDPAnswer.reject(new Error('failed to send ROAP SDP offer'));
5784
5802
  clearTimeout(this.sdpResponseTimer);
5785
5803
  this.sdpResponseTimer = undefined;
@@ -6458,6 +6476,21 @@ export default class Meeting extends StatelessWebexPlugin {
6458
6476
  ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT / 1000
6459
6477
  } seconds`
6460
6478
  );
6479
+ // @ts-ignore
6480
+ this.webex.internal.newMetrics.submitClientEvent({
6481
+ name: 'client.media-engine.remote-sdp-received',
6482
+ payload: {
6483
+ canProceed: false,
6484
+ errors: [
6485
+ // @ts-ignore
6486
+ this.webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode({
6487
+ clientErrorCode: CALL_DIAGNOSTIC_CONFIG.MISSING_ROAP_ANSWER_CLIENT_CODE,
6488
+ }),
6489
+ ],
6490
+ },
6491
+ options: {meetingId: this.id, rawError: new Error('Timeout waiting for SDP answer')},
6492
+ });
6493
+
6461
6494
  deferSDPAnswer.reject(new Error('Timed out waiting for REMOTE SDP ANSWER'));
6462
6495
  }, ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT);
6463
6496
 
@@ -33,6 +33,7 @@ import {
33
33
  ONLINE,
34
34
  OFFLINE,
35
35
  RECONNECTION,
36
+ ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT,
36
37
  } from '@webex/plugin-meetings/src/constants';
37
38
  import * as InternalMediaCoreModule from '@webex/internal-media-core';
38
39
  import {
@@ -1765,13 +1766,12 @@ describe('plugin-meetings', () => {
1765
1766
  meeting.audio = muteStateStub;
1766
1767
  meeting.video = muteStateStub;
1767
1768
  sinon.stub(Media, 'createMediaConnection').returns(fakeMediaConnection);
1768
- meeting.setMercuryListener = sinon.stub().returns(true);
1769
- meeting.setupMediaConnectionListeners = sinon.stub();
1770
- meeting.setMercuryListener = sinon.stub();
1771
- meeting.roap.doTurnDiscovery = sinon
1772
- .stub()
1769
+ sinon.stub(meeting, 'setupMediaConnectionListeners');
1770
+ sinon.stub(meeting, 'setMercuryListener');
1771
+ sinon
1772
+ .stub(meeting.roap, 'doTurnDiscovery')
1773
1773
  .resolves({turnServerInfo: {}, turnDiscoverySkippedReason: undefined});
1774
- meeting.waitForRemoteSDPAnswer = sinon.stub().resolves();
1774
+ sinon.stub(meeting, 'waitForRemoteSDPAnswer').resolves();
1775
1775
 
1776
1776
  // normally the first Roap message we send is creating confluence, so mock LocusMediaRequest.isConfluenceCreated()
1777
1777
  // to return false the first time it's called and true the 2nd time, to simulate how it would happen for real
@@ -2125,6 +2125,61 @@ describe('plugin-meetings', () => {
2125
2125
  }
2126
2126
  });
2127
2127
 
2128
+ it('sends correct CA event when times out waiting for SDP answer', async () => {
2129
+ const eventListeners = {};
2130
+ const clock = sinon.useFakeTimers();
2131
+
2132
+ // these 2 are stubbed, we need the real versions:
2133
+ meeting.waitForRemoteSDPAnswer.restore();
2134
+ meeting.setupMediaConnectionListeners.restore();
2135
+
2136
+ meeting.meetingState = 'ACTIVE';
2137
+
2138
+ // setup a mock media connection that will trigger an offer when initiateOffer() is called
2139
+ Media.createMediaConnection = sinon.stub().returns({
2140
+ initiateOffer: sinon.stub().callsFake(() => {
2141
+ // simulate offer being generated
2142
+ eventListeners[Event.LOCAL_SDP_OFFER_GENERATED]();
2143
+
2144
+ return Promise.resolve();
2145
+ }),
2146
+ close: sinon.stub(),
2147
+ on: (event, listener) => {
2148
+ eventListeners[event] = listener;
2149
+ },
2150
+ forceRtcMetricsSend: sinon.stub().resolves(),
2151
+ });
2152
+
2153
+ const getErrorPayloadForClientErrorCodeStub =
2154
+ (webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode =
2155
+ sinon
2156
+ .stub()
2157
+ .callsFake(({clientErrorCode}) => ({errorCode: clientErrorCode, fatal: true})));
2158
+
2159
+ const result = meeting.addMedia();
2160
+ await testUtils.flushPromises();
2161
+
2162
+ // simulate timeout waiting for the SDP answer that never comes
2163
+ await clock.tickAsync(ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT);
2164
+
2165
+ await assert.isRejected(result);
2166
+
2167
+ assert.calledOnceWithExactly(getErrorPayloadForClientErrorCodeStub, {
2168
+ clientErrorCode: 2007,
2169
+ });
2170
+ assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
2171
+ name: 'client.media-engine.remote-sdp-received',
2172
+ payload: {
2173
+ canProceed: false,
2174
+ errors: [{errorCode: 2007, fatal: true}],
2175
+ },
2176
+ options: {
2177
+ meetingId: meeting.id,
2178
+ rawError: sinon.match.instanceOf(Error),
2179
+ },
2180
+ });
2181
+ });
2182
+
2128
2183
  it('if an error occurs after media request has already been sent, and the user waits until the server kicks them out, a UserNotJoinedError should be thrown when attempting to addMedia again', async () => {
2129
2184
  meeting.meetingState = 'ACTIVE';
2130
2185
  // setup the mock to cause addMedia() to fail
@@ -3200,7 +3255,7 @@ describe('plugin-meetings', () => {
3200
3255
  clientErrorCode: MISSING_ROAP_ANSWER_CLIENT_CODE,
3201
3256
  expectedErrorPayload: {
3202
3257
  errorDescription: ERROR_DESCRIPTIONS.MISSING_ROAP_ANSWER,
3203
- category: 'signaling',
3258
+ category: 'media',
3204
3259
  },
3205
3260
  },
3206
3261
  {
@@ -7890,12 +7945,18 @@ describe('plugin-meetings', () => {
7890
7945
  });
7891
7946
 
7892
7947
  it('handles OFFER message correctly when request fails', async () => {
7948
+ const fakeError = new Error('fake error');
7893
7949
  const clock = sinon.useFakeTimers();
7894
7950
  sinon.spy(clock, 'clearTimeout');
7895
7951
  meeting.deferSDPAnswer = {reject: sinon.stub()};
7896
7952
  meeting.sdpResponseTimer = '1234';
7897
- sendRoapMediaRequestStub.rejects();
7953
+ sendRoapMediaRequestStub.rejects(fakeError);
7898
7954
  sinon.stub(meeting, 'roapMessageReceived');
7955
+ const getErrorPayloadForClientErrorCodeStub =
7956
+ (webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode =
7957
+ sinon
7958
+ .stub()
7959
+ .callsFake(({clientErrorCode}) => ({errorCode: clientErrorCode, fatal: true})));
7899
7960
 
7900
7961
  eventListeners[Event.ROAP_MESSAGE_TO_SEND]({
7901
7962
  roapMessage: {
@@ -7920,6 +7981,21 @@ describe('plugin-meetings', () => {
7920
7981
  assert.calledOnce(clock.clearTimeout);
7921
7982
  assert.calledWith(clock.clearTimeout, '1234');
7922
7983
  assert.equal(meeting.sdpResponseTimer, undefined);
7984
+
7985
+ assert.calledOnceWithExactly(getErrorPayloadForClientErrorCodeStub, {
7986
+ clientErrorCode: 2007,
7987
+ });
7988
+ assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
7989
+ name: 'client.media-engine.remote-sdp-received',
7990
+ payload: {
7991
+ canProceed: false,
7992
+ errors: [{errorCode: 2007, fatal: true}],
7993
+ },
7994
+ options: {
7995
+ meetingId: meeting.id,
7996
+ rawError: fakeError,
7997
+ },
7998
+ });
7923
7999
  });
7924
8000
 
7925
8001
  it('handles ANSWER message correctly', () => {