@webex/contact-center 3.12.0-task-refactor.4 → 3.12.0-task-refactor.6
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.
- package/dist/services/task/TaskManager.js +1 -0
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +8 -6
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/state-machine/TaskStateMachine.js +77 -14
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
- package/dist/services/task/state-machine/actions.js +85 -13
- package/dist/services/task/state-machine/actions.js.map +1 -1
- package/dist/services/task/state-machine/guards.js +35 -0
- package/dist/services/task/state-machine/guards.js.map +1 -1
- package/dist/services/task/state-machine/uiControlsComputer.js +76 -10
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
- package/dist/services/task/voice/Voice.js +10 -4
- package/dist/services/task/voice/Voice.js.map +1 -1
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +68 -8
- package/dist/types/services/task/state-machine/guards.d.ts +5 -0
- package/dist/types/services/task/voice/Voice.d.ts +18 -17
- package/dist/webex.js +1 -1
- package/package.json +1 -1
- package/src/services/task/TaskManager.ts +1 -1
- package/src/services/task/TaskUtils.ts +8 -6
- package/src/services/task/state-machine/TaskStateMachine.ts +101 -16
- package/src/services/task/state-machine/actions.ts +148 -24
- package/src/services/task/state-machine/guards.ts +46 -0
- package/src/services/task/state-machine/uiControlsComputer.ts +158 -15
- package/src/services/task/voice/Voice.ts +12 -5
- package/test/unit/spec/services/WebCallingService.ts +7 -1
- package/test/unit/spec/services/task/TaskManager.ts +26 -0
- package/test/unit/spec/services/task/TaskUtils.ts +16 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +573 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +88 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +1023 -46
- package/test/unit/spec/services/task/voice/Voice.ts +44 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -46,6 +46,487 @@ function createConsultTaskData() {
|
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
function createConsultedAgentInconsistentTaskData() {
|
|
50
|
+
return createTaskData({
|
|
51
|
+
agentId: 'agent-2',
|
|
52
|
+
mediaResourceId: 'interaction-1',
|
|
53
|
+
consultMediaResourceId: 'consult-media',
|
|
54
|
+
consultingAgentId: 'agent-1',
|
|
55
|
+
isConsulted: false,
|
|
56
|
+
interaction: {
|
|
57
|
+
interactionId: 'interaction-1',
|
|
58
|
+
mainInteractionId: 'interaction-1',
|
|
59
|
+
participants: {
|
|
60
|
+
'agent-1': {id: 'agent-1', pType: 'AGENT', hasLeft: false},
|
|
61
|
+
'agent-2': {
|
|
62
|
+
id: 'agent-2',
|
|
63
|
+
pType: 'AGENT',
|
|
64
|
+
hasLeft: false,
|
|
65
|
+
consultState: 'consulting',
|
|
66
|
+
currentState: 'consulting',
|
|
67
|
+
isConsulted: true,
|
|
68
|
+
},
|
|
69
|
+
'customer-1': {id: 'customer-1', pType: 'Customer', hasLeft: false},
|
|
70
|
+
} as any,
|
|
71
|
+
media: {
|
|
72
|
+
'interaction-1': {
|
|
73
|
+
mediaResourceId: 'interaction-1',
|
|
74
|
+
mType: 'mainCall',
|
|
75
|
+
isHold: false,
|
|
76
|
+
participants: ['agent-1', 'customer-1'],
|
|
77
|
+
},
|
|
78
|
+
'consult-media': {
|
|
79
|
+
mediaResourceId: 'consult-media',
|
|
80
|
+
mType: 'consult',
|
|
81
|
+
isHold: false,
|
|
82
|
+
participants: ['agent-1', 'agent-2'],
|
|
83
|
+
},
|
|
84
|
+
} as any,
|
|
85
|
+
} as any,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function createPendingConsultHydrateTaskData() {
|
|
90
|
+
return createTaskData({
|
|
91
|
+
agentId: 'agent-1',
|
|
92
|
+
mediaResourceId: 'interaction-1',
|
|
93
|
+
consultMediaResourceId: 'consult-media',
|
|
94
|
+
isConsulted: false,
|
|
95
|
+
interaction: {
|
|
96
|
+
state: 'conference',
|
|
97
|
+
interactionId: 'interaction-1',
|
|
98
|
+
mainInteractionId: 'interaction-1',
|
|
99
|
+
participants: {
|
|
100
|
+
'agent-1': {
|
|
101
|
+
id: 'agent-1',
|
|
102
|
+
pType: 'AGENT',
|
|
103
|
+
hasLeft: false,
|
|
104
|
+
consultState: 'consultInitiated',
|
|
105
|
+
isConsulted: false,
|
|
106
|
+
},
|
|
107
|
+
'agent-2': {
|
|
108
|
+
id: 'agent-2',
|
|
109
|
+
pType: 'AGENT',
|
|
110
|
+
hasLeft: false,
|
|
111
|
+
hasJoined: false,
|
|
112
|
+
consultState: 'consultReserved',
|
|
113
|
+
isConsulted: true,
|
|
114
|
+
},
|
|
115
|
+
'agent-3': {id: 'agent-3', pType: 'AGENT', hasLeft: false, consultState: 'conferencing'},
|
|
116
|
+
'customer-1': {id: 'customer-1', pType: 'Customer', hasLeft: false},
|
|
117
|
+
} as any,
|
|
118
|
+
media: {
|
|
119
|
+
'interaction-1': {
|
|
120
|
+
mediaResourceId: 'interaction-1',
|
|
121
|
+
isHold: true,
|
|
122
|
+
mType: 'mainCall',
|
|
123
|
+
participants: ['agent-1', 'agent-3', 'customer-1'],
|
|
124
|
+
},
|
|
125
|
+
'consult-media': {
|
|
126
|
+
mediaResourceId: 'consult-media',
|
|
127
|
+
isHold: false,
|
|
128
|
+
mType: 'consult',
|
|
129
|
+
participants: ['agent-1', 'agent-2'],
|
|
130
|
+
},
|
|
131
|
+
} as any,
|
|
132
|
+
callProcessingDetails: {
|
|
133
|
+
conferenceHoldParticipant: 'true',
|
|
134
|
+
},
|
|
135
|
+
} as any,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function createHeldConferenceWithActiveConsultTaskData() {
|
|
140
|
+
return createTaskData({
|
|
141
|
+
agentId: 'agent-2',
|
|
142
|
+
mediaResourceId: 'interaction-1',
|
|
143
|
+
consultMediaResourceId: 'consult-media',
|
|
144
|
+
consultingAgentId: 'agent-1',
|
|
145
|
+
isConsulted: false,
|
|
146
|
+
interaction: {
|
|
147
|
+
state: 'conference',
|
|
148
|
+
interactionId: 'interaction-1',
|
|
149
|
+
mainInteractionId: 'interaction-1',
|
|
150
|
+
participants: {
|
|
151
|
+
'agent-1': {
|
|
152
|
+
id: 'agent-1',
|
|
153
|
+
pType: 'AGENT',
|
|
154
|
+
hasLeft: false,
|
|
155
|
+
consultState: 'consulting',
|
|
156
|
+
isConsulted: false,
|
|
157
|
+
},
|
|
158
|
+
'agent-2': {
|
|
159
|
+
id: 'agent-2',
|
|
160
|
+
pType: 'AGENT',
|
|
161
|
+
hasLeft: false,
|
|
162
|
+
consultState: 'conferencing',
|
|
163
|
+
isConsulted: false,
|
|
164
|
+
},
|
|
165
|
+
'agent-3': {
|
|
166
|
+
id: 'agent-3',
|
|
167
|
+
pType: 'AGENT',
|
|
168
|
+
hasLeft: false,
|
|
169
|
+
consultState: 'consultReserved',
|
|
170
|
+
isConsulted: true,
|
|
171
|
+
},
|
|
172
|
+
'customer-1': {id: 'customer-1', pType: 'Customer', hasLeft: false},
|
|
173
|
+
} as any,
|
|
174
|
+
media: {
|
|
175
|
+
'interaction-1': {
|
|
176
|
+
mediaResourceId: 'interaction-1',
|
|
177
|
+
isHold: true,
|
|
178
|
+
mType: 'mainCall',
|
|
179
|
+
participants: ['agent-1', 'agent-2', 'customer-1'],
|
|
180
|
+
},
|
|
181
|
+
'consult-media': {
|
|
182
|
+
mediaResourceId: 'consult-media',
|
|
183
|
+
isHold: false,
|
|
184
|
+
mType: 'consult',
|
|
185
|
+
participants: ['agent-1', 'agent-3'],
|
|
186
|
+
},
|
|
187
|
+
} as any,
|
|
188
|
+
} as any,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function createUnheldConferenceWithActiveConsultTaskData() {
|
|
193
|
+
return createTaskData({
|
|
194
|
+
agentId: 'agent-2',
|
|
195
|
+
mediaResourceId: 'interaction-1',
|
|
196
|
+
isConsulted: false,
|
|
197
|
+
interaction: {
|
|
198
|
+
state: 'conference',
|
|
199
|
+
type: 'AgentContactUnheld',
|
|
200
|
+
interactionId: 'interaction-1',
|
|
201
|
+
mainInteractionId: 'interaction-1',
|
|
202
|
+
owner: 'agent-5',
|
|
203
|
+
participants: {
|
|
204
|
+
'agent-2': {
|
|
205
|
+
id: 'agent-2',
|
|
206
|
+
pType: 'AGENT',
|
|
207
|
+
hasLeft: false,
|
|
208
|
+
consultState: 'conferencing',
|
|
209
|
+
isConsulted: false,
|
|
210
|
+
},
|
|
211
|
+
'agent-5': {
|
|
212
|
+
id: 'agent-5',
|
|
213
|
+
pType: 'AGENT',
|
|
214
|
+
hasLeft: false,
|
|
215
|
+
consultState: 'consulting',
|
|
216
|
+
isConsulted: false,
|
|
217
|
+
},
|
|
218
|
+
'agent-15': {
|
|
219
|
+
id: 'agent-15',
|
|
220
|
+
pType: 'AGENT',
|
|
221
|
+
hasLeft: false,
|
|
222
|
+
consultState: 'consulting',
|
|
223
|
+
isConsulted: true,
|
|
224
|
+
},
|
|
225
|
+
'customer-1': {id: 'customer-1', pType: 'Customer', hasLeft: false},
|
|
226
|
+
} as any,
|
|
227
|
+
media: {
|
|
228
|
+
'interaction-1': {
|
|
229
|
+
mediaResourceId: 'interaction-1',
|
|
230
|
+
isHold: false,
|
|
231
|
+
mType: 'mainCall',
|
|
232
|
+
participants: ['customer-1', 'agent-5', 'agent-2'],
|
|
233
|
+
},
|
|
234
|
+
'consult-media': {
|
|
235
|
+
mediaResourceId: 'consult-media',
|
|
236
|
+
isHold: true,
|
|
237
|
+
mType: 'consult',
|
|
238
|
+
participants: ['agent-5', 'agent-15'],
|
|
239
|
+
},
|
|
240
|
+
} as any,
|
|
241
|
+
} as any,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function createConferenceWithOtherAgentConsultPendingTaskData() {
|
|
246
|
+
return createTaskData({
|
|
247
|
+
agentId: 'agent-2',
|
|
248
|
+
mediaResourceId: 'interaction-1',
|
|
249
|
+
consultMediaResourceId: 'consult-media',
|
|
250
|
+
isConsulted: false,
|
|
251
|
+
interaction: {
|
|
252
|
+
state: 'conference',
|
|
253
|
+
interactionId: 'interaction-1',
|
|
254
|
+
mainInteractionId: 'interaction-1',
|
|
255
|
+
participants: {
|
|
256
|
+
'agent-1': {
|
|
257
|
+
id: 'agent-1',
|
|
258
|
+
pType: 'AGENT',
|
|
259
|
+
hasLeft: false,
|
|
260
|
+
consultState: 'consultInitiated',
|
|
261
|
+
isConsulted: false,
|
|
262
|
+
},
|
|
263
|
+
'agent-2': {
|
|
264
|
+
id: 'agent-2',
|
|
265
|
+
pType: 'AGENT',
|
|
266
|
+
hasLeft: false,
|
|
267
|
+
consultState: 'conferencing',
|
|
268
|
+
isConsulted: false,
|
|
269
|
+
},
|
|
270
|
+
'agent-3': {
|
|
271
|
+
id: 'agent-3',
|
|
272
|
+
pType: 'AGENT',
|
|
273
|
+
hasLeft: false,
|
|
274
|
+
consultState: 'consultReserved',
|
|
275
|
+
isConsulted: true,
|
|
276
|
+
},
|
|
277
|
+
'customer-1': {id: 'customer-1', pType: 'Customer', hasLeft: false},
|
|
278
|
+
} as any,
|
|
279
|
+
media: {
|
|
280
|
+
'interaction-1': {
|
|
281
|
+
mediaResourceId: 'interaction-1',
|
|
282
|
+
isHold: false,
|
|
283
|
+
mType: 'mainCall',
|
|
284
|
+
participants: ['agent-1', 'agent-2', 'customer-1'],
|
|
285
|
+
},
|
|
286
|
+
'consult-media': {
|
|
287
|
+
mediaResourceId: 'consult-media',
|
|
288
|
+
isHold: false,
|
|
289
|
+
mType: 'consult',
|
|
290
|
+
participants: ['agent-1', 'agent-3'],
|
|
291
|
+
},
|
|
292
|
+
} as any,
|
|
293
|
+
} as any,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function createPostConsultCompletedMultiAgentTaskData(agentId: string) {
|
|
298
|
+
return createTaskData({
|
|
299
|
+
agentId,
|
|
300
|
+
mediaResourceId: 'interaction-1',
|
|
301
|
+
consultMediaResourceId: null as any,
|
|
302
|
+
isConsulted: false,
|
|
303
|
+
interaction: {
|
|
304
|
+
state: 'conference',
|
|
305
|
+
interactionId: 'interaction-1',
|
|
306
|
+
mainInteractionId: 'interaction-1',
|
|
307
|
+
owner: 'agent-1',
|
|
308
|
+
participants: {
|
|
309
|
+
'agent-1': {
|
|
310
|
+
id: 'agent-1',
|
|
311
|
+
pType: 'AGENT',
|
|
312
|
+
hasLeft: false,
|
|
313
|
+
consultState: 'consultCompleted',
|
|
314
|
+
isConsulted: false,
|
|
315
|
+
},
|
|
316
|
+
'agent-2': {
|
|
317
|
+
id: 'agent-2',
|
|
318
|
+
pType: 'AGENT',
|
|
319
|
+
hasLeft: false,
|
|
320
|
+
consultState: 'conferencing',
|
|
321
|
+
isConsulted: false,
|
|
322
|
+
},
|
|
323
|
+
'agent-3': {
|
|
324
|
+
id: 'agent-3',
|
|
325
|
+
pType: 'AGENT',
|
|
326
|
+
hasLeft: false,
|
|
327
|
+
consultState: 'conferencing',
|
|
328
|
+
isConsulted: false,
|
|
329
|
+
},
|
|
330
|
+
'agent-4': {
|
|
331
|
+
id: 'agent-4',
|
|
332
|
+
pType: 'AGENT',
|
|
333
|
+
hasLeft: false,
|
|
334
|
+
consultState: 'conferencing',
|
|
335
|
+
isConsulted: false,
|
|
336
|
+
},
|
|
337
|
+
'agent-5': {
|
|
338
|
+
id: 'agent-5',
|
|
339
|
+
pType: 'AGENT',
|
|
340
|
+
hasLeft: false,
|
|
341
|
+
consultState: 'conferencing',
|
|
342
|
+
isConsulted: false,
|
|
343
|
+
},
|
|
344
|
+
'customer-1': {id: 'customer-1', pType: 'Customer', hasLeft: false},
|
|
345
|
+
} as any,
|
|
346
|
+
media: {
|
|
347
|
+
'interaction-1': {
|
|
348
|
+
mediaResourceId: 'interaction-1',
|
|
349
|
+
isHold: true,
|
|
350
|
+
mType: 'mainCall',
|
|
351
|
+
participants: ['agent-1', 'agent-2', 'agent-3', 'agent-4', 'agent-5', 'customer-1'],
|
|
352
|
+
},
|
|
353
|
+
} as any,
|
|
354
|
+
} as any,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function createConferenceConsultingInitiatorTaskData() {
|
|
359
|
+
return createTaskData({
|
|
360
|
+
agentId: 'agent-1',
|
|
361
|
+
mediaResourceId: 'interaction-1',
|
|
362
|
+
consultMediaResourceId: 'consult-media',
|
|
363
|
+
consultingAgentId: 'agent-1',
|
|
364
|
+
isConsulted: false,
|
|
365
|
+
interaction: {
|
|
366
|
+
state: 'conference',
|
|
367
|
+
interactionId: 'interaction-1',
|
|
368
|
+
mainInteractionId: 'interaction-1',
|
|
369
|
+
owner: 'agent-1',
|
|
370
|
+
participants: {
|
|
371
|
+
'agent-1': {
|
|
372
|
+
id: 'agent-1',
|
|
373
|
+
pType: 'AGENT',
|
|
374
|
+
hasLeft: false,
|
|
375
|
+
consultState: 'consulting',
|
|
376
|
+
isConsulted: false,
|
|
377
|
+
},
|
|
378
|
+
'agent-2': {
|
|
379
|
+
id: 'agent-2',
|
|
380
|
+
pType: 'AGENT',
|
|
381
|
+
hasLeft: false,
|
|
382
|
+
consultState: 'conferencing',
|
|
383
|
+
isConsulted: false,
|
|
384
|
+
},
|
|
385
|
+
'agent-4': {
|
|
386
|
+
id: 'agent-4',
|
|
387
|
+
pType: 'AGENT',
|
|
388
|
+
hasLeft: false,
|
|
389
|
+
consultState: 'consultReserved',
|
|
390
|
+
isConsulted: true,
|
|
391
|
+
},
|
|
392
|
+
'customer-1': {id: 'customer-1', pType: 'Customer', hasLeft: false},
|
|
393
|
+
} as any,
|
|
394
|
+
media: {
|
|
395
|
+
'interaction-1': {
|
|
396
|
+
mediaResourceId: 'interaction-1',
|
|
397
|
+
isHold: true,
|
|
398
|
+
mType: 'mainCall',
|
|
399
|
+
participants: ['agent-1', 'agent-2', 'customer-1'],
|
|
400
|
+
},
|
|
401
|
+
'consult-media': {
|
|
402
|
+
mediaResourceId: 'consult-media',
|
|
403
|
+
isHold: false,
|
|
404
|
+
mType: 'consult',
|
|
405
|
+
participants: ['agent-1', 'agent-4'],
|
|
406
|
+
},
|
|
407
|
+
} as any,
|
|
408
|
+
} as any,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function createConferenceConsultInitiatedInitiatorTaskData() {
|
|
413
|
+
return createTaskData({
|
|
414
|
+
agentId: 'agent-1',
|
|
415
|
+
mediaResourceId: 'interaction-1',
|
|
416
|
+
consultMediaResourceId: 'consult-media',
|
|
417
|
+
destAgentId: 'agent-4',
|
|
418
|
+
destinationType: 'Agent',
|
|
419
|
+
isConsulted: false,
|
|
420
|
+
type: 'AgentConsultCreated' as any,
|
|
421
|
+
interaction: {
|
|
422
|
+
state: 'conference',
|
|
423
|
+
interactionId: 'interaction-1',
|
|
424
|
+
mainInteractionId: 'interaction-1',
|
|
425
|
+
owner: 'agent-5',
|
|
426
|
+
participants: {
|
|
427
|
+
'agent-1': {
|
|
428
|
+
id: 'agent-1',
|
|
429
|
+
pType: 'AGENT',
|
|
430
|
+
hasLeft: false,
|
|
431
|
+
consultState: 'consultInitiated',
|
|
432
|
+
isConsulted: false,
|
|
433
|
+
},
|
|
434
|
+
'agent-2': {
|
|
435
|
+
id: 'agent-2',
|
|
436
|
+
pType: 'AGENT',
|
|
437
|
+
hasLeft: false,
|
|
438
|
+
consultState: 'conferencing',
|
|
439
|
+
isConsulted: false,
|
|
440
|
+
},
|
|
441
|
+
'agent-4': {
|
|
442
|
+
id: 'agent-4',
|
|
443
|
+
pType: 'AGENT',
|
|
444
|
+
hasLeft: false,
|
|
445
|
+
hasJoined: false,
|
|
446
|
+
consultState: null,
|
|
447
|
+
isConsulted: true,
|
|
448
|
+
},
|
|
449
|
+
'customer-1': {id: 'customer-1', pType: 'Customer', hasLeft: false},
|
|
450
|
+
} as any,
|
|
451
|
+
media: {
|
|
452
|
+
'interaction-1': {
|
|
453
|
+
mediaResourceId: 'interaction-1',
|
|
454
|
+
isHold: true,
|
|
455
|
+
mType: 'mainCall',
|
|
456
|
+
participants: ['agent-1', 'agent-2', 'customer-1'],
|
|
457
|
+
},
|
|
458
|
+
'consult-media': {
|
|
459
|
+
mediaResourceId: 'consult-media',
|
|
460
|
+
isHold: false,
|
|
461
|
+
mType: 'consult',
|
|
462
|
+
participants: ['agent-1', 'agent-4'],
|
|
463
|
+
},
|
|
464
|
+
} as any,
|
|
465
|
+
} as any,
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function createAgentContactUnheldInitiatorConsultTaskData() {
|
|
470
|
+
return createTaskData({
|
|
471
|
+
agentId: 'agent-1',
|
|
472
|
+
mediaResourceId: 'interaction-1',
|
|
473
|
+
consultMediaResourceId: 'consult-media',
|
|
474
|
+
destAgentId: null as any,
|
|
475
|
+
isConsulted: false,
|
|
476
|
+
interaction: {
|
|
477
|
+
state: 'conference',
|
|
478
|
+
interactionId: 'interaction-1',
|
|
479
|
+
mainInteractionId: 'interaction-1',
|
|
480
|
+
owner: 'agent-5',
|
|
481
|
+
participants: {
|
|
482
|
+
'agent-1': {
|
|
483
|
+
id: 'agent-1',
|
|
484
|
+
pType: 'AGENT',
|
|
485
|
+
hasLeft: false,
|
|
486
|
+
consultState: 'consulting',
|
|
487
|
+
isConsulted: false,
|
|
488
|
+
},
|
|
489
|
+
'agent-15': {
|
|
490
|
+
id: 'agent-15',
|
|
491
|
+
pType: 'AGENT',
|
|
492
|
+
hasLeft: false,
|
|
493
|
+
consultState: 'consulting',
|
|
494
|
+
isConsulted: true,
|
|
495
|
+
},
|
|
496
|
+
'agent-5': {
|
|
497
|
+
id: 'agent-5',
|
|
498
|
+
pType: 'AGENT',
|
|
499
|
+
hasLeft: false,
|
|
500
|
+
consultState: 'conferencing',
|
|
501
|
+
isConsulted: false,
|
|
502
|
+
},
|
|
503
|
+
'agent-3': {
|
|
504
|
+
id: 'agent-3',
|
|
505
|
+
pType: 'AGENT',
|
|
506
|
+
hasLeft: false,
|
|
507
|
+
consultState: 'conferencing',
|
|
508
|
+
isConsulted: false,
|
|
509
|
+
},
|
|
510
|
+
'customer-1': {id: 'customer-1', pType: 'Customer', hasLeft: false},
|
|
511
|
+
} as any,
|
|
512
|
+
media: {
|
|
513
|
+
'interaction-1': {
|
|
514
|
+
mediaResourceId: 'interaction-1',
|
|
515
|
+
isHold: true,
|
|
516
|
+
mType: 'mainCall',
|
|
517
|
+
participants: ['customer-1', 'agent-5', 'agent-3', 'agent-1'],
|
|
518
|
+
},
|
|
519
|
+
'consult-media': {
|
|
520
|
+
mediaResourceId: 'consult-media',
|
|
521
|
+
isHold: false,
|
|
522
|
+
mType: 'consult',
|
|
523
|
+
participants: ['agent-15', 'agent-1'],
|
|
524
|
+
},
|
|
525
|
+
} as any,
|
|
526
|
+
} as any,
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
49
530
|
function createVoiceContext(overrides: Partial<TaskContext> = {}): TaskContext {
|
|
50
531
|
return {
|
|
51
532
|
taskData: createConsultTaskData(),
|
|
@@ -71,78 +552,574 @@ function createVoiceContext(overrides: Partial<TaskContext> = {}): TaskContext {
|
|
|
71
552
|
};
|
|
72
553
|
}
|
|
73
554
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
555
|
+
function createTaskData1LikeConferenceConsultTaskData() {
|
|
556
|
+
return createTaskData({
|
|
557
|
+
agentId: '058b3e7c-8fcf-45ee-b0c4-4ef546d360b9',
|
|
558
|
+
mediaResourceId: '72402b8c-802d-4537-84d4-f244c3e586b1',
|
|
559
|
+
consultMediaResourceId: '66cc5edd-8ac9-4f27-8f48-286edea460b2',
|
|
560
|
+
consultingAgentId: '058b3e7c-8fcf-45ee-b0c4-4ef546d360b9',
|
|
561
|
+
destAgentId: '747a2138-0a24-48fc-8d69-3a336d9b7158',
|
|
562
|
+
interaction: {
|
|
563
|
+
state: 'conference',
|
|
564
|
+
type: 'AgentConsulting',
|
|
565
|
+
interactionId: '72402b8c-802d-4537-84d4-f244c3e586b1',
|
|
566
|
+
mainInteractionId: '72402b8c-802d-4537-84d4-f244c3e586b1',
|
|
567
|
+
participants: {
|
|
568
|
+
'058b3e7c-8fcf-45ee-b0c4-4ef546d360b9': {
|
|
569
|
+
id: '058b3e7c-8fcf-45ee-b0c4-4ef546d360b9',
|
|
570
|
+
pType: 'Agent',
|
|
571
|
+
hasLeft: false,
|
|
572
|
+
consultState: 'consulting',
|
|
573
|
+
isConsulted: false,
|
|
574
|
+
},
|
|
575
|
+
'747a2138-0a24-48fc-8d69-3a336d9b7158': {
|
|
576
|
+
id: '747a2138-0a24-48fc-8d69-3a336d9b7158',
|
|
577
|
+
pType: 'Agent',
|
|
578
|
+
hasLeft: false,
|
|
579
|
+
consultState: 'consulting',
|
|
580
|
+
isConsulted: true,
|
|
581
|
+
},
|
|
582
|
+
'e271075a-077d-42d0-9ae4-2a43cb847664': {
|
|
583
|
+
id: 'e271075a-077d-42d0-9ae4-2a43cb847664',
|
|
584
|
+
pType: 'Agent',
|
|
585
|
+
hasLeft: false,
|
|
586
|
+
consultState: 'conferencing',
|
|
587
|
+
isConsulted: false,
|
|
588
|
+
},
|
|
589
|
+
'ed612aec-bafe-404d-b9b2-ea7de23a04f0': {
|
|
590
|
+
id: 'ed612aec-bafe-404d-b9b2-ea7de23a04f0',
|
|
591
|
+
pType: 'Agent',
|
|
592
|
+
hasLeft: false,
|
|
593
|
+
consultState: 'conferencing',
|
|
594
|
+
isConsulted: false,
|
|
595
|
+
},
|
|
596
|
+
'+14696762938': {id: '+14696762938', pType: 'Customer', hasLeft: false},
|
|
597
|
+
} as any,
|
|
598
|
+
media: {
|
|
599
|
+
'72402b8c-802d-4537-84d4-f244c3e586b1': {
|
|
600
|
+
mediaResourceId: '72402b8c-802d-4537-84d4-f244c3e586b1',
|
|
601
|
+
mType: 'mainCall',
|
|
602
|
+
isHold: true,
|
|
603
|
+
participants: [
|
|
604
|
+
'+14696762938',
|
|
605
|
+
'e271075a-077d-42d0-9ae4-2a43cb847664',
|
|
606
|
+
'ed612aec-bafe-404d-b9b2-ea7de23a04f0',
|
|
607
|
+
'058b3e7c-8fcf-45ee-b0c4-4ef546d360b9',
|
|
608
|
+
],
|
|
609
|
+
},
|
|
610
|
+
'66cc5edd-8ac9-4f27-8f48-286edea460b2': {
|
|
611
|
+
mediaResourceId: '66cc5edd-8ac9-4f27-8f48-286edea460b2',
|
|
612
|
+
mType: 'consult',
|
|
613
|
+
isHold: false,
|
|
614
|
+
participants: ['747a2138-0a24-48fc-8d69-3a336d9b7158', '058b3e7c-8fcf-45ee-b0c4-4ef546d360b9'],
|
|
615
|
+
},
|
|
616
|
+
} as any,
|
|
617
|
+
owner: 'e271075a-077d-42d0-9ae4-2a43cb847664',
|
|
618
|
+
callProcessingDetails: {
|
|
619
|
+
conferenceHoldParticipant: 'true',
|
|
620
|
+
},
|
|
621
|
+
} as any,
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
describe('uiControlsComputer consult initiator controls', () => {
|
|
626
|
+
it('returns separate main and consult controls when consult leg is active', () => {
|
|
627
|
+
const context = createVoiceContext();
|
|
628
|
+
|
|
629
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, context.taskData);
|
|
630
|
+
|
|
631
|
+
expect(uiControls.activeLeg).toBe('consult');
|
|
632
|
+
expect(uiControls.consult).toBeDefined();
|
|
633
|
+
|
|
634
|
+
expect(uiControls.main.hold).toEqual({isVisible: false, isEnabled: false});
|
|
635
|
+
expect(uiControls.main.transfer).toEqual({isVisible: true, isEnabled: false});
|
|
636
|
+
expect(uiControls.main.conference).toEqual({isVisible: true, isEnabled: false});
|
|
637
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: false});
|
|
638
|
+
|
|
639
|
+
expect(uiControls.consult.hold).toEqual({isVisible: false, isEnabled: false});
|
|
640
|
+
expect(uiControls.consult.mute).toEqual({isVisible: false, isEnabled: false});
|
|
641
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: true, isEnabled: true});
|
|
642
|
+
expect(uiControls.consult.conference).toEqual({isVisible: true, isEnabled: true});
|
|
643
|
+
expect(uiControls.consult.endConsult).toEqual({isVisible: true, isEnabled: true});
|
|
644
|
+
expect(uiControls.consult.switch).toEqual({isVisible: true, isEnabled: true});
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
it('switches top-level controls to main leg while keeping consult leg visible', () => {
|
|
648
|
+
const context = createVoiceContext({
|
|
649
|
+
consultCallHeld: true,
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
const uiControls = computeUIControls(TaskState.CONNECTED, context, context.taskData);
|
|
653
|
+
|
|
654
|
+
expect(uiControls.activeLeg).toBe('main');
|
|
655
|
+
expect(uiControls.consult).toBeDefined();
|
|
656
|
+
|
|
657
|
+
expect(uiControls.main.hold).toEqual({isVisible: false, isEnabled: false});
|
|
658
|
+
expect(uiControls.main.switch).toEqual({isVisible: true, isEnabled: true});
|
|
659
|
+
expect(uiControls.main.transfer).toEqual({isVisible: true, isEnabled: true});
|
|
660
|
+
expect(uiControls.main.conference).toEqual({isVisible: true, isEnabled: true});
|
|
661
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: false});
|
|
662
|
+
|
|
663
|
+
expect(uiControls.consult.hold).toEqual({isVisible: false, isEnabled: false});
|
|
664
|
+
expect(uiControls.consult.mute).toEqual({isVisible: false, isEnabled: false});
|
|
665
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: true, isEnabled: false});
|
|
666
|
+
expect(uiControls.consult.conference).toEqual({isVisible: true, isEnabled: false});
|
|
667
|
+
expect(uiControls.consult.endConsult).toEqual({isVisible: true, isEnabled: true});
|
|
668
|
+
expect(uiControls.consult.end).toEqual({isVisible: false, isEnabled: false});
|
|
669
|
+
expect(uiControls.consult.switch).toEqual({isVisible: false, isEnabled: false});
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
it('hides transfer for the consulted agent during consult', () => {
|
|
673
|
+
const consultedTaskData = createConsultTaskData();
|
|
674
|
+
const consultedContext = createVoiceContext({
|
|
675
|
+
consultInitiator: false,
|
|
676
|
+
taskData: {
|
|
677
|
+
...consultedTaskData,
|
|
678
|
+
isConsulted: true,
|
|
679
|
+
} as any,
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
const uiControls = computeUIControls(
|
|
683
|
+
TaskState.CONSULTING,
|
|
684
|
+
consultedContext,
|
|
685
|
+
consultedContext.taskData
|
|
686
|
+
);
|
|
687
|
+
|
|
688
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
it('hides main-leg controls for consulted agent when payload isConsulted is stale false', () => {
|
|
692
|
+
const taskData = createConsultedAgentInconsistentTaskData();
|
|
693
|
+
const baseContext = createVoiceContext();
|
|
694
|
+
const consultedContext = createVoiceContext({
|
|
695
|
+
consultInitiator: false,
|
|
696
|
+
taskData,
|
|
697
|
+
uiControlConfig: {
|
|
698
|
+
...baseContext.uiControlConfig,
|
|
699
|
+
agentId: 'agent-2',
|
|
700
|
+
},
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
const uiControls = computeUIControls(TaskState.CONNECTED, consultedContext, taskData);
|
|
704
|
+
|
|
705
|
+
expect(uiControls.main.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
706
|
+
expect(uiControls.main.end).toEqual({isVisible: false, isEnabled: false});
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
it('keeps consult-ring controls disabled except endConsult during hydrate pending state', () => {
|
|
710
|
+
const pendingTaskData = createPendingConsultHydrateTaskData();
|
|
711
|
+
const context = createVoiceContext({
|
|
712
|
+
taskData: pendingTaskData as any,
|
|
713
|
+
consultInitiator: false,
|
|
714
|
+
consultFromConference: false,
|
|
715
|
+
consultDestinationAgentJoined: false,
|
|
716
|
+
consultCallHeld: false,
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, pendingTaskData as any);
|
|
720
|
+
|
|
721
|
+
expect(uiControls.main.transfer).toEqual({isVisible: true, isEnabled: false});
|
|
722
|
+
expect(uiControls.main.conference).toEqual({isVisible: true, isEnabled: false});
|
|
723
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: false});
|
|
724
|
+
|
|
725
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: true, isEnabled: false});
|
|
726
|
+
expect(uiControls.consult.switch).toEqual({isVisible: true, isEnabled: false});
|
|
727
|
+
expect(uiControls.consult.mergeToConference).toEqual({isVisible: true, isEnabled: false});
|
|
728
|
+
expect(uiControls.consult.endConsult).toEqual({isVisible: true, isEnabled: true});
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it('collapses stale consult leg controls during wrapup', () => {
|
|
732
|
+
const context = createVoiceContext();
|
|
733
|
+
|
|
734
|
+
const uiControls = computeUIControls(TaskState.WRAPPING_UP, context, context.taskData);
|
|
735
|
+
|
|
736
|
+
expect(uiControls.activeLeg).toBe('main');
|
|
737
|
+
expect(uiControls.main.wrapup).toEqual({isVisible: true, isEnabled: true});
|
|
738
|
+
expect(uiControls.consult).toEqual(getDefaultUIControls().consult);
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
it('disables consult for non-initiators when another agent has active consult', () => {
|
|
742
|
+
const taskData = createConferenceWithOtherAgentConsultPendingTaskData();
|
|
743
|
+
const baseContext = createVoiceContext();
|
|
744
|
+
const context = createVoiceContext({
|
|
745
|
+
consultInitiator: false,
|
|
746
|
+
consultFromConference: false,
|
|
747
|
+
taskData,
|
|
748
|
+
uiControlConfig: {
|
|
749
|
+
...baseContext.uiControlConfig,
|
|
750
|
+
agentId: 'agent-2',
|
|
751
|
+
},
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
755
|
+
|
|
756
|
+
expect(uiControls.main.consult).toEqual({isVisible: true, isEnabled: false});
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
it('enables end and exitConference for non-initiators on held main leg while another agent consults', () => {
|
|
760
|
+
const taskData = createHeldConferenceWithActiveConsultTaskData();
|
|
761
|
+
const baseContext = createVoiceContext();
|
|
762
|
+
const context = createVoiceContext({
|
|
763
|
+
consultInitiator: false,
|
|
764
|
+
taskData,
|
|
765
|
+
uiControlConfig: {
|
|
766
|
+
...baseContext.uiControlConfig,
|
|
767
|
+
agentId: 'agent-2',
|
|
768
|
+
},
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
77
772
|
|
|
78
|
-
|
|
773
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: true});
|
|
774
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: true, isEnabled: true});
|
|
775
|
+
});
|
|
79
776
|
|
|
80
|
-
|
|
81
|
-
|
|
777
|
+
it('enables end and exitConference on held main leg when consultInitiator flag is stale true', () => {
|
|
778
|
+
const taskData = createHeldConferenceWithActiveConsultTaskData();
|
|
779
|
+
const baseContext = createVoiceContext();
|
|
780
|
+
const context = createVoiceContext({
|
|
781
|
+
consultInitiator: true,
|
|
782
|
+
taskData,
|
|
783
|
+
uiControlConfig: {
|
|
784
|
+
...baseContext.uiControlConfig,
|
|
785
|
+
agentId: 'agent-2',
|
|
786
|
+
},
|
|
787
|
+
});
|
|
82
788
|
|
|
83
|
-
|
|
84
|
-
expect(uiControls.main.transfer).toEqual({isVisible: true, isEnabled: false});
|
|
85
|
-
expect(uiControls.main.conference).toEqual({isVisible: true, isEnabled: false});
|
|
86
|
-
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: false});
|
|
789
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
87
790
|
|
|
88
|
-
expect(uiControls.
|
|
89
|
-
expect(uiControls.
|
|
90
|
-
|
|
91
|
-
|
|
791
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: true});
|
|
792
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: true, isEnabled: true});
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
it('enables end and exitConference on unheld main leg for non-initiator during active conference consult', () => {
|
|
796
|
+
const taskData = createUnheldConferenceWithActiveConsultTaskData();
|
|
797
|
+
const baseContext = createVoiceContext();
|
|
798
|
+
const context = createVoiceContext({
|
|
799
|
+
consultInitiator: false,
|
|
800
|
+
taskData,
|
|
801
|
+
uiControlConfig: {
|
|
802
|
+
...baseContext.uiControlConfig,
|
|
803
|
+
agentId: 'agent-2',
|
|
804
|
+
},
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
808
|
+
|
|
809
|
+
expect(uiControls.activeLeg).toBe('main');
|
|
810
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: true});
|
|
811
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: true, isEnabled: true});
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
it('keeps consult disabled for non-owner after owner consult completes in multi-agent conference', () => {
|
|
815
|
+
const taskData = createPostConsultCompletedMultiAgentTaskData('agent-2');
|
|
816
|
+
const baseContext = createVoiceContext();
|
|
817
|
+
const context = createVoiceContext({
|
|
818
|
+
consultInitiator: false,
|
|
819
|
+
taskData,
|
|
820
|
+
uiControlConfig: {
|
|
821
|
+
...baseContext.uiControlConfig,
|
|
822
|
+
agentId: 'agent-2',
|
|
823
|
+
},
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
827
|
+
|
|
828
|
+
expect(uiControls.main.consult).toEqual({isVisible: true, isEnabled: false});
|
|
829
|
+
});
|
|
830
|
+
|
|
831
|
+
it('keeps consult enabled for owner after consult completes in multi-agent conference', () => {
|
|
832
|
+
const taskData = createPostConsultCompletedMultiAgentTaskData('agent-1');
|
|
833
|
+
const baseContext = createVoiceContext();
|
|
834
|
+
const context = createVoiceContext({
|
|
835
|
+
consultInitiator: false,
|
|
836
|
+
taskData,
|
|
837
|
+
uiControlConfig: {
|
|
838
|
+
...baseContext.uiControlConfig,
|
|
839
|
+
agentId: 'agent-1',
|
|
840
|
+
},
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
844
|
+
|
|
845
|
+
expect(uiControls.main.consult).toEqual({isVisible: true, isEnabled: true});
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
it('hides transfer and enables transferConference on consult leg for conference initiator', () => {
|
|
849
|
+
const taskData = createConferenceConsultingInitiatorTaskData();
|
|
850
|
+
const baseContext = createVoiceContext();
|
|
851
|
+
const context = createVoiceContext({
|
|
852
|
+
consultInitiator: true,
|
|
853
|
+
consultFromConference: true,
|
|
854
|
+
consultDestinationAgentJoined: true,
|
|
855
|
+
consultCallHeld: false,
|
|
856
|
+
taskData,
|
|
857
|
+
uiControlConfig: {
|
|
858
|
+
...baseContext.uiControlConfig,
|
|
859
|
+
agentId: 'agent-1',
|
|
860
|
+
},
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, taskData);
|
|
864
|
+
|
|
865
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
866
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
867
|
+
expect(uiControls.main.transferConference).toEqual({isVisible: true, isEnabled: false});
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
it('keeps consult leg controls active and main leg conference controls disabled on hydrate-like context', () => {
|
|
871
|
+
const taskData = createConferenceConsultingInitiatorTaskData();
|
|
872
|
+
const baseContext = createVoiceContext();
|
|
873
|
+
const context = createVoiceContext({
|
|
874
|
+
consultInitiator: true,
|
|
875
|
+
consultFromConference: true,
|
|
876
|
+
consultDestinationAgentJoined: true,
|
|
877
|
+
consultCallHeld: false,
|
|
878
|
+
taskData,
|
|
879
|
+
uiControlConfig: {
|
|
880
|
+
...baseContext.uiControlConfig,
|
|
881
|
+
agentId: 'agent-1',
|
|
882
|
+
},
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, taskData);
|
|
886
|
+
|
|
887
|
+
expect(uiControls.activeLeg).toBe('consult');
|
|
888
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: false});
|
|
889
|
+
expect(uiControls.main.conference).toEqual({isVisible: true, isEnabled: false});
|
|
890
|
+
expect(uiControls.main.transferConference).toEqual({isVisible: true, isEnabled: false});
|
|
92
891
|
expect(uiControls.consult.switch).toEqual({isVisible: true, isEnabled: true});
|
|
892
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
893
|
+
expect(uiControls.consult.mergeToConference).toEqual({isVisible: true, isEnabled: true});
|
|
894
|
+
expect(uiControls.consult.endConsult).toEqual({isVisible: true, isEnabled: true});
|
|
93
895
|
});
|
|
94
896
|
|
|
95
|
-
it('
|
|
897
|
+
it('keeps transferConference visible on consult leg for initiator even when state is conferencing', () => {
|
|
898
|
+
const taskData = createConferenceConsultingInitiatorTaskData();
|
|
899
|
+
const baseContext = createVoiceContext();
|
|
900
|
+
const context = createVoiceContext({
|
|
901
|
+
consultInitiator: true,
|
|
902
|
+
consultFromConference: true,
|
|
903
|
+
consultDestinationAgentJoined: true,
|
|
904
|
+
consultCallHeld: false,
|
|
905
|
+
taskData,
|
|
906
|
+
uiControlConfig: {
|
|
907
|
+
...baseContext.uiControlConfig,
|
|
908
|
+
agentId: 'agent-1',
|
|
909
|
+
},
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
913
|
+
|
|
914
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
915
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
916
|
+
});
|
|
917
|
+
|
|
918
|
+
it('shows transferConference for initiator in AgentContactUnheld-style conference consult context', () => {
|
|
919
|
+
const taskData = createAgentContactUnheldInitiatorConsultTaskData();
|
|
920
|
+
const baseContext = createVoiceContext();
|
|
96
921
|
const context = createVoiceContext({
|
|
922
|
+
consultInitiator: true,
|
|
923
|
+
consultFromConference: false,
|
|
924
|
+
consultDestinationAgentJoined: true,
|
|
925
|
+
consultCallHeld: false,
|
|
926
|
+
taskData,
|
|
927
|
+
uiControlConfig: {
|
|
928
|
+
...baseContext.uiControlConfig,
|
|
929
|
+
agentId: 'agent-1',
|
|
930
|
+
},
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
934
|
+
|
|
935
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
it('shows transferConference on main leg when initiator has active conference consult', () => {
|
|
939
|
+
const taskData = createConferenceConsultingInitiatorTaskData();
|
|
940
|
+
const baseContext = createVoiceContext();
|
|
941
|
+
const context = createVoiceContext({
|
|
942
|
+
consultInitiator: true,
|
|
943
|
+
consultFromConference: true,
|
|
944
|
+
consultDestinationAgentJoined: true,
|
|
97
945
|
consultCallHeld: true,
|
|
946
|
+
taskData,
|
|
947
|
+
uiControlConfig: {
|
|
948
|
+
...baseContext.uiControlConfig,
|
|
949
|
+
agentId: 'agent-1',
|
|
950
|
+
},
|
|
98
951
|
});
|
|
99
952
|
|
|
100
|
-
const uiControls = computeUIControls(TaskState.
|
|
953
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
101
954
|
|
|
102
955
|
expect(uiControls.activeLeg).toBe('main');
|
|
103
|
-
expect(uiControls.
|
|
956
|
+
expect(uiControls.main.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
957
|
+
expect(uiControls.main.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
958
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: false});
|
|
959
|
+
});
|
|
104
960
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
961
|
+
it('keeps transferConference visible on consult leg for taskData1-style payload', () => {
|
|
962
|
+
const taskData = createTaskData1LikeConferenceConsultTaskData();
|
|
963
|
+
const baseContext = createVoiceContext();
|
|
964
|
+
const context = createVoiceContext({
|
|
965
|
+
consultInitiator: true,
|
|
966
|
+
consultFromConference: true,
|
|
967
|
+
consultDestinationAgentJoined: true,
|
|
968
|
+
consultCallHeld: false,
|
|
969
|
+
taskData,
|
|
970
|
+
uiControlConfig: {
|
|
971
|
+
...baseContext.uiControlConfig,
|
|
972
|
+
agentId: '058b3e7c-8fcf-45ee-b0c4-4ef546d360b9',
|
|
973
|
+
},
|
|
974
|
+
});
|
|
110
975
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
expect(uiControls.
|
|
114
|
-
expect(uiControls.consult.
|
|
115
|
-
expect(uiControls.consult.
|
|
116
|
-
expect(uiControls.consult.switch).toEqual({isVisible: false, isEnabled: false});
|
|
976
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
977
|
+
|
|
978
|
+
expect(uiControls.activeLeg).toBe('consult');
|
|
979
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
980
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
117
981
|
});
|
|
118
982
|
|
|
119
|
-
it('
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
983
|
+
it('enables transferConference after AgentConsulting follows AgentConsultCreated for initiator', () => {
|
|
984
|
+
const baseContext = createVoiceContext();
|
|
985
|
+
const createdTaskData = createConferenceConsultInitiatedInitiatorTaskData();
|
|
986
|
+
const createdContext = createVoiceContext({
|
|
987
|
+
consultInitiator: true,
|
|
988
|
+
consultFromConference: true,
|
|
989
|
+
consultDestinationAgentJoined: false,
|
|
990
|
+
consultCallHeld: false,
|
|
991
|
+
taskData: createdTaskData,
|
|
992
|
+
uiControlConfig: {
|
|
993
|
+
...baseContext.uiControlConfig,
|
|
994
|
+
agentId: 'agent-1',
|
|
995
|
+
},
|
|
127
996
|
});
|
|
997
|
+
const createdControls = computeUIControls(TaskState.CONSULTING, createdContext, createdTaskData);
|
|
128
998
|
|
|
129
|
-
|
|
999
|
+
expect(createdControls.consult.transferConference).toEqual({isVisible: true, isEnabled: false});
|
|
1000
|
+
|
|
1001
|
+
const consultingTaskData = createConferenceConsultingInitiatorTaskData();
|
|
1002
|
+
const consultingContext = createVoiceContext({
|
|
1003
|
+
...createdContext,
|
|
1004
|
+
taskData: consultingTaskData,
|
|
1005
|
+
consultDestinationAgentJoined: true,
|
|
1006
|
+
});
|
|
1007
|
+
const consultingControls = computeUIControls(
|
|
130
1008
|
TaskState.CONSULTING,
|
|
131
|
-
|
|
132
|
-
|
|
1009
|
+
consultingContext,
|
|
1010
|
+
consultingTaskData
|
|
133
1011
|
);
|
|
134
1012
|
|
|
135
|
-
expect(
|
|
1013
|
+
expect(consultingControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
136
1014
|
});
|
|
137
1015
|
|
|
138
|
-
it('
|
|
139
|
-
const
|
|
1016
|
+
it('hides exitConference on main leg for consult initiator before destination joins', () => {
|
|
1017
|
+
const taskData = createConferenceConsultInitiatedInitiatorTaskData();
|
|
1018
|
+
const baseContext = createVoiceContext();
|
|
1019
|
+
const context = createVoiceContext({
|
|
1020
|
+
consultInitiator: true,
|
|
1021
|
+
consultFromConference: true,
|
|
1022
|
+
consultDestinationAgentJoined: false,
|
|
1023
|
+
consultCallHeld: false,
|
|
1024
|
+
taskData,
|
|
1025
|
+
uiControlConfig: {
|
|
1026
|
+
...baseContext.uiControlConfig,
|
|
1027
|
+
agentId: 'agent-1',
|
|
1028
|
+
},
|
|
1029
|
+
});
|
|
140
1030
|
|
|
141
|
-
const uiControls = computeUIControls(TaskState.
|
|
1031
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
142
1032
|
|
|
143
|
-
expect(uiControls.
|
|
144
|
-
|
|
145
|
-
|
|
1033
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: false, isEnabled: false});
|
|
1034
|
+
});
|
|
1035
|
+
|
|
1036
|
+
it('hides exitConference on main leg while consulting and destination has not joined', () => {
|
|
1037
|
+
const taskData = createConferenceConsultInitiatedInitiatorTaskData();
|
|
1038
|
+
const baseContext = createVoiceContext();
|
|
1039
|
+
const context = createVoiceContext({
|
|
1040
|
+
consultInitiator: true,
|
|
1041
|
+
consultFromConference: true,
|
|
1042
|
+
consultDestinationAgentJoined: false,
|
|
1043
|
+
consultCallHeld: false,
|
|
1044
|
+
taskData,
|
|
1045
|
+
uiControlConfig: {
|
|
1046
|
+
...baseContext.uiControlConfig,
|
|
1047
|
+
agentId: 'agent-1',
|
|
1048
|
+
},
|
|
1049
|
+
});
|
|
1050
|
+
|
|
1051
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, taskData);
|
|
1052
|
+
|
|
1053
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: false, isEnabled: false});
|
|
1054
|
+
});
|
|
1055
|
+
|
|
1056
|
+
it('hides exitConference on main leg for pending self consult even with stale initiator flags', () => {
|
|
1057
|
+
const taskData = createConferenceConsultInitiatedInitiatorTaskData();
|
|
1058
|
+
const baseContext = createVoiceContext();
|
|
1059
|
+
const context = createVoiceContext({
|
|
1060
|
+
consultInitiator: false,
|
|
1061
|
+
consultFromConference: false,
|
|
1062
|
+
consultDestinationAgentJoined: false,
|
|
1063
|
+
consultCallHeld: false,
|
|
1064
|
+
taskData,
|
|
1065
|
+
uiControlConfig: {
|
|
1066
|
+
...baseContext.uiControlConfig,
|
|
1067
|
+
agentId: 'agent-1',
|
|
1068
|
+
},
|
|
1069
|
+
});
|
|
1070
|
+
|
|
1071
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, taskData);
|
|
1072
|
+
|
|
1073
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: false, isEnabled: false});
|
|
1074
|
+
});
|
|
1075
|
+
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
describe('uiControlsComputer outdial accept/decline controls', () => {
|
|
1079
|
+
function createOutdialContext(voiceVariant: 'webrtc' | 'pstn' = 'webrtc'): TaskContext {
|
|
1080
|
+
const taskData = createTaskData({
|
|
1081
|
+
interaction: {
|
|
1082
|
+
outboundType: 'OUTDIAL',
|
|
1083
|
+
state: 'new',
|
|
1084
|
+
isTerminated: false,
|
|
1085
|
+
} as any,
|
|
1086
|
+
});
|
|
1087
|
+
return {
|
|
1088
|
+
taskData,
|
|
1089
|
+
consultInitiator: false,
|
|
1090
|
+
exitingConference: false,
|
|
1091
|
+
consultFromConference: false,
|
|
1092
|
+
transferConferenceRequested: false,
|
|
1093
|
+
consultDestinationType: null,
|
|
1094
|
+
consultDestinationAgentId: null,
|
|
1095
|
+
consultDestinationAgentJoined: false,
|
|
1096
|
+
consultCallHeld: false,
|
|
1097
|
+
recordingControlsAvailable: false,
|
|
1098
|
+
recordingInProgress: false,
|
|
1099
|
+
uiControlConfig: {
|
|
1100
|
+
isEndTaskEnabled: true,
|
|
1101
|
+
isEndConsultEnabled: true,
|
|
1102
|
+
channelType: TASK_CHANNEL_TYPE.VOICE,
|
|
1103
|
+
isRecordingEnabled: false,
|
|
1104
|
+
agentId: 'agent-1',
|
|
1105
|
+
voiceVariant,
|
|
1106
|
+
},
|
|
1107
|
+
uiControls: getDefaultUIControls(),
|
|
1108
|
+
};
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
it('accept is visible but disabled for WebRTC outdial in OFFERED state', () => {
|
|
1112
|
+
const context = createOutdialContext('webrtc');
|
|
1113
|
+
const uiControls = computeUIControls(TaskState.OFFERED, context, context.taskData);
|
|
1114
|
+
|
|
1115
|
+
expect(uiControls.main.accept).toEqual({isVisible: true, isEnabled: false});
|
|
1116
|
+
});
|
|
1117
|
+
|
|
1118
|
+
it('decline is visible but disabled for WebRTC outdial in OFFERED state', () => {
|
|
1119
|
+
const context = createOutdialContext('webrtc');
|
|
1120
|
+
const uiControls = computeUIControls(TaskState.OFFERED, context, context.taskData);
|
|
1121
|
+
|
|
1122
|
+
expect(uiControls.main.decline).toEqual({isVisible: true, isEnabled: false});
|
|
146
1123
|
});
|
|
147
1124
|
});
|
|
148
1125
|
|