@webex/contact-center 3.12.0-task-refactor.5 → 3.12.0-task-refactor.7
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/TaskUtils.js +8 -6
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/state-machine/TaskStateMachine.js +72 -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 +72 -7
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1 -1
- package/dist/services/task/voice/Voice.js.map +1 -1
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +60 -8
- package/dist/types/services/task/state-machine/guards.d.ts +5 -0
- package/dist/webex.js +1 -1
- package/package.json +1 -1
- package/src/services/task/TaskUtils.ts +8 -6
- package/src/services/task/state-machine/TaskStateMachine.ts +95 -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 +163 -9
- package/src/services/task/voice/Voice.ts +4 -1
- package/test/unit/spec/services/WebCallingService.ts +7 -1
- package/test/unit/spec/services/task/TaskUtils.ts +16 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +512 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +88 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +1000 -7
- package/test/unit/spec/services/task/voice/Voice.ts +20 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {TASK_CHANNEL_TYPE} from '../../../../../../src/services/task/types';
|
|
1
|
+
import {TASK_CHANNEL_TYPE, VOICE_VARIANT} from '../../../../../../src/services/task/types';
|
|
2
2
|
import {TaskState} from '../../../../../../src/services/task/state-machine/constants';
|
|
3
3
|
import {
|
|
4
4
|
computeUIControls,
|
|
@@ -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,6 +552,76 @@ function createVoiceContext(overrides: Partial<TaskContext> = {}): TaskContext {
|
|
|
71
552
|
};
|
|
72
553
|
}
|
|
73
554
|
|
|
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
|
+
|
|
74
625
|
describe('uiControlsComputer consult initiator controls', () => {
|
|
75
626
|
it('returns separate main and consult controls when consult leg is active', () => {
|
|
76
627
|
const context = createVoiceContext();
|
|
@@ -86,6 +637,7 @@ describe('uiControlsComputer consult initiator controls', () => {
|
|
|
86
637
|
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: false});
|
|
87
638
|
|
|
88
639
|
expect(uiControls.consult.hold).toEqual({isVisible: false, isEnabled: false});
|
|
640
|
+
expect(uiControls.consult.mute).toEqual({isVisible: false, isEnabled: false});
|
|
89
641
|
expect(uiControls.consult.transfer).toEqual({isVisible: true, isEnabled: true});
|
|
90
642
|
expect(uiControls.consult.conference).toEqual({isVisible: true, isEnabled: true});
|
|
91
643
|
expect(uiControls.consult.endConsult).toEqual({isVisible: true, isEnabled: true});
|
|
@@ -108,12 +660,77 @@ describe('uiControlsComputer consult initiator controls', () => {
|
|
|
108
660
|
expect(uiControls.main.conference).toEqual({isVisible: true, isEnabled: true});
|
|
109
661
|
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: false});
|
|
110
662
|
|
|
111
|
-
expect(uiControls.consult.hold).toEqual({isVisible: false, isEnabled: false});
|
|
112
|
-
expect(uiControls.consult.
|
|
113
|
-
expect(uiControls.consult.
|
|
114
|
-
expect(uiControls.consult.
|
|
115
|
-
expect(uiControls.consult.
|
|
116
|
-
expect(uiControls.consult.
|
|
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('enables mute only on active leg when main leg is active', () => {
|
|
673
|
+
const baseTaskData = createConsultTaskData();
|
|
674
|
+
const taskData = createTaskData({
|
|
675
|
+
...baseTaskData,
|
|
676
|
+
interaction: {
|
|
677
|
+
...baseTaskData.interaction,
|
|
678
|
+
media: {
|
|
679
|
+
...baseTaskData.interaction.media,
|
|
680
|
+
'consult-media': {
|
|
681
|
+
...baseTaskData.interaction.media['consult-media'],
|
|
682
|
+
participants: ['agent-1', 'agent-2'],
|
|
683
|
+
},
|
|
684
|
+
},
|
|
685
|
+
},
|
|
686
|
+
});
|
|
687
|
+
const baseContext = createVoiceContext();
|
|
688
|
+
const context = createVoiceContext({
|
|
689
|
+
taskData,
|
|
690
|
+
consultCallHeld: true,
|
|
691
|
+
uiControlConfig: {
|
|
692
|
+
...baseContext.uiControlConfig,
|
|
693
|
+
voiceVariant: VOICE_VARIANT.WEBRTC,
|
|
694
|
+
},
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
const uiControls = computeUIControls(TaskState.CONNECTED, context, context.taskData);
|
|
698
|
+
|
|
699
|
+
expect(uiControls.activeLeg).toBe('main');
|
|
700
|
+
expect(uiControls.main.mute).toEqual({isVisible: true, isEnabled: true});
|
|
701
|
+
expect(uiControls.consult.mute).toEqual({isVisible: true, isEnabled: false});
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
it('enables mute only on active leg when consult leg is active', () => {
|
|
705
|
+
const baseTaskData = createConsultTaskData();
|
|
706
|
+
const taskData = createTaskData({
|
|
707
|
+
...baseTaskData,
|
|
708
|
+
interaction: {
|
|
709
|
+
...baseTaskData.interaction,
|
|
710
|
+
media: {
|
|
711
|
+
...baseTaskData.interaction.media,
|
|
712
|
+
'consult-media': {
|
|
713
|
+
...baseTaskData.interaction.media['consult-media'],
|
|
714
|
+
participants: ['agent-1', 'agent-2'],
|
|
715
|
+
},
|
|
716
|
+
},
|
|
717
|
+
},
|
|
718
|
+
});
|
|
719
|
+
const baseContext = createVoiceContext();
|
|
720
|
+
const context = createVoiceContext({
|
|
721
|
+
taskData,
|
|
722
|
+
consultCallHeld: false,
|
|
723
|
+
uiControlConfig: {
|
|
724
|
+
...baseContext.uiControlConfig,
|
|
725
|
+
voiceVariant: VOICE_VARIANT.WEBRTC,
|
|
726
|
+
},
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, context.taskData);
|
|
730
|
+
|
|
731
|
+
expect(uiControls.activeLeg).toBe('consult');
|
|
732
|
+
expect(uiControls.main.mute).toEqual({isVisible: true, isEnabled: false});
|
|
733
|
+
expect(uiControls.consult.mute).toEqual({isVisible: true, isEnabled: true});
|
|
117
734
|
});
|
|
118
735
|
|
|
119
736
|
it('hides transfer for the consulted agent during consult', () => {
|
|
@@ -135,6 +752,46 @@ describe('uiControlsComputer consult initiator controls', () => {
|
|
|
135
752
|
expect(uiControls.consult.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
136
753
|
});
|
|
137
754
|
|
|
755
|
+
it('hides main-leg controls for consulted agent when payload isConsulted is stale false', () => {
|
|
756
|
+
const taskData = createConsultedAgentInconsistentTaskData();
|
|
757
|
+
const baseContext = createVoiceContext();
|
|
758
|
+
const consultedContext = createVoiceContext({
|
|
759
|
+
consultInitiator: false,
|
|
760
|
+
taskData,
|
|
761
|
+
uiControlConfig: {
|
|
762
|
+
...baseContext.uiControlConfig,
|
|
763
|
+
agentId: 'agent-2',
|
|
764
|
+
},
|
|
765
|
+
});
|
|
766
|
+
|
|
767
|
+
const uiControls = computeUIControls(TaskState.CONNECTED, consultedContext, taskData);
|
|
768
|
+
|
|
769
|
+
expect(uiControls.main.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
770
|
+
expect(uiControls.main.end).toEqual({isVisible: false, isEnabled: false});
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
it('keeps consult-ring controls disabled except endConsult during hydrate pending state', () => {
|
|
774
|
+
const pendingTaskData = createPendingConsultHydrateTaskData();
|
|
775
|
+
const context = createVoiceContext({
|
|
776
|
+
taskData: pendingTaskData as any,
|
|
777
|
+
consultInitiator: false,
|
|
778
|
+
consultFromConference: false,
|
|
779
|
+
consultDestinationAgentJoined: false,
|
|
780
|
+
consultCallHeld: false,
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, pendingTaskData as any);
|
|
784
|
+
|
|
785
|
+
expect(uiControls.main.transfer).toEqual({isVisible: true, isEnabled: false});
|
|
786
|
+
expect(uiControls.main.conference).toEqual({isVisible: true, isEnabled: false});
|
|
787
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: false});
|
|
788
|
+
|
|
789
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: true, isEnabled: false});
|
|
790
|
+
expect(uiControls.consult.switch).toEqual({isVisible: true, isEnabled: false});
|
|
791
|
+
expect(uiControls.consult.mergeToConference).toEqual({isVisible: true, isEnabled: false});
|
|
792
|
+
expect(uiControls.consult.endConsult).toEqual({isVisible: true, isEnabled: true});
|
|
793
|
+
});
|
|
794
|
+
|
|
138
795
|
it('collapses stale consult leg controls during wrapup', () => {
|
|
139
796
|
const context = createVoiceContext();
|
|
140
797
|
|
|
@@ -144,6 +801,342 @@ describe('uiControlsComputer consult initiator controls', () => {
|
|
|
144
801
|
expect(uiControls.main.wrapup).toEqual({isVisible: true, isEnabled: true});
|
|
145
802
|
expect(uiControls.consult).toEqual(getDefaultUIControls().consult);
|
|
146
803
|
});
|
|
804
|
+
|
|
805
|
+
it('disables consult for non-initiators when another agent has active consult', () => {
|
|
806
|
+
const taskData = createConferenceWithOtherAgentConsultPendingTaskData();
|
|
807
|
+
const baseContext = createVoiceContext();
|
|
808
|
+
const context = createVoiceContext({
|
|
809
|
+
consultInitiator: false,
|
|
810
|
+
consultFromConference: false,
|
|
811
|
+
taskData,
|
|
812
|
+
uiControlConfig: {
|
|
813
|
+
...baseContext.uiControlConfig,
|
|
814
|
+
agentId: 'agent-2',
|
|
815
|
+
},
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
819
|
+
|
|
820
|
+
expect(uiControls.main.consult).toEqual({isVisible: true, isEnabled: false});
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
it('enables end and exitConference for non-initiators on held main leg while another agent consults', () => {
|
|
824
|
+
const taskData = createHeldConferenceWithActiveConsultTaskData();
|
|
825
|
+
const baseContext = createVoiceContext();
|
|
826
|
+
const context = createVoiceContext({
|
|
827
|
+
consultInitiator: false,
|
|
828
|
+
taskData,
|
|
829
|
+
uiControlConfig: {
|
|
830
|
+
...baseContext.uiControlConfig,
|
|
831
|
+
agentId: 'agent-2',
|
|
832
|
+
},
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
836
|
+
|
|
837
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: true});
|
|
838
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: true, isEnabled: true});
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
it('enables end and exitConference on held main leg when consultInitiator flag is stale true', () => {
|
|
842
|
+
const taskData = createHeldConferenceWithActiveConsultTaskData();
|
|
843
|
+
const baseContext = createVoiceContext();
|
|
844
|
+
const context = createVoiceContext({
|
|
845
|
+
consultInitiator: true,
|
|
846
|
+
taskData,
|
|
847
|
+
uiControlConfig: {
|
|
848
|
+
...baseContext.uiControlConfig,
|
|
849
|
+
agentId: 'agent-2',
|
|
850
|
+
},
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
854
|
+
|
|
855
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: true});
|
|
856
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: true, isEnabled: true});
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
it('enables end and exitConference on unheld main leg for non-initiator during active conference consult', () => {
|
|
860
|
+
const taskData = createUnheldConferenceWithActiveConsultTaskData();
|
|
861
|
+
const baseContext = createVoiceContext();
|
|
862
|
+
const context = createVoiceContext({
|
|
863
|
+
consultInitiator: false,
|
|
864
|
+
taskData,
|
|
865
|
+
uiControlConfig: {
|
|
866
|
+
...baseContext.uiControlConfig,
|
|
867
|
+
agentId: 'agent-2',
|
|
868
|
+
},
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
872
|
+
|
|
873
|
+
expect(uiControls.activeLeg).toBe('main');
|
|
874
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: true});
|
|
875
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: true, isEnabled: true});
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
it('keeps consult disabled for non-owner after owner consult completes in multi-agent conference', () => {
|
|
879
|
+
const taskData = createPostConsultCompletedMultiAgentTaskData('agent-2');
|
|
880
|
+
const baseContext = createVoiceContext();
|
|
881
|
+
const context = createVoiceContext({
|
|
882
|
+
consultInitiator: false,
|
|
883
|
+
taskData,
|
|
884
|
+
uiControlConfig: {
|
|
885
|
+
...baseContext.uiControlConfig,
|
|
886
|
+
agentId: 'agent-2',
|
|
887
|
+
},
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
891
|
+
|
|
892
|
+
expect(uiControls.main.consult).toEqual({isVisible: true, isEnabled: false});
|
|
893
|
+
});
|
|
894
|
+
|
|
895
|
+
it('keeps consult enabled for owner after consult completes in multi-agent conference', () => {
|
|
896
|
+
const taskData = createPostConsultCompletedMultiAgentTaskData('agent-1');
|
|
897
|
+
const baseContext = createVoiceContext();
|
|
898
|
+
const context = createVoiceContext({
|
|
899
|
+
consultInitiator: false,
|
|
900
|
+
taskData,
|
|
901
|
+
uiControlConfig: {
|
|
902
|
+
...baseContext.uiControlConfig,
|
|
903
|
+
agentId: 'agent-1',
|
|
904
|
+
},
|
|
905
|
+
});
|
|
906
|
+
|
|
907
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
908
|
+
|
|
909
|
+
expect(uiControls.main.consult).toEqual({isVisible: true, isEnabled: true});
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
it('hides transfer and enables transferConference on consult leg for conference initiator', () => {
|
|
913
|
+
const taskData = createConferenceConsultingInitiatorTaskData();
|
|
914
|
+
const baseContext = createVoiceContext();
|
|
915
|
+
const context = createVoiceContext({
|
|
916
|
+
consultInitiator: true,
|
|
917
|
+
consultFromConference: true,
|
|
918
|
+
consultDestinationAgentJoined: true,
|
|
919
|
+
consultCallHeld: false,
|
|
920
|
+
taskData,
|
|
921
|
+
uiControlConfig: {
|
|
922
|
+
...baseContext.uiControlConfig,
|
|
923
|
+
agentId: 'agent-1',
|
|
924
|
+
},
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, taskData);
|
|
928
|
+
|
|
929
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
930
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
931
|
+
expect(uiControls.main.transferConference).toEqual({isVisible: true, isEnabled: false});
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
it('keeps consult leg controls active and main leg conference controls disabled on hydrate-like context', () => {
|
|
935
|
+
const taskData = createConferenceConsultingInitiatorTaskData();
|
|
936
|
+
const baseContext = createVoiceContext();
|
|
937
|
+
const context = createVoiceContext({
|
|
938
|
+
consultInitiator: true,
|
|
939
|
+
consultFromConference: true,
|
|
940
|
+
consultDestinationAgentJoined: true,
|
|
941
|
+
consultCallHeld: false,
|
|
942
|
+
taskData,
|
|
943
|
+
uiControlConfig: {
|
|
944
|
+
...baseContext.uiControlConfig,
|
|
945
|
+
agentId: 'agent-1',
|
|
946
|
+
},
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, taskData);
|
|
950
|
+
|
|
951
|
+
expect(uiControls.activeLeg).toBe('consult');
|
|
952
|
+
expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: false});
|
|
953
|
+
expect(uiControls.main.conference).toEqual({isVisible: true, isEnabled: false});
|
|
954
|
+
expect(uiControls.main.transferConference).toEqual({isVisible: true, isEnabled: false});
|
|
955
|
+
expect(uiControls.consult.switch).toEqual({isVisible: true, isEnabled: true});
|
|
956
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
957
|
+
expect(uiControls.consult.mergeToConference).toEqual({isVisible: true, isEnabled: true});
|
|
958
|
+
expect(uiControls.consult.endConsult).toEqual({isVisible: true, isEnabled: true});
|
|
959
|
+
});
|
|
960
|
+
|
|
961
|
+
it('keeps transferConference visible on consult leg for initiator even when state is conferencing', () => {
|
|
962
|
+
const taskData = createConferenceConsultingInitiatorTaskData();
|
|
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: 'agent-1',
|
|
973
|
+
},
|
|
974
|
+
});
|
|
975
|
+
|
|
976
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
977
|
+
|
|
978
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
979
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
it('shows transferConference for initiator in AgentContactUnheld-style conference consult context', () => {
|
|
983
|
+
const taskData = createAgentContactUnheldInitiatorConsultTaskData();
|
|
984
|
+
const baseContext = createVoiceContext();
|
|
985
|
+
const context = createVoiceContext({
|
|
986
|
+
consultInitiator: true,
|
|
987
|
+
consultFromConference: false,
|
|
988
|
+
consultDestinationAgentJoined: true,
|
|
989
|
+
consultCallHeld: false,
|
|
990
|
+
taskData,
|
|
991
|
+
uiControlConfig: {
|
|
992
|
+
...baseContext.uiControlConfig,
|
|
993
|
+
agentId: 'agent-1',
|
|
994
|
+
},
|
|
995
|
+
});
|
|
996
|
+
|
|
997
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
998
|
+
|
|
999
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
1000
|
+
});
|
|
1001
|
+
|
|
1002
|
+
it('shows transferConference on main leg when initiator has active conference consult', () => {
|
|
1003
|
+
const taskData = createConferenceConsultingInitiatorTaskData();
|
|
1004
|
+
const baseContext = createVoiceContext();
|
|
1005
|
+
const context = createVoiceContext({
|
|
1006
|
+
consultInitiator: true,
|
|
1007
|
+
consultFromConference: true,
|
|
1008
|
+
consultDestinationAgentJoined: true,
|
|
1009
|
+
consultCallHeld: true,
|
|
1010
|
+
taskData,
|
|
1011
|
+
uiControlConfig: {
|
|
1012
|
+
...baseContext.uiControlConfig,
|
|
1013
|
+
agentId: 'agent-1',
|
|
1014
|
+
},
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
1018
|
+
|
|
1019
|
+
expect(uiControls.activeLeg).toBe('main');
|
|
1020
|
+
expect(uiControls.main.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
1021
|
+
expect(uiControls.main.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
1022
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: false});
|
|
1023
|
+
});
|
|
1024
|
+
|
|
1025
|
+
it('keeps transferConference visible on consult leg for taskData1-style payload', () => {
|
|
1026
|
+
const taskData = createTaskData1LikeConferenceConsultTaskData();
|
|
1027
|
+
const baseContext = createVoiceContext();
|
|
1028
|
+
const context = createVoiceContext({
|
|
1029
|
+
consultInitiator: true,
|
|
1030
|
+
consultFromConference: true,
|
|
1031
|
+
consultDestinationAgentJoined: true,
|
|
1032
|
+
consultCallHeld: false,
|
|
1033
|
+
taskData,
|
|
1034
|
+
uiControlConfig: {
|
|
1035
|
+
...baseContext.uiControlConfig,
|
|
1036
|
+
agentId: '058b3e7c-8fcf-45ee-b0c4-4ef546d360b9',
|
|
1037
|
+
},
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
1041
|
+
|
|
1042
|
+
expect(uiControls.activeLeg).toBe('consult');
|
|
1043
|
+
expect(uiControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
1044
|
+
expect(uiControls.consult.transfer).toEqual({isVisible: false, isEnabled: false});
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
it('enables transferConference after AgentConsulting follows AgentConsultCreated for initiator', () => {
|
|
1048
|
+
const baseContext = createVoiceContext();
|
|
1049
|
+
const createdTaskData = createConferenceConsultInitiatedInitiatorTaskData();
|
|
1050
|
+
const createdContext = createVoiceContext({
|
|
1051
|
+
consultInitiator: true,
|
|
1052
|
+
consultFromConference: true,
|
|
1053
|
+
consultDestinationAgentJoined: false,
|
|
1054
|
+
consultCallHeld: false,
|
|
1055
|
+
taskData: createdTaskData,
|
|
1056
|
+
uiControlConfig: {
|
|
1057
|
+
...baseContext.uiControlConfig,
|
|
1058
|
+
agentId: 'agent-1',
|
|
1059
|
+
},
|
|
1060
|
+
});
|
|
1061
|
+
const createdControls = computeUIControls(TaskState.CONSULTING, createdContext, createdTaskData);
|
|
1062
|
+
|
|
1063
|
+
expect(createdControls.consult.transferConference).toEqual({isVisible: true, isEnabled: false});
|
|
1064
|
+
|
|
1065
|
+
const consultingTaskData = createConferenceConsultingInitiatorTaskData();
|
|
1066
|
+
const consultingContext = createVoiceContext({
|
|
1067
|
+
...createdContext,
|
|
1068
|
+
taskData: consultingTaskData,
|
|
1069
|
+
consultDestinationAgentJoined: true,
|
|
1070
|
+
});
|
|
1071
|
+
const consultingControls = computeUIControls(
|
|
1072
|
+
TaskState.CONSULTING,
|
|
1073
|
+
consultingContext,
|
|
1074
|
+
consultingTaskData
|
|
1075
|
+
);
|
|
1076
|
+
|
|
1077
|
+
expect(consultingControls.consult.transferConference).toEqual({isVisible: true, isEnabled: true});
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
it('hides exitConference on main leg for consult initiator before destination joins', () => {
|
|
1081
|
+
const taskData = createConferenceConsultInitiatedInitiatorTaskData();
|
|
1082
|
+
const baseContext = createVoiceContext();
|
|
1083
|
+
const context = createVoiceContext({
|
|
1084
|
+
consultInitiator: true,
|
|
1085
|
+
consultFromConference: true,
|
|
1086
|
+
consultDestinationAgentJoined: false,
|
|
1087
|
+
consultCallHeld: false,
|
|
1088
|
+
taskData,
|
|
1089
|
+
uiControlConfig: {
|
|
1090
|
+
...baseContext.uiControlConfig,
|
|
1091
|
+
agentId: 'agent-1',
|
|
1092
|
+
},
|
|
1093
|
+
});
|
|
1094
|
+
|
|
1095
|
+
const uiControls = computeUIControls(TaskState.CONFERENCING, context, taskData);
|
|
1096
|
+
|
|
1097
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: false, isEnabled: false});
|
|
1098
|
+
});
|
|
1099
|
+
|
|
1100
|
+
it('hides exitConference on main leg while consulting and destination has not joined', () => {
|
|
1101
|
+
const taskData = createConferenceConsultInitiatedInitiatorTaskData();
|
|
1102
|
+
const baseContext = createVoiceContext();
|
|
1103
|
+
const context = createVoiceContext({
|
|
1104
|
+
consultInitiator: true,
|
|
1105
|
+
consultFromConference: true,
|
|
1106
|
+
consultDestinationAgentJoined: false,
|
|
1107
|
+
consultCallHeld: false,
|
|
1108
|
+
taskData,
|
|
1109
|
+
uiControlConfig: {
|
|
1110
|
+
...baseContext.uiControlConfig,
|
|
1111
|
+
agentId: 'agent-1',
|
|
1112
|
+
},
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, taskData);
|
|
1116
|
+
|
|
1117
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: false, isEnabled: false});
|
|
1118
|
+
});
|
|
1119
|
+
|
|
1120
|
+
it('hides exitConference on main leg for pending self consult even with stale initiator flags', () => {
|
|
1121
|
+
const taskData = createConferenceConsultInitiatedInitiatorTaskData();
|
|
1122
|
+
const baseContext = createVoiceContext();
|
|
1123
|
+
const context = createVoiceContext({
|
|
1124
|
+
consultInitiator: false,
|
|
1125
|
+
consultFromConference: false,
|
|
1126
|
+
consultDestinationAgentJoined: false,
|
|
1127
|
+
consultCallHeld: false,
|
|
1128
|
+
taskData,
|
|
1129
|
+
uiControlConfig: {
|
|
1130
|
+
...baseContext.uiControlConfig,
|
|
1131
|
+
agentId: 'agent-1',
|
|
1132
|
+
},
|
|
1133
|
+
});
|
|
1134
|
+
|
|
1135
|
+
const uiControls = computeUIControls(TaskState.CONSULTING, context, taskData);
|
|
1136
|
+
|
|
1137
|
+
expect(uiControls.main.exitConference).toEqual({isVisible: false, isEnabled: false});
|
|
1138
|
+
});
|
|
1139
|
+
|
|
147
1140
|
});
|
|
148
1141
|
|
|
149
1142
|
describe('uiControlsComputer outdial accept/decline controls', () => {
|