@webex/plugin-meetings 2.37.1 → 2.38.0

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 (69) hide show
  1. package/dist/config.js +1 -1
  2. package/dist/config.js.map +1 -1
  3. package/dist/constants.js +2 -1
  4. package/dist/constants.js.map +1 -1
  5. package/dist/locus-info/index.js +24 -0
  6. package/dist/locus-info/index.js.map +1 -1
  7. package/dist/locus-info/parser.js +1 -0
  8. package/dist/locus-info/parser.js.map +1 -1
  9. package/dist/media/properties.js.map +1 -1
  10. package/dist/meeting/index.js +405 -352
  11. package/dist/meeting/index.js.map +1 -1
  12. package/dist/meeting/request.js +0 -27
  13. package/dist/meeting/request.js.map +1 -1
  14. package/dist/meeting/util.js +0 -56
  15. package/dist/meeting/util.js.map +1 -1
  16. package/dist/meeting-info/meeting-info-v2.js +2 -0
  17. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  18. package/dist/meetings/index.js +27 -17
  19. package/dist/meetings/index.js.map +1 -1
  20. package/dist/meetings/request.js +14 -12
  21. package/dist/meetings/request.js.map +1 -1
  22. package/dist/member/util.js +3 -1
  23. package/dist/member/util.js.map +1 -1
  24. package/dist/members/request.js +3 -1
  25. package/dist/members/request.js.map +1 -1
  26. package/dist/reachability/index.js +4 -4
  27. package/dist/reachability/index.js.map +1 -1
  28. package/dist/reactions/reactions.type.js +1 -0
  29. package/dist/reactions/reactions.type.js.map +1 -1
  30. package/dist/recording-controller/enums.js +17 -0
  31. package/dist/recording-controller/enums.js.map +1 -0
  32. package/dist/recording-controller/index.js +343 -0
  33. package/dist/recording-controller/index.js.map +1 -0
  34. package/dist/recording-controller/util.js +63 -0
  35. package/dist/recording-controller/util.js.map +1 -0
  36. package/dist/roap/turnDiscovery.js.map +1 -1
  37. package/dist/statsAnalyzer/mqaUtil.js +18 -6
  38. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  39. package/package.json +23 -18
  40. package/src/config.ts +1 -1
  41. package/src/constants.ts +1 -0
  42. package/src/locus-info/index.ts +24 -0
  43. package/src/locus-info/parser.ts +1 -0
  44. package/src/media/properties.ts +1 -1
  45. package/src/meeting/index.ts +121 -70
  46. package/src/meeting/request.ts +0 -31
  47. package/src/meeting/util.ts +0 -60
  48. package/src/meeting-info/meeting-info-v2.ts +2 -0
  49. package/src/meetings/index.ts +8 -3
  50. package/src/meetings/request.ts +1 -1
  51. package/src/member/util.ts +2 -1
  52. package/src/members/request.ts +1 -0
  53. package/src/reachability/index.ts +2 -1
  54. package/src/reactions/reactions.type.ts +2 -1
  55. package/src/recording-controller/enums.ts +8 -0
  56. package/src/recording-controller/index.ts +315 -0
  57. package/src/recording-controller/util.ts +58 -0
  58. package/src/roap/turnDiscovery.ts +1 -1
  59. package/src/statsAnalyzer/mqaUtil.ts +6 -0
  60. package/test/integration/spec/journey.js +1 -1
  61. package/test/integration/spec/space-meeting.js +1 -1
  62. package/test/integration/spec/transcription.js +1 -1
  63. package/test/unit/spec/meeting/index.js +33 -6
  64. package/test/unit/spec/meeting/utils.js +0 -127
  65. package/test/unit/spec/recording-controller/index.js +231 -0
  66. package/test/unit/spec/recording-controller/util.js +102 -0
  67. package/test/unit/spec/roap/index.ts +2 -1
  68. package/test/unit/spec/roap/turnDiscovery.ts +5 -4
  69. package/tsconfig.json +6 -0
@@ -0,0 +1,231 @@
1
+ import RecordingController from '@webex/plugin-meetings/src/recording-controller';
2
+ import sinon from 'sinon';
3
+ import {assert} from '@webex/test-helper-chai';
4
+ import { HTTP_VERBS } from '@webex/plugin-meetings/src/constants';
5
+
6
+ describe('plugin-meetings', () => {
7
+ describe('recording-controller tests', () => {
8
+ describe('index', () => {
9
+ let request;
10
+
11
+ describe('class tests', () => {
12
+ it('can set and extract new values later on', () => {
13
+ const controller = new RecordingController({});
14
+ assert.isUndefined(controller.getServiceUrl());
15
+ assert.isUndefined(controller.getSessionId());
16
+ assert.isUndefined(controller.getLocusUrl());
17
+ assert.isUndefined(controller.getLocusId());
18
+ controller.set({
19
+ serviceUrl: 'test',
20
+ sessionId: 'testId',
21
+ locusUrl: 'test/id',
22
+ displayHints: [],
23
+ })
24
+ assert(controller.getServiceUrl(), 'test');
25
+ assert(controller.getSessionId(), 'testId');
26
+ assert(controller.getLocusUrl(), 'test/id');
27
+ assert(controller.getLocusId(), 'id');
28
+ });
29
+ });
30
+
31
+
32
+ describe('legacy locus style recording', () => {
33
+ const locusUrl = 'locusUrl';
34
+ let controller;
35
+
36
+ beforeEach(() => {
37
+ request = {
38
+ request: sinon.stub().returns(Promise.resolve()),
39
+ };
40
+
41
+ controller = new RecordingController(request);
42
+
43
+ controller.set({
44
+ locusUrl,
45
+ displayHints: [],
46
+ })
47
+
48
+ });
49
+
50
+ describe('startRecording', () => {
51
+ it('rejects when correct display hint is not present', () => {
52
+ const result = controller.startRecording();
53
+
54
+ assert.notCalled(request.request);
55
+
56
+ assert.isRejected(result);
57
+ });
58
+
59
+ it('can start recording when the correct display hint is present', () => {
60
+ controller.setDisplayHints(['RECORDING_CONTROL_START']);
61
+
62
+ const result = controller.startRecording();
63
+
64
+ assert.calledWith(request.request, {uri: `${locusUrl}/controls`, body: {record: {recording: true, paused: false}}, method: HTTP_VERBS.PATCH});
65
+
66
+ assert.deepEqual(result, request.request.firstCall.returnValue);
67
+ });
68
+ });
69
+
70
+ describe('stopRecording', () => {
71
+ it('rejects when correct display hint is not present', () => {
72
+ const result = controller.stopRecording();
73
+
74
+ assert.notCalled(request.request);
75
+
76
+ assert.isRejected(result);
77
+ });
78
+
79
+ it('can stop recording when the correct display hint is present', () => {
80
+ controller.setDisplayHints(['RECORDING_CONTROL_STOP']);
81
+
82
+ const result = controller.stopRecording();
83
+
84
+ assert.calledWith(request.request, {uri: `${locusUrl}/controls`, body: {record: {recording: false, paused: false}}, method: HTTP_VERBS.PATCH});
85
+
86
+ assert.deepEqual(result, request.request.firstCall.returnValue);
87
+ });
88
+ });
89
+
90
+ describe('pauseRecording', () => {
91
+ it('rejects when correct display hint is not present', () => {
92
+ const result = controller.pauseRecording();
93
+
94
+ assert.notCalled(request.request);
95
+
96
+ assert.isRejected(result);
97
+ });
98
+
99
+ it('can pause recording when the correct display hint is present', () => {
100
+ controller.setDisplayHints(['RECORDING_CONTROL_PAUSE']);
101
+
102
+ const result = controller.pauseRecording();
103
+
104
+ assert.calledWith(request.request, {uri: `${locusUrl}/controls`, body: {record: {recording: true, paused: true}}, method: HTTP_VERBS.PATCH});
105
+
106
+ assert.deepEqual(result, request.request.firstCall.returnValue);
107
+ });
108
+ });
109
+
110
+ describe('resumeRecording', () => {
111
+ it('rejects when correct display hint is not present', () => {
112
+ const result = controller.pauseRecording();
113
+
114
+ assert.notCalled(request.request);
115
+
116
+ assert.isRejected(result);
117
+ });
118
+
119
+ it('can resume recording when the correct display hint is present', () => {
120
+ controller.setDisplayHints(['RECORDING_CONTROL_RESUME']);
121
+
122
+ const result = controller.resumeRecording();
123
+
124
+ assert.calledWith(request.request, {uri: `${locusUrl}/controls`, body: {record: {recording: true, paused: false}}, method: HTTP_VERBS.PATCH});
125
+
126
+ assert.deepEqual(result, request.request.firstCall.returnValue);
127
+ });
128
+ });
129
+ });
130
+
131
+ describe('recording streaming service style tests', () => {
132
+ let controller;
133
+
134
+ beforeEach(() => {
135
+ request = {
136
+ request: sinon.stub().returns(Promise.resolve()),
137
+ };
138
+
139
+ controller = new RecordingController(request);
140
+
141
+ controller.set({
142
+ serviceUrl: 'test',
143
+ sessionId: 'testId',
144
+ locusUrl: 'test/id',
145
+ displayHints: [],
146
+ })
147
+ });
148
+
149
+ describe('startRecording', () => {
150
+ it('rejects when correct display hint is not present', () => {
151
+ const result = controller.startRecording();
152
+
153
+ assert.notCalled(request.request);
154
+
155
+ assert.isRejected(result);
156
+ });
157
+
158
+ it('can start recording when the correct display hint is present', () => {
159
+ controller.setDisplayHints(['RECORDING_CONTROL_START']);
160
+
161
+ const result = controller.startRecording();
162
+
163
+ assert.calledWith(request.request, {uri: `test/loci/id/recording`, body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'start'}}, method: HTTP_VERBS.PUT});
164
+
165
+ assert.deepEqual(result, request.request.firstCall.returnValue);
166
+ });
167
+ });
168
+
169
+ describe('stopRecording', () => {
170
+ it('rejects when correct display hint is not present', () => {
171
+ const result = controller.pauseRecording();
172
+
173
+ assert.notCalled(request.request);
174
+
175
+ assert.isRejected(result);
176
+ });
177
+
178
+ it('can start recording when the correct display hint is present', () => {
179
+ controller.setDisplayHints(['RECORDING_CONTROL_STOP']);
180
+
181
+ const result = controller.stopRecording();
182
+
183
+ assert.calledWith(request.request, {uri: `test/loci/id/recording`, body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'stop'}}, method: HTTP_VERBS.PUT});
184
+
185
+ assert.deepEqual(result, request.request.firstCall.returnValue);
186
+ });
187
+ });
188
+
189
+ describe('pauseRecording', () => {
190
+ it('rejects when correct display hint is not present', () => {
191
+ const result = controller.pauseRecording();
192
+
193
+ assert.notCalled(request.request);
194
+
195
+ assert.isRejected(result);
196
+ });
197
+
198
+ it('can pause recording when the correct display hint is present', () => {
199
+ controller.setDisplayHints(['RECORDING_CONTROL_PAUSE']);
200
+
201
+ const result = controller.pauseRecording();
202
+
203
+ assert.calledWith(request.request, {uri: `test/loci/id/recording`, body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'pause'}}, method: HTTP_VERBS.PUT});
204
+
205
+ assert.deepEqual(result, request.request.firstCall.returnValue);
206
+ });
207
+ });
208
+
209
+ describe('resumeRecording', () => {
210
+ it('rejects when correct display hint is not present', () => {
211
+ const result = controller.resumeRecording();
212
+
213
+ assert.notCalled(request.request);
214
+
215
+ assert.isRejected(result);
216
+ });
217
+
218
+ it('can resume recording when the correct display hint is present', () => {
219
+ controller.setDisplayHints(['RECORDING_CONTROL_RESUME']);
220
+
221
+ const result = controller.resumeRecording();
222
+
223
+ assert.calledWith(request.request, {uri: `test/loci/id/recording`, body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'resume'}}, method: HTTP_VERBS.PUT});
224
+
225
+ assert.deepEqual(result, request.request.firstCall.returnValue);
226
+ });
227
+ });
228
+ });
229
+ });
230
+ });
231
+ });
@@ -0,0 +1,102 @@
1
+ import RecordingUtil from '@webex/plugin-meetings/src/recording-controller/util';
2
+ import RecordingAction from '@webex/plugin-meetings/src/recording-controller/enums';
3
+ import { assert } from 'chai';
4
+
5
+ describe('plugin-meetings', () => {
6
+ describe('recording-controller tests', () => {
7
+ describe('recording util tests', () => {
8
+
9
+ let locusInfo;
10
+
11
+ beforeEach(() => {
12
+ locusInfo = {
13
+ parsedLocus: {
14
+ info: {
15
+ userDisplayHints: [],
16
+ },
17
+ },
18
+ };
19
+ });
20
+
21
+ describe('canUserStart', () => {
22
+ it('can start recording when the correct display hint is present', () => {
23
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_START');
24
+
25
+ assert.equal(RecordingUtil.canUserStart(locusInfo.parsedLocus.info.userDisplayHints), true);
26
+ });
27
+
28
+ it('rejects when correct display hint is not present', () => {
29
+ assert.equal(RecordingUtil.canUserStart(locusInfo.parsedLocus.info.userDisplayHints), false);
30
+ });
31
+ });
32
+
33
+ describe('canUserPause', () => {
34
+ it('can pause recording when the correct display hint is present', () => {
35
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_PAUSE');
36
+
37
+ assert.equal(RecordingUtil.canUserPause(locusInfo.parsedLocus.info.userDisplayHints), true);
38
+ });
39
+
40
+ it('rejects when correct display hint is not present', () => {
41
+ assert.equal(RecordingUtil.canUserPause(locusInfo.parsedLocus.info.userDisplayHints), false);
42
+ });
43
+ });
44
+
45
+ describe('canUserStop', () => {
46
+ it('can stop recording when the correct display hint is present', () => {
47
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_STOP');
48
+
49
+ assert.equal(RecordingUtil.canUserStop(locusInfo.parsedLocus.info.userDisplayHints), true);
50
+ });
51
+
52
+ it('rejects when correct display hint is not present', () => {
53
+ assert.equal(RecordingUtil.canUserStop(locusInfo.parsedLocus.info.userDisplayHints), false);
54
+ });
55
+ });
56
+
57
+ describe('canUserResume', () => {
58
+ it('can start recording when the correct display hint is present', () => {
59
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_RESUME');
60
+
61
+ assert.equal(RecordingUtil.canUserResume(locusInfo.parsedLocus.info.userDisplayHints), true);
62
+ });
63
+
64
+ it('rejects when correct display hint is not present', () => {
65
+ assert.equal(RecordingUtil.canUserResume(locusInfo.parsedLocus.info.userDisplayHints), false);
66
+ });
67
+ });
68
+
69
+ describe('deriveRecordingStates', () => {
70
+ it('gets the correct values for a start recording action', () => {
71
+ assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Start), {recording: true, paused: false});
72
+ });
73
+
74
+ it('gets the correct values for a stop recording action', () => {
75
+ assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Stop), {recording: false, paused: false});
76
+ });
77
+
78
+ it('gets the correct values for a resume recording action', () => {
79
+ assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Resume), {recording: true, paused: false});
80
+ });
81
+
82
+ it('gets the correct values for a paused recording action', () => {
83
+ assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Pause), {recording: true, paused: true});
84
+ });
85
+ });
86
+
87
+ describe('extractLocusId', () => {
88
+ it('gets the correct id from the url param', () => {
89
+ assert.equal(RecordingUtil.extractLocusId('test/id'), 'id');
90
+ });
91
+
92
+ it('works with empty string parameters passed', () => {
93
+ assert.equal(RecordingUtil.extractLocusId(''), '');
94
+ });
95
+
96
+ it('works with no parameters passed', () => {
97
+ assert.isUndefined(RecordingUtil.extractLocusId(undefined));
98
+ });
99
+ });
100
+ });
101
+ });
102
+ });
@@ -6,12 +6,13 @@ import {ROAP} from '@webex/plugin-meetings/src/constants';
6
6
  import RoapRequest from '@webex/plugin-meetings/src/roap/request';
7
7
  import RoapHandler from '@webex/plugin-meetings/src/roap/handler';
8
8
  import Roap from '@webex/plugin-meetings/src/roap/';
9
+ import Meeting from '@webex/plugin-meetings/src/meeting';
9
10
 
10
11
  describe('Roap', () => {
11
12
  describe('doTurnDiscovery', () => {
12
13
  it('calls this.turnDiscovery.doTurnDiscovery() and forwards all the arguments', async () => {
13
14
  const RESULT = {something: 'some value'};
14
- const meeting = {id: 'some meeting id'};
15
+ const meeting = {id: 'some meeting id'} as Meeting;
15
16
 
16
17
  const doTurnDiscoveryStub = sinon
17
18
  .stub(TurnDiscovery.prototype, 'doTurnDiscovery')
@@ -104,7 +104,7 @@ describe('TurnDiscovery', () => {
104
104
 
105
105
  // check that TURN_DISCOVERY_REQUEST was sent
106
106
  await checkRoapMessageSent('TURN_DISCOVERY_REQUEST', 0);
107
-
107
+ // @ts-ignore
108
108
  mockRoapRequest.sendRoap.resetHistory();
109
109
 
110
110
  // simulate the response
@@ -141,6 +141,7 @@ describe('TurnDiscovery', () => {
141
141
  await checkRoapMessageSent('TURN_DISCOVERY_REQUEST', 0, '');
142
142
 
143
143
  // the main part of the test is complete now, checking the remaining part of the flow just for completeness
144
+ // @ts-ignore
144
145
  mockRoapRequest.sendRoap.resetHistory();
145
146
 
146
147
  // simulate the response
@@ -173,7 +174,7 @@ describe('TurnDiscovery', () => {
173
174
 
174
175
  // check that TURN_DISCOVERY_REQUEST was sent
175
176
  await checkRoapMessageSent('TURN_DISCOVERY_REQUEST', 0);
176
-
177
+ // @ts-ignore
177
178
  mockRoapRequest.sendRoap.resetHistory();
178
179
 
179
180
  // simulate the response with some extra headers
@@ -206,7 +207,7 @@ describe('TurnDiscovery', () => {
206
207
  const prevConfigValue = testMeeting.config.experimental.enableTurnDiscovery;
207
208
 
208
209
  testMeeting.config.experimental.enableTurnDiscovery = false;
209
-
210
+ // @ts-ignore
210
211
  const result = await new TurnDiscovery(mockRoapRequest).doTurnDiscovery(testMeeting);
211
212
 
212
213
  const {turnServerInfo, turnDiscoverySkippedReason} = result;
@@ -319,7 +320,7 @@ describe('TurnDiscovery', () => {
319
320
 
320
321
  // check that TURN_DISCOVERY_REQUEST was sent
321
322
  await checkRoapMessageSent('TURN_DISCOVERY_REQUEST', 0);
322
-
323
+ // @ts-ignore
323
324
  mockRoapRequest.sendRoap.resetHistory();
324
325
 
325
326
  // setup the mock so that sending of OK fails
package/tsconfig.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "../../../tsconfig.json",
3
+ "include": [
4
+ "src"
5
+ ],
6
+ }