@webex/internal-plugin-voicea 3.0.0-beta.4 → 3.0.0-beta.400

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.
@@ -1,6 +1,7 @@
1
+ import 'jsdom-global/register';
1
2
  import MockWebex from '@webex/test-helper-mock-webex';
2
3
  import MockWebSocket from '@webex/test-helper-mock-web-socket';
3
- import {assert} from '@webex/test-helper-chai';
4
+ import {assert, expect} from '@webex/test-helper-chai';
4
5
  import sinon from 'sinon';
5
6
  import Mercury from '@webex/internal-plugin-mercury';
6
7
  import LLMChannel from '@webex/internal-plugin-llm';
@@ -41,17 +42,26 @@ describe('plugin-voicea', () => {
41
42
  });
42
43
  });
43
44
 
45
+ describe("#constructor", () => {
46
+ it('should init status', () => {
47
+ assert.equal(voiceaService.announceStatus, 'idle');
48
+ assert.equal(voiceaService.captionStatus, 'idle');
49
+ });
50
+ });
51
+
44
52
  describe('#sendAnnouncement', () => {
45
53
  beforeEach(async () => {
46
54
  const mockWebSocket = new MockWebSocket();
47
55
 
48
56
  voiceaService.webex.internal.llm.socket = mockWebSocket;
57
+ voiceaService.announceStatus = "idle";
49
58
  });
50
59
 
51
60
  it("sends announcement if voicea hasn't joined", () => {
52
61
  const spy = sinon.spy(voiceaService, 'listenToEvents');
53
62
 
54
63
  voiceaService.sendAnnouncement();
64
+ assert.equal(voiceaService.announceStatus, 'joining');
55
65
  assert.calledOnce(spy);
56
66
 
57
67
  assert.calledOnceWithExactly(voiceaService.webex.internal.llm.socket.send, {
@@ -98,16 +108,14 @@ describe('plugin-voicea', () => {
98
108
  data: {relayType: 'voicea.annc', voiceaPayload: {}},
99
109
  });
100
110
 
101
- assert.equal(voiceaService.hasVoiceaJoined, true);
102
111
  assert.equal(voiceaService.areCaptionsEnabled, true);
103
- assert.equal(voiceaService.isTranscribingEnabled, true);
104
112
  assert.equal(voiceaService.vmcDeviceId, 'ws');
105
113
 
106
114
  voiceaService.deregisterEvents();
107
- assert.equal(voiceaService.hasVoiceaJoined, false);
108
115
  assert.equal(voiceaService.areCaptionsEnabled, false);
109
- assert.equal(voiceaService.isTranscribingEnabled, false);
110
116
  assert.equal(voiceaService.vmcDeviceId, undefined);
117
+ assert.equal(voiceaService.announceStatus, 'idle');
118
+ assert.equal(voiceaService.captionStatus, 'idle');
111
119
  });
112
120
  });
113
121
  describe('#processAnnouncementMessage', () => {
@@ -194,28 +202,38 @@ describe('plugin-voicea', () => {
194
202
  sinon.match({
195
203
  method: 'PUT',
196
204
  url: `${locusUrl}/controls/`,
197
- body: {languageCode},
205
+ body: {
206
+ transcribe: {
207
+ spokenLanguage: languageCode
208
+ }
209
+ },
198
210
  })
199
211
  );
200
212
  });
201
213
  });
202
214
 
203
- describe('#turnOnCaptions', () => {
215
+ describe('#requestTurnOnCaptions', () => {
204
216
  beforeEach(async () => {
205
217
  const mockWebSocket = new MockWebSocket();
206
218
 
207
219
  voiceaService.webex.internal.llm.socket = mockWebSocket;
220
+ voiceaService.captionStatus = 'idle';
208
221
  });
209
222
 
223
+ afterEach( () => {
224
+ voiceaService.captionStatus = 'idle';
225
+ })
226
+
210
227
  it('turns on captions', async () => {
211
- const announcementSpy = sinon.spy(voiceaService, 'sendAnnouncement');
228
+ const announcementSpy = sinon.spy(voiceaService, 'announce');
212
229
 
213
230
  const triggerSpy = sinon.spy();
214
231
 
215
232
  voiceaService.on(EVENT_TRIGGERS.CAPTIONS_TURNED_ON, triggerSpy);
216
233
  voiceaService.listenToEvents();
217
234
 
218
- await voiceaService.turnOnCaptions();
235
+ await voiceaService.requestTurnOnCaptions();
236
+ assert.equal(voiceaService.captionStatus, 'enabled');
219
237
  sinon.assert.calledWith(
220
238
  voiceaService.request,
221
239
  sinon.match({
@@ -230,18 +248,119 @@ describe('plugin-voicea', () => {
230
248
  assert.calledOnce(announcementSpy);
231
249
  });
232
250
 
233
- it("doesn't call API on captions", async () => {
234
- await voiceaService.turnOnCaptions();
251
+ it("should handle request fail", async () => {
252
+ voiceaService.captionStatus = 'sending';
253
+ voiceaService.request = sinon.stub().rejects();
254
+
255
+ try {
256
+ await voiceaService.requestTurnOnCaptions();
257
+ } catch (error) {
258
+ expect(error.message).to.include('turn on captions fail');
259
+ return;
260
+ }
261
+ assert.equal(voiceaService.captionStatus, 'idle');
262
+ });
263
+ });
235
264
 
236
- // eslint-disable-next-line no-underscore-dangle
237
- voiceaService.webex.internal.llm._emit('event:relay.event', {
238
- headers: {from: 'ws'},
239
- data: {relayType: 'voicea.annc', voiceaPayload: {}},
265
+ describe("#isAnnounceProcessing", () => {
266
+ afterEach(() => {
267
+ voiceaService.announceStatus = 'idle';
268
+ });
269
+
270
+ ['joining', 'joined'].forEach((status) => {
271
+ it(`should return true when status is ${status}`, () => {
272
+ voiceaService.announceStatus = status;
273
+ assert.equal(voiceaService.isAnnounceProcessing(), true);
240
274
  });
275
+ });
276
+
277
+ it('should return false when status is not processing status', () => {
278
+ voiceaService.announceStatus = 'idle';
279
+ assert.equal(voiceaService.isAnnounceProcessing(), false);
280
+ });
281
+ });
282
+
283
+ describe("#announce", () => {
284
+ let isAnnounceProcessing, sendAnnouncement;
285
+ beforeEach(() => {
286
+ voiceaService.webex.internal.llm.isConnected.returns(true);
287
+ sendAnnouncement = sinon.stub(voiceaService, 'sendAnnouncement');
288
+ isAnnounceProcessing = sinon.stub(voiceaService, 'isAnnounceProcessing').returns(false)
289
+ });
290
+
291
+ afterEach(() => {
292
+ voiceaService.webex.internal.llm.isConnected.returns(true);
293
+ isAnnounceProcessing.restore();
294
+ sendAnnouncement.restore();
295
+ });
296
+
297
+ it('announce to llm data channel', ()=> {
298
+ voiceaService.announce();
299
+ assert.calledOnce(sendAnnouncement);
300
+ });
301
+
302
+ it('announce to llm data channel before llm connected', ()=> {
303
+ voiceaService.webex.internal.llm.isConnected.returns(false);
304
+ assert.throws(() => voiceaService.announce(), "voicea can not announce before llm connected");
305
+ assert.notCalled(sendAnnouncement);
306
+ });
307
+
308
+ it('should not announce duplicate', () => {
309
+ isAnnounceProcessing.returns(true);
310
+ voiceaService.announce();
311
+ assert.notCalled(sendAnnouncement);
312
+ })
313
+ });
314
+
315
+ describe("#isCaptionProcessing", () => {
316
+ afterEach(() => {
317
+ voiceaService.captionStatus = 'idle';
318
+ });
319
+
320
+ ['sending', 'enabled'].forEach((status) => {
321
+ it(`should return true when status is ${status}`, () => {
322
+ voiceaService.captionStatus = status;
323
+ assert.equal(voiceaService.isCaptionProcessing(), true);
324
+ });
325
+ });
241
326
 
242
- const response = await voiceaService.turnOnCaptions();
327
+ it('should return false when status is not processing status', () => {
328
+ voiceaService.captionStatus = 'idle';
329
+ assert.equal(voiceaService.isCaptionProcessing(), false);
330
+ });
331
+ });
332
+
333
+ describe('#turnOnCaptions', () => {
334
+ let requestTurnOnCaptions, isCaptionProcessing;
335
+ beforeEach(() => {
336
+ requestTurnOnCaptions = sinon.stub(voiceaService, 'requestTurnOnCaptions');
337
+ isCaptionProcessing = sinon.stub(voiceaService, 'isCaptionProcessing').returns(false);
338
+ voiceaService.webex.internal.llm.isConnected.returns(true);
339
+ });
340
+
341
+ afterEach(() => {
342
+ requestTurnOnCaptions.restore();
343
+ isCaptionProcessing.restore();
344
+ voiceaService.webex.internal.llm.isConnected.returns(true);
345
+ });
346
+
347
+ it('call request turn on captions', () => {
348
+ isCaptionProcessing.returns(false);
349
+ voiceaService.turnOnCaptions();
350
+ assert.calledOnce(requestTurnOnCaptions);
351
+ });
243
352
 
244
- assert.equal(response, undefined);
353
+ it("turns on captions before llm connected", () => {
354
+ isCaptionProcessing.returns(false);
355
+ voiceaService.webex.internal.llm.isConnected.returns(true);
356
+ // assert.throws(() => voiceaService.turnOnCaptions(), "can not turn on captions before llm connected");
357
+ assert.notCalled(requestTurnOnCaptions);
358
+ });
359
+
360
+ it('should not turn on duplicate when processing', () => {
361
+ isCaptionProcessing.returns(true);
362
+ voiceaService.turnOnCaptions();
363
+ assert.notCalled(voiceaService.requestTurnOnCaptions);
245
364
  });
246
365
  });
247
366
 
@@ -263,9 +382,6 @@ describe('plugin-voicea', () => {
263
382
  data: {relayType: 'voicea.annc', voiceaPayload: {}},
264
383
  });
265
384
 
266
- const triggerSpy = sinon.spy();
267
-
268
- voiceaService.on(EVENT_TRIGGERS.TRANSCRIBING_ON, triggerSpy);
269
385
  voiceaService.listenToEvents();
270
386
 
271
387
  await voiceaService.toggleTranscribing(true);
@@ -278,16 +394,12 @@ describe('plugin-voicea', () => {
278
394
  })
279
395
  );
280
396
 
281
- assert.calledOnce(triggerSpy);
282
397
  assert.notCalled(announcementSpy);
283
398
  });
284
399
 
285
400
  it('turns on transcribing with CC disabled', async () => {
286
401
  const announcementSpy = sinon.spy(voiceaService, 'sendAnnouncement');
287
402
 
288
- const triggerSpy = sinon.spy();
289
-
290
- voiceaService.on(EVENT_TRIGGERS.TRANSCRIBING_ON, triggerSpy);
291
403
  voiceaService.listenToEvents();
292
404
 
293
405
  await voiceaService.toggleTranscribing(true);
@@ -300,7 +412,6 @@ describe('plugin-voicea', () => {
300
412
  })
301
413
  );
302
414
 
303
- assert.calledOnce(triggerSpy);
304
415
  assert.calledOnce(announcementSpy);
305
416
  });
306
417
 
@@ -309,9 +420,6 @@ describe('plugin-voicea', () => {
309
420
 
310
421
  const announcementSpy = sinon.spy(voiceaService, 'sendAnnouncement');
311
422
 
312
- const triggerSpy = sinon.spy();
313
-
314
- voiceaService.on(EVENT_TRIGGERS.TRANSCRIBING_OFF, triggerSpy);
315
423
  voiceaService.listenToEvents();
316
424
 
317
425
  await voiceaService.toggleTranscribing(false);
@@ -324,24 +432,8 @@ describe('plugin-voicea', () => {
324
432
  })
325
433
  );
326
434
 
327
- assert.calledOnce(triggerSpy);
328
435
  assert.notCalled(announcementSpy);
329
436
  });
330
-
331
- it("doesn't call API on same value", async () => {
332
- await voiceaService.toggleTranscribing(true);
333
- const triggerSpy = sinon.spy();
334
- const announcementSpy = sinon.spy(voiceaService, 'sendAnnouncement');
335
-
336
- voiceaService.on(EVENT_TRIGGERS.TRANSCRIBING_OFF, triggerSpy);
337
-
338
- await voiceaService.toggleTranscribing(true);
339
-
340
- assert.notCalled(triggerSpy);
341
- assert.notCalled(announcementSpy);
342
-
343
- assert.calledTwice(voiceaService.request);
344
- });
345
437
  });
346
438
 
347
439
  describe('#processCaptionLanguageResponse', () => {
@@ -459,6 +551,9 @@ describe('plugin-voicea', () => {
459
551
  transcript_id: '3ec73890-bffb-f28b-e77f-99dc13caea7e',
460
552
  ts: 1611653204.3147924,
461
553
  type: 'transcript_final_result',
554
+ translations: {
555
+ en: "Hello?",
556
+ },
462
557
  transcript: {
463
558
  alignments: [
464
559
  {
@@ -508,6 +603,9 @@ describe('plugin-voicea', () => {
508
603
  assert.calledOnceWithExactly(triggerSpy, {
509
604
  isFinal: true,
510
605
  transcriptId: '3ec73890-bffb-f28b-e77f-99dc13caea7e',
606
+ translations: {
607
+ en: "Hello?"
608
+ },
511
609
  transcript: {
512
610
  csis: [3556942592],
513
611
  text: 'Hello?',
@@ -642,5 +740,19 @@ describe('plugin-voicea', () => {
642
740
  });
643
741
  });
644
742
  });
743
+
744
+ describe("#getCaptionStatus", () => {
745
+ it('works correctly', () => {
746
+ voiceaService.captionStatus = "enabled"
747
+ assert.equal(voiceaService.getCaptionStatus(), "enabled");
748
+ });
749
+ });
750
+
751
+ describe("#getAnnounceStatus", () => {
752
+ it('works correctly', () => {
753
+ voiceaService.announceStatus = "joined"
754
+ assert.equal(voiceaService.getAnnounceStatus(), "joined");
755
+ });
756
+ });
645
757
  });
646
758
  });