@webex/plugin-meetings 3.11.0-next.36 → 3.11.0-next.38

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.
@@ -26,6 +26,7 @@ describe('plugin-meetings', () => {
26
26
  canLowerAllHands: null,
27
27
  canLowerSomeoneElsesHand: null,
28
28
  bothLeaveAndEndMeetingAvailable: null,
29
+ requireHostEndMeetingBeforeLeave: null,
29
30
  canEnableClosedCaption: null,
30
31
  canStartTranscribing: null,
31
32
  canStopTranscribing: null,
@@ -112,6 +113,7 @@ describe('plugin-meetings', () => {
112
113
  canEnablePollingQA: null,
113
114
  canDisablePollingQA: null,
114
115
  canAttendeeRequestAiAssistantEnabled: null,
116
+ isAttendeeRequestAiAssistantDeclinedAll: null,
115
117
 
116
118
  ...expected,
117
119
  };
@@ -150,6 +152,7 @@ describe('plugin-meetings', () => {
150
152
  'canLowerAllHands',
151
153
  'canLowerSomeoneElsesHand',
152
154
  'bothLeaveAndEndMeetingAvailable',
155
+ 'requireHostEndMeetingBeforeLeave',
153
156
  'canEnableClosedCaption',
154
157
  'canStopTranscribing',
155
158
  'isClosedCaptionActive',
@@ -230,6 +233,7 @@ describe('plugin-meetings', () => {
230
233
  'canEnablePollingQA',
231
234
  'canDisablePollingQA',
232
235
  'canAttendeeRequestAiAssistantEnabled',
236
+ 'isAttendeeRequestAiAssistantDeclinedAll',
233
237
  ].forEach((key) => {
234
238
  it(`get and set for ${key} work as expected`, () => {
235
239
  const inMeetingActions = new InMeetingActions();
@@ -265,7 +265,7 @@ describe('plugin-meetings', () => {
265
265
  stopReachability: sinon.stub(),
266
266
  isSubnetReachable: sinon.stub().returns(true),
267
267
  };
268
- webex.internal.llm.isDataChannelTokenEnabled = sinon.stub().resolves(false)
268
+ webex.internal.llm.isDataChannelTokenEnabled = sinon.stub().resolves(false);
269
269
  webex.internal.llm.on = sinon.stub();
270
270
  webex.internal.newMetrics.callDiagnosticLatencies = new CallDiagnosticLatencies(
271
271
  {},
@@ -11887,6 +11887,7 @@ describe('plugin-meetings', () => {
11887
11887
  let canUnsetDisallowUnmuteSpy;
11888
11888
  let canUserRaiseHandSpy;
11889
11889
  let bothLeaveAndEndMeetingAvailableSpy;
11890
+ let requireHostEndMeetingBeforeLeaveSpy;
11890
11891
  let canUserLowerAllHandsSpy;
11891
11892
  let canUserLowerSomeoneElsesHandSpy;
11892
11893
  let waitingForOthersToJoinSpy;
@@ -11899,6 +11900,7 @@ describe('plugin-meetings', () => {
11899
11900
  let isSpokenLanguageAutoDetectionEnabledSpy;
11900
11901
  let showAutoEndMeetingWarningSpy;
11901
11902
  let canAttendeeRequestAiAssistantEnabledSpy;
11903
+ let attendeeRequestAiAssistantDeclinedAllSpy;
11902
11904
  // Due to import tree issues, hasHints must be stubed within the scope of the `it`.
11903
11905
 
11904
11906
  beforeEach(() => {
@@ -11919,6 +11921,10 @@ describe('plugin-meetings', () => {
11919
11921
  MeetingUtil,
11920
11922
  'bothLeaveAndEndMeetingAvailable'
11921
11923
  );
11924
+ requireHostEndMeetingBeforeLeaveSpy = sinon.spy(
11925
+ MeetingUtil,
11926
+ 'requireHostEndMeetingBeforeLeave'
11927
+ );
11922
11928
  canUserLowerSomeoneElsesHandSpy = sinon.spy(MeetingUtil, 'canUserLowerSomeoneElsesHand');
11923
11929
  waitingForOthersToJoinSpy = sinon.spy(MeetingUtil, 'waitingForOthersToJoin');
11924
11930
  canSendReactionsSpy = sinon.spy(MeetingUtil, 'canSendReactions');
@@ -11939,6 +11945,10 @@ describe('plugin-meetings', () => {
11939
11945
  MeetingUtil,
11940
11946
  'canAttendeeRequestAiAssistantEnabled'
11941
11947
  );
11948
+ attendeeRequestAiAssistantDeclinedAllSpy = sinon.spy(
11949
+ MeetingUtil,
11950
+ 'attendeeRequestAiAssistantDeclinedAll'
11951
+ );
11942
11952
  });
11943
11953
 
11944
11954
  afterEach(() => {
@@ -11946,6 +11956,7 @@ describe('plugin-meetings', () => {
11946
11956
  waitingForOthersToJoinSpy.restore();
11947
11957
  showAutoEndMeetingWarningSpy.restore();
11948
11958
  canAttendeeRequestAiAssistantEnabledSpy.restore();
11959
+ attendeeRequestAiAssistantDeclinedAllSpy.restore();
11949
11960
  });
11950
11961
 
11951
11962
  forEach(
@@ -12485,6 +12496,7 @@ describe('plugin-meetings', () => {
12485
12496
  assert.calledWith(canUnsetDisallowUnmuteSpy, userDisplayHints);
12486
12497
  assert.calledWith(canUserRaiseHandSpy, userDisplayHints);
12487
12498
  assert.calledWith(bothLeaveAndEndMeetingAvailableSpy, userDisplayHints);
12499
+ assert.calledWith(requireHostEndMeetingBeforeLeaveSpy, userDisplayHints);
12488
12500
  assert.calledWith(canUserLowerAllHandsSpy, userDisplayHints);
12489
12501
  assert.calledWith(canUserLowerSomeoneElsesHandSpy, userDisplayHints);
12490
12502
  assert.calledWith(waitingForOthersToJoinSpy, userDisplayHints);
@@ -12501,6 +12513,7 @@ describe('plugin-meetings', () => {
12501
12513
  userDisplayHints,
12502
12514
  meeting.roles
12503
12515
  );
12516
+ assert.calledWith(attendeeRequestAiAssistantDeclinedAllSpy, userDisplayHints);
12504
12517
 
12505
12518
  assert.calledWith(ControlsOptionsUtil.hasHints, {
12506
12519
  requiredHints: [DISPLAY_HINTS.MUTE_ALL],
@@ -12709,7 +12722,7 @@ describe('plugin-meetings', () => {
12709
12722
  meeting.joinedWith = {state: 'JOINED'};
12710
12723
  meeting.locusInfo = {
12711
12724
  url: 'a url',
12712
- info: {datachannelUrl: 'a datachannel url'}
12725
+ info: {datachannelUrl: 'a datachannel url'},
12713
12726
  };
12714
12727
 
12715
12728
  const result = await meeting.updateLLMConnection();
@@ -12757,7 +12770,7 @@ describe('plugin-meetings', () => {
12757
12770
  );
12758
12771
  assert.equal(result, 'something');
12759
12772
  });
12760
- it('disconnects if the locus url has changed', async () => {
12773
+ it('disconnects if the locus url has changed', async () => {
12761
12774
  meeting.joinedWith = {state: 'JOINED'};
12762
12775
 
12763
12776
  webex.internal.llm.isConnected.returns(true);
@@ -12766,15 +12779,15 @@ describe('plugin-meetings', () => {
12766
12779
  meeting.locusInfo = {
12767
12780
  url: 'a different url',
12768
12781
  info: {datachannelUrl: 'a datachannel url'},
12769
- self: {}
12782
+ self: {},
12770
12783
  };
12771
12784
 
12772
12785
  const result = await meeting.updateLLMConnection();
12773
12786
 
12774
- assert.calledWithExactly(
12775
- webex.internal.llm.disconnectLLM,
12776
- {code: 3050, reason: 'done (permanent)'}
12777
- );
12787
+ assert.calledWithExactly(webex.internal.llm.disconnectLLM, {
12788
+ code: 3050,
12789
+ reason: 'done (permanent)',
12790
+ });
12778
12791
 
12779
12792
  assert.calledWithExactly(
12780
12793
  webex.internal.llm.registerAndConnect,
@@ -12816,15 +12829,15 @@ describe('plugin-meetings', () => {
12816
12829
  meeting.locusInfo = {
12817
12830
  url: 'a url',
12818
12831
  info: {datachannelUrl: 'a different datachannel url'},
12819
- self: {}
12832
+ self: {},
12820
12833
  };
12821
12834
 
12822
12835
  const result = await meeting.updateLLMConnection();
12823
12836
 
12824
- assert.calledWithExactly(
12825
- webex.internal.llm.disconnectLLM,
12826
- {code: 3050, reason: 'done (permanent)'}
12827
- );
12837
+ assert.calledWithExactly(webex.internal.llm.disconnectLLM, {
12838
+ code: 3050,
12839
+ reason: 'done (permanent)',
12840
+ });
12828
12841
 
12829
12842
  assert.calledWithExactly(
12830
12843
  webex.internal.llm.registerAndConnect,
@@ -12911,11 +12924,7 @@ describe('plugin-meetings', () => {
12911
12924
  'a datachannel url',
12912
12925
  'token-123'
12913
12926
  );
12914
- assert.calledWithExactly(
12915
- webex.internal.llm.setDatachannelToken,
12916
- 'token-123',
12917
- 'default'
12918
- );
12927
+ assert.calledWithExactly(webex.internal.llm.setDatachannelToken, 'token-123', 'default');
12919
12928
  });
12920
12929
  it('prefers refreshed token over locus self token', async () => {
12921
12930
  meeting.joinedWith = {state: 'JOINED'};
@@ -12925,9 +12934,7 @@ describe('plugin-meetings', () => {
12925
12934
  self: {datachannelToken: 'locus-token'},
12926
12935
  };
12927
12936
 
12928
- webex.internal.llm.getDatachannelToken
12929
- .withArgs('default')
12930
- .returns('refreshed-token');
12937
+ webex.internal.llm.getDatachannelToken.withArgs('default').returns('refreshed-token');
12931
12938
 
12932
12939
  await meeting.updateLLMConnection();
12933
12940
 
@@ -12958,8 +12965,10 @@ describe('plugin-meetings', () => {
12958
12965
  meeting.webinar.isJoinPracticeSessionDataChannel.returns(true);
12959
12966
 
12960
12967
  webex.internal.llm.getDatachannelToken
12961
- .withArgs(true).returns('refreshed-ps-token') // refreshed practice token
12962
- .withArgs(false).returns('refreshed-normal-token'); // refreshed normal token
12968
+ .withArgs(true)
12969
+ .returns('refreshed-ps-token') // refreshed practice token
12970
+ .withArgs(false)
12971
+ .returns('refreshed-normal-token'); // refreshed normal token
12963
12972
 
12964
12973
  await meeting.updateLLMConnection();
12965
12974
 
@@ -12981,7 +12990,7 @@ describe('plugin-meetings', () => {
12981
12990
  meeting.locusInfo = {
12982
12991
  url: 'a url',
12983
12992
  info: {datachannelUrl: 'a datachannel url'},
12984
- self: {datachannelToken: 'token-123'}
12993
+ self: {datachannelToken: 'token-123'},
12985
12994
  };
12986
12995
 
12987
12996
  webex.internal.llm.getDatachannelToken.returns(undefined);
@@ -12995,11 +13004,7 @@ describe('plugin-meetings', () => {
12995
13004
  'a datachannel url',
12996
13005
  'token-123'
12997
13006
  );
12998
- assert.calledWithExactly(
12999
- webex.internal.llm.setDatachannelToken,
13000
- 'token-123',
13001
- 'default'
13002
- );
13007
+ assert.calledWithExactly(webex.internal.llm.setDatachannelToken, 'token-123', 'default');
13003
13008
  });
13004
13009
  });
13005
13010
 
@@ -14577,7 +14582,7 @@ describe('plugin-meetings', () => {
14577
14582
  meeting.locusUrl = 'https://locus.example.com';
14578
14583
  meeting.meetingRequest = {
14579
14584
  fetchDatachannelToken: sinon.stub().resolves({
14580
- body: { datachannelToken: 'mock-token' },
14585
+ body: {datachannelToken: 'mock-token'},
14581
14586
  }),
14582
14587
  };
14583
14588
  meeting.members = {
@@ -14593,14 +14598,11 @@ describe('plugin-meetings', () => {
14593
14598
 
14594
14599
  sinon.assert.calledOnce(meeting.meetingRequest.fetchDatachannelToken);
14595
14600
 
14596
- sinon.assert.calledWith(
14597
- meeting.meetingRequest.fetchDatachannelToken,
14598
- {
14599
- locusUrl: 'https://locus.example.com',
14600
- requestingParticipantId: 'self-123',
14601
- isPracticeSession: true,
14602
- }
14603
- );
14601
+ sinon.assert.calledWith(meeting.meetingRequest.fetchDatachannelToken, {
14602
+ locusUrl: 'https://locus.example.com',
14603
+ requestingParticipantId: 'self-123',
14604
+ isPracticeSession: true,
14605
+ });
14604
14606
  });
14605
14607
 
14606
14608
  it('returns the correct structured result', async () => {
@@ -1011,6 +1011,30 @@ describe('plugin-meetings', () => {
1011
1011
  });
1012
1012
  });
1013
1013
 
1014
+ describe('attendeeRequestAiAssistantDeclinedAll', () => {
1015
+ it('returns true when display hint is present', () => {
1016
+ assert.isTrue(
1017
+ MeetingUtil.attendeeRequestAiAssistantDeclinedAll([
1018
+ 'ATTENDEE_REQUEST_AI_ASSISTANT_DECLINED_ALL',
1019
+ ])
1020
+ );
1021
+ });
1022
+
1023
+ it('returns false when display hint is not present', () => {
1024
+ assert.isFalse(MeetingUtil.attendeeRequestAiAssistantDeclinedAll([]));
1025
+ });
1026
+
1027
+ it('returns false when display hint is absent among other hints', () => {
1028
+ assert.isFalse(
1029
+ MeetingUtil.attendeeRequestAiAssistantDeclinedAll(['SOME_OTHER_HINT', 'ANOTHER_HINT'])
1030
+ );
1031
+ });
1032
+
1033
+ it('returns false when called with no arguments', () => {
1034
+ assert.isFalse(MeetingUtil.attendeeRequestAiAssistantDeclinedAll());
1035
+ });
1036
+ });
1037
+
1014
1038
  describe('bothLeaveAndEndMeetingAvailable', () => {
1015
1039
  it('works as expected', () => {
1016
1040
  assert.deepEqual(
@@ -1029,6 +1053,46 @@ describe('plugin-meetings', () => {
1029
1053
  });
1030
1054
  });
1031
1055
 
1056
+ describe('requireHostEndMeetingBeforeLeave', () => {
1057
+ it('works as expected', () => {
1058
+ assert.deepEqual(
1059
+ MeetingUtil.requireHostEndMeetingBeforeLeave(['REQUIRE_HOST_END_MEETING_BEFORE_LEAVE']),
1060
+ true
1061
+ );
1062
+ assert.deepEqual(
1063
+ MeetingUtil.requireHostEndMeetingBeforeLeave([
1064
+ 'LEAVE_TRANSFER_HOST_END_MEETING',
1065
+ 'END_MEETING',
1066
+ ]),
1067
+ false
1068
+ );
1069
+ assert.deepEqual(
1070
+ MeetingUtil.requireHostEndMeetingBeforeLeave([
1071
+ 'REQUIRE_HOST_END_MEETING_BEFORE_LEAVE',
1072
+ 'END_MEETING',
1073
+ ]),
1074
+ true
1075
+ );
1076
+ assert.deepEqual(
1077
+ MeetingUtil.requireHostEndMeetingBeforeLeave([
1078
+ 'REQUIRE_HOST_END_MEETING_BEFORE_LEAVE',
1079
+ 'LEAVE_MEETING',
1080
+ ]),
1081
+ true
1082
+ );
1083
+ assert.deepEqual(
1084
+ MeetingUtil.requireHostEndMeetingBeforeLeave([
1085
+ 'REQUIRE_HOST_END_MEETING_BEFORE_LEAVE',
1086
+ 'LEAVE_MEETING',
1087
+ 'END_MEETING',
1088
+ ]),
1089
+ true
1090
+ );
1091
+ assert.deepEqual(MeetingUtil.requireHostEndMeetingBeforeLeave(['END_MEETING']), true);
1092
+ assert.deepEqual(MeetingUtil.requireHostEndMeetingBeforeLeave([]), false);
1093
+ });
1094
+ });
1095
+
1032
1096
  describe('canUserLock', () => {
1033
1097
  it('works as expected', () => {
1034
1098
  assert.deepEqual(