@webex/plugin-meetings 2.60.1-next.14 → 2.60.1-next.15

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.
@@ -0,0 +1,266 @@
1
+ import {
2
+ getSpeakerFromProxyOrStore,
3
+ processNewCaptions,
4
+ } from '@webex/plugin-meetings/src/meeting/voicea-meeting';
5
+ import {assert} from '@webex/test-helper-chai';
6
+ import { expect } from 'chai';
7
+
8
+ describe('plugin-meetings', () => {
9
+ let fakeMeeting, fakeVoiceaPayload;
10
+ const fakeMemberId = "4f35a5ab-f750-3ba7-b309-dea62a512257";
11
+ beforeEach(() => {
12
+ const fakeMemberList = {
13
+ [fakeMemberId]: {
14
+ participant: {
15
+ person: {
16
+ id: "8093d335-9b96-4f9d-a6b2-7293423be88a",
17
+ name: "John Doe",
18
+ isExternal: false,
19
+ orgId: "1eb65fdf-9643-417f-9974-ad72cae0e10f",
20
+ incomingCallProtocols: []
21
+ },
22
+ status: {
23
+ audioStatus: "SENDRECV",
24
+ videoStatus: "INACTIVE",
25
+ videoSlidesStatus: "RECVONLY",
26
+ audioSlidesStatus: "INACTIVE",
27
+ csis: [
28
+ 3060099329,
29
+ 3060099328,
30
+ 1234867712,
31
+ 1234867713
32
+ ]
33
+ },
34
+ },
35
+ id: fakeMemberId
36
+ }
37
+ };
38
+
39
+ const fakeCaptions = {
40
+ captions: [
41
+ {
42
+ id: "6bece1b9-4e50-fafe-fb63-d27d5fb27280",
43
+ isFinal: true,
44
+ text: "Oh it's not update.",
45
+ currentSpokenLanguage: "en",
46
+ timestamp: "1:34",
47
+ speaker: {
48
+ speakerId: "8093d335-9b96-4f9d-a6b2-7293423be88a",
49
+ name: "John Doe"
50
+ }
51
+ },
52
+ {
53
+ id: "c34400a9-cb2b-20c3-d20c-bd7981cc62a9",
54
+ isFinal: true,
55
+ text: "Nice.",
56
+ currentSpokenLanguage: "en",
57
+ timestamp: "1:60",
58
+ speaker: {
59
+ speakerId: "8093d335-9b96-4f9d-a6b2-7293423be88a",
60
+ name: "John Doe"
61
+ }
62
+ },
63
+ {
64
+ id: "311cc182-e657-c077-c078-795f866c4e9b_8093d335-9b96-4f9d-a6b2-7293423be88a",
65
+ isFinal: false,
66
+ text: " Don't bother me talking I'm just going to get the transcript data that is interim and I",
67
+ currentCaptionLanguage: "en",
68
+ speaker: {
69
+ speakerId: "8093d335-9b96-4f9d-a6b2-7293423be88a",
70
+ name: "John Doe"
71
+ }
72
+ }
73
+ ],
74
+ interimCaptions: {
75
+ "6bece1b9-4e50-fafe-fb63-d27d5fb27280": [],
76
+ "c34400a9-cb2b-20c3-d20c-bd7981cc62a9": [],
77
+ "311cc182-e657-c077-c078-795f866c4e9b": [
78
+ "311cc182-e657-c077-c078-795f866c4e9b_8093d335-9b96-4f9d-a6b2-7293423be88a"
79
+ ]
80
+ },
81
+ speakerProxy: {},
82
+ };
83
+
84
+ fakeMeeting = {
85
+ members: {
86
+ membersCollection: {
87
+ members: fakeMemberList
88
+ }
89
+ },
90
+ transcription: fakeCaptions
91
+ }
92
+
93
+ fakeVoiceaPayload = {
94
+ isFinal: true,
95
+ transcriptId: "311cc182-e657-c077-c078-795f866c4e9b",
96
+ transcripts: [
97
+ {
98
+ text: "Don't bother me talking I'm just going to get the transcript data that is interim and I needed if I keep talking, I get the interim data",
99
+ csis: [
100
+ 1234867712
101
+ ],
102
+ transcript_language_code: "en"
103
+ }
104
+ ],
105
+ transcript: {
106
+ text: "Don't bother me talking I'm just going to get the transcript data that is interim and I needed if I keep talking, I get the interim data",
107
+ csis: [
108
+ 1234867712
109
+ ],
110
+ transcript_language_code: "en"
111
+ }
112
+ };
113
+ });
114
+
115
+ describe('voicea-meeting', () => {
116
+ it('should export the correct members', () => {
117
+ assert.isFunction(getSpeakerFromProxyOrStore);
118
+ assert.isFunction(processNewCaptions);
119
+ });
120
+
121
+ describe('getSpeakerFromProxyOrStore', () => {
122
+ it('should return a cached speaker if csisKey is in speakerProxy', () => {
123
+ // Add a speaker to the speakerProxy
124
+ const csisKey = 1234867712;
125
+ const cachedSpeaker = {
126
+ speakerId: 'cached-speaker-id',
127
+ name: 'Cached Speaker'
128
+ };
129
+ fakeMeeting.transcription.speakerProxy[csisKey] = cachedSpeaker;
130
+
131
+ const { speaker, needsCaching } = getSpeakerFromProxyOrStore({
132
+ csisKey,
133
+ meetingMembers: fakeMeeting.members.membersCollection.members,
134
+ transcriptData: fakeMeeting.transcription
135
+ });
136
+
137
+ expect(speaker).to.deep.equal(cachedSpeaker);
138
+ expect(needsCaching).to.be.false;
139
+ });
140
+
141
+ it('should find and cache a speaker if not already in speakerProxy', () => {
142
+ const csisKey = 1234867712; // This csis exists in the fakeMemberList
143
+
144
+ // Ensure speakerProxy is empty
145
+ fakeMeeting.transcription.speakerProxy = {};
146
+
147
+ const { speaker, needsCaching } = getSpeakerFromProxyOrStore({
148
+ csisKey,
149
+ meetingMembers: fakeMeeting.members.membersCollection.members,
150
+ transcriptData: fakeMeeting.transcription
151
+ });
152
+
153
+ expect(speaker.speakerId).to.equal(fakeMeeting.members.membersCollection.members[fakeMemberId].participant.person.id);
154
+ expect(speaker.name).to.equal(fakeMeeting.members.membersCollection.members[fakeMemberId].participant.person.name);
155
+ expect(needsCaching).to.be.true;
156
+ });
157
+ });
158
+
159
+ describe('processNewCaptions', () => {
160
+ it('should process new final captions correctly', () => {
161
+ let transcriptData = fakeMeeting.transcription;
162
+ let transcriptId = fakeVoiceaPayload.transcriptId;
163
+ delete fakeVoiceaPayload.transcripts;
164
+
165
+ // Assuming that processNewCaptions is a pure function that doesn't mutate the input but returns a new state
166
+ processNewCaptions({
167
+ data: fakeVoiceaPayload,
168
+ meeting: fakeMeeting
169
+ });
170
+
171
+ // Check if speaker details are cached if needed
172
+ const csisKey = fakeVoiceaPayload.transcript.csis[0];
173
+ const speaker = transcriptData.speakerProxy[csisKey];
174
+ expect(speaker).to.exist;
175
+
176
+ // Check if interim captions are removed
177
+ expect(transcriptData.interimCaptions[transcriptId]).to.deep.equal([]);
178
+
179
+ //check if the interim caption is removed
180
+ const oldInterimCaption = transcriptData.captions.find(caption => caption.id === `${transcriptId}_${speaker.speakerId}`);
181
+ expect(oldInterimCaption).to.not.exist;
182
+
183
+ // Check the final caption data
184
+ const newCaption = transcriptData.captions.find(caption => caption.id === transcriptId);
185
+ expect(newCaption).to.exist;
186
+ expect(newCaption).to.include({
187
+ id: transcriptId,
188
+ isFinal: fakeVoiceaPayload.isFinal,
189
+ text: fakeVoiceaPayload.transcript.text,
190
+ currentSpokenLanguage: fakeVoiceaPayload.transcript.transcript_language_code,
191
+ });
192
+
193
+ // Check the speaker data in the new caption
194
+ expect(newCaption.speaker).to.deep.equal(speaker);
195
+ });
196
+
197
+ it('should process new interim captions correctly', () => {
198
+ let transcriptData = fakeMeeting.transcription;
199
+ let transcriptId = fakeVoiceaPayload.transcriptId;
200
+ delete fakeVoiceaPayload.transcript;
201
+
202
+ transcriptData.captions.splice(transcriptData.length - 1, 1);
203
+ fakeVoiceaPayload.isFinal = false;
204
+
205
+ processNewCaptions({
206
+ data: fakeVoiceaPayload,
207
+ meeting: fakeMeeting
208
+ });
209
+
210
+ // Check if speaker details are cached if needed
211
+ const csisKey = fakeVoiceaPayload.transcripts[0].csis[0];
212
+ const speaker = transcriptData.speakerProxy[csisKey];
213
+ expect(speaker).to.exist;
214
+
215
+ // Check the final caption data
216
+ const newCaption = transcriptData.captions.find(caption => caption.id === `${transcriptId}_${speaker.speakerId}`);
217
+ expect(newCaption).to.exist;
218
+ expect(newCaption).to.include({
219
+ id: `${transcriptId}_${speaker.speakerId}`,
220
+ isFinal: fakeVoiceaPayload.isFinal,
221
+ text: fakeVoiceaPayload.transcripts[0].text,
222
+ currentCaptionLanguage: fakeVoiceaPayload.transcripts[0].transcript_language_code,
223
+ });
224
+
225
+ // Check if interim captions has the right caption id
226
+ expect(transcriptData.interimCaptions[transcriptId]).to.deep.equal([newCaption.id]);
227
+
228
+ // Check the speaker data in the new caption
229
+ expect(newCaption.speaker).to.deep.equal(speaker);
230
+ });
231
+
232
+ it('should process interim captions with an existing one correctly', () => {
233
+ let transcriptData = fakeMeeting.transcription;
234
+ let transcriptId = fakeVoiceaPayload.transcriptId;
235
+ delete fakeVoiceaPayload.transcript;
236
+ fakeVoiceaPayload.isFinal = false;
237
+
238
+ processNewCaptions({
239
+ data: fakeVoiceaPayload,
240
+ meeting: fakeMeeting
241
+ });
242
+
243
+ // Check if speaker details are cached if needed
244
+ const csisKey = fakeVoiceaPayload.transcripts[0].csis[0];
245
+ const speaker = transcriptData.speakerProxy[csisKey];
246
+ expect(speaker).to.exist;
247
+
248
+ // Check the final caption data
249
+ const newCaption = transcriptData.captions.find(caption => caption.id === `${transcriptId}_${speaker.speakerId}`);
250
+ expect(newCaption).to.exist;
251
+ expect(newCaption).to.include({
252
+ id: `${transcriptId}_${speaker.speakerId}`,
253
+ isFinal: fakeVoiceaPayload.isFinal,
254
+ text: fakeVoiceaPayload.transcripts[0].text,
255
+ currentCaptionLanguage: fakeVoiceaPayload.transcripts[0].transcript_language_code,
256
+ });
257
+
258
+ // Check if interim captions has the right caption id
259
+ expect(transcriptData.interimCaptions[transcriptId]).to.deep.equal([newCaption.id]);
260
+
261
+ // Check the speaker data in the new caption
262
+ expect(newCaption.speaker).to.deep.equal(speaker);
263
+ });
264
+ });
265
+ });
266
+ });