@webex/contact-center 3.12.0-next.15 → 3.12.0-next.151

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/.sdd/manifest.json +887 -0
  2. package/AGENTS.md +94 -0
  3. package/ai-docs/ARCHITECTURE.md +168 -0
  4. package/ai-docs/CONTRACTS.md +62 -0
  5. package/ai-docs/GETTING_STARTED.md +168 -0
  6. package/ai-docs/GLOSSARY.md +43 -0
  7. package/ai-docs/README.md +138 -0
  8. package/ai-docs/REVIEW_CHECKLIST.md +41 -0
  9. package/ai-docs/RULES.md +444 -0
  10. package/ai-docs/SECURITY.md +52 -0
  11. package/ai-docs/SERVICE_STATE.md +52 -0
  12. package/ai-docs/SPEC_INDEX.md +65 -0
  13. package/ai-docs/adr/0001-spec-source-policy.md +55 -0
  14. package/ai-docs/adr/README.md +8 -0
  15. package/ai-docs/adr/_adr-template.md +31 -0
  16. package/ai-docs/contact-center-spec.md +382 -0
  17. package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
  18. package/ai-docs/features/contact-owner-change-refactor.md +78 -0
  19. package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
  20. package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
  21. package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
  22. package/ai-docs/patterns/event-driven-patterns.md +485 -0
  23. package/ai-docs/patterns/testing-patterns.md +480 -0
  24. package/ai-docs/patterns/typescript-patterns.md +365 -0
  25. package/ai-docs/templates/README.md +102 -0
  26. package/ai-docs/templates/documentation/create-agents-md.md +240 -0
  27. package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
  28. package/ai-docs/templates/existing-service/bug-fix.md +254 -0
  29. package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
  30. package/ai-docs/templates/new-method/00-master.md +80 -0
  31. package/ai-docs/templates/new-method/01-requirements.md +232 -0
  32. package/ai-docs/templates/new-method/02-implementation.md +295 -0
  33. package/ai-docs/templates/new-method/03-tests.md +201 -0
  34. package/ai-docs/templates/new-method/04-validation.md +141 -0
  35. package/ai-docs/templates/new-service/00-master.md +109 -0
  36. package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
  37. package/ai-docs/templates/new-service/02-code-generation.md +346 -0
  38. package/ai-docs/templates/new-service/03-integration.md +178 -0
  39. package/ai-docs/templates/new-service/04-test-generation.md +205 -0
  40. package/ai-docs/templates/new-service/05-validation.md +145 -0
  41. package/dist/cc.js +1010 -47
  42. package/dist/cc.js.map +1 -1
  43. package/dist/config.js +13 -0
  44. package/dist/config.js.map +1 -1
  45. package/dist/constants.js +40 -3
  46. package/dist/constants.js.map +1 -1
  47. package/dist/index.js +54 -17
  48. package/dist/index.js.map +1 -1
  49. package/dist/metrics/MetricsManager.js +16 -0
  50. package/dist/metrics/MetricsManager.js.map +1 -1
  51. package/dist/metrics/behavioral-events.js +211 -0
  52. package/dist/metrics/behavioral-events.js.map +1 -1
  53. package/dist/metrics/constants.js +58 -4
  54. package/dist/metrics/constants.js.map +1 -1
  55. package/dist/services/AddressBook.js +18 -15
  56. package/dist/services/AddressBook.js.map +1 -1
  57. package/dist/services/AnswerCallOnWebexService.js +202 -0
  58. package/dist/services/AnswerCallOnWebexService.js.map +1 -0
  59. package/dist/services/ApiAiAssistant.js +351 -14
  60. package/dist/services/ApiAiAssistant.js.map +1 -1
  61. package/dist/services/EntryPoint.js +46 -68
  62. package/dist/services/EntryPoint.js.map +1 -1
  63. package/dist/services/Queue.js +27 -22
  64. package/dist/services/Queue.js.map +1 -1
  65. package/dist/services/UserPreference.js +427 -0
  66. package/dist/services/UserPreference.js.map +1 -0
  67. package/dist/services/WebexCrossClientService.js +225 -0
  68. package/dist/services/WebexCrossClientService.js.map +1 -0
  69. package/dist/services/WxAppTelephonyMercurySync.js +111 -0
  70. package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
  71. package/dist/services/config/Util.js +48 -48
  72. package/dist/services/config/Util.js.map +1 -1
  73. package/dist/services/config/constants.js +56 -78
  74. package/dist/services/config/constants.js.map +1 -1
  75. package/dist/services/config/index.js +100 -226
  76. package/dist/services/config/index.js.map +1 -1
  77. package/dist/services/config/types.js +97 -24
  78. package/dist/services/config/types.js.map +1 -1
  79. package/dist/services/core/Err.js.map +1 -1
  80. package/dist/services/core/Utils.js +111 -32
  81. package/dist/services/core/Utils.js.map +1 -1
  82. package/dist/services/core/WebexRequest.js +6 -2
  83. package/dist/services/core/WebexRequest.js.map +1 -1
  84. package/dist/services/core/aqm-reqs.js +28 -14
  85. package/dist/services/core/aqm-reqs.js.map +1 -1
  86. package/dist/services/core/types.js.map +1 -1
  87. package/dist/services/core/websocket/WebSocketManager.js +2 -1
  88. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  89. package/dist/services/core/websocket/types.js.map +1 -1
  90. package/dist/services/index.js +1 -1
  91. package/dist/services/index.js.map +1 -1
  92. package/dist/services/task/Task.js +955 -0
  93. package/dist/services/task/Task.js.map +1 -0
  94. package/dist/services/task/TaskFactory.js +50 -0
  95. package/dist/services/task/TaskFactory.js.map +1 -0
  96. package/dist/services/task/TaskManager.js +1272 -523
  97. package/dist/services/task/TaskManager.js.map +1 -1
  98. package/dist/services/task/TaskUtils.js +221 -27
  99. package/dist/services/task/TaskUtils.js.map +1 -1
  100. package/dist/services/task/WebexCallingUtils.js +70 -0
  101. package/dist/services/task/WebexCallingUtils.js.map +1 -0
  102. package/dist/services/task/constants.js +21 -2
  103. package/dist/services/task/constants.js.map +1 -1
  104. package/dist/services/task/contact.js +29 -0
  105. package/dist/services/task/contact.js.map +1 -1
  106. package/dist/services/task/dialer.js +78 -0
  107. package/dist/services/task/dialer.js.map +1 -1
  108. package/dist/services/task/digital/Digital.js +78 -0
  109. package/dist/services/task/digital/Digital.js.map +1 -0
  110. package/dist/services/task/state-machine/TaskStateMachine.js +982 -0
  111. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  112. package/dist/services/task/state-machine/actions.js +572 -0
  113. package/dist/services/task/state-machine/actions.js.map +1 -0
  114. package/dist/services/task/state-machine/constants.js +161 -0
  115. package/dist/services/task/state-machine/constants.js.map +1 -0
  116. package/dist/services/task/state-machine/guards.js +379 -0
  117. package/dist/services/task/state-machine/guards.js.map +1 -0
  118. package/dist/services/task/state-machine/index.js +53 -0
  119. package/dist/services/task/state-machine/index.js.map +1 -0
  120. package/dist/services/task/state-machine/types.js +54 -0
  121. package/dist/services/task/state-machine/types.js.map +1 -0
  122. package/dist/services/task/state-machine/uiControlsComputer.js +703 -0
  123. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  124. package/dist/services/task/taskDataNormalizer.js +99 -0
  125. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  126. package/dist/services/task/types.js +259 -5
  127. package/dist/services/task/types.js.map +1 -1
  128. package/dist/services/task/voice/Voice.js +1504 -0
  129. package/dist/services/task/voice/Voice.js.map +1 -0
  130. package/dist/services/task/voice/WebRTC.js +152 -0
  131. package/dist/services/task/voice/WebRTC.js.map +1 -0
  132. package/dist/services/task/voice/wxAppOfferObservability.js +145 -0
  133. package/dist/services/task/voice/wxAppOfferObservability.js.map +1 -0
  134. package/dist/services/task/voice/wxAppVoiceMethods.js +395 -0
  135. package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
  136. package/dist/services/wxAppDiagnosticLogging.js +159 -0
  137. package/dist/services/wxAppDiagnosticLogging.js.map +1 -0
  138. package/dist/services/wxAppTelephonyUtils.js +19 -0
  139. package/dist/services/wxAppTelephonyUtils.js.map +1 -0
  140. package/dist/types/cc.d.ts +196 -9
  141. package/dist/types/config.d.ts +13 -0
  142. package/dist/types/constants.d.ts +38 -1
  143. package/dist/types/index.d.ts +54 -20
  144. package/dist/types/metrics/MetricsManager.d.ts +6 -0
  145. package/dist/types/metrics/constants.d.ts +52 -1
  146. package/dist/types/services/AddressBook.d.ts +2 -1
  147. package/dist/types/services/AnswerCallOnWebexService.d.ts +38 -0
  148. package/dist/types/services/ApiAiAssistant.d.ts +58 -5
  149. package/dist/types/services/EntryPoint.d.ts +7 -5
  150. package/dist/types/services/Queue.d.ts +5 -3
  151. package/dist/types/services/UserPreference.d.ts +118 -0
  152. package/dist/types/services/WebexCrossClientService.d.ts +32 -0
  153. package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
  154. package/dist/types/services/config/Util.d.ts +4 -8
  155. package/dist/types/services/config/constants.d.ts +49 -76
  156. package/dist/types/services/config/index.d.ts +16 -64
  157. package/dist/types/services/config/types.d.ts +248 -114
  158. package/dist/types/services/core/Err.d.ts +6 -0
  159. package/dist/types/services/core/Utils.d.ts +35 -13
  160. package/dist/types/services/core/WebexRequest.d.ts +1 -0
  161. package/dist/types/services/core/types.d.ts +2 -0
  162. package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
  163. package/dist/types/services/core/websocket/types.d.ts +1 -1
  164. package/dist/types/services/index.d.ts +1 -1
  165. package/dist/types/services/task/Task.d.ts +186 -0
  166. package/dist/types/services/task/TaskFactory.d.ts +14 -0
  167. package/dist/types/services/task/TaskUtils.d.ts +54 -2
  168. package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
  169. package/dist/types/services/task/constants.d.ts +19 -0
  170. package/dist/types/services/task/contact.d.ts +4 -0
  171. package/dist/types/services/task/dialer.d.ts +30 -0
  172. package/dist/types/services/task/digital/Digital.d.ts +23 -0
  173. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1442 -0
  174. package/dist/types/services/task/state-machine/actions.d.ts +10 -0
  175. package/dist/types/services/task/state-machine/constants.d.ts +107 -0
  176. package/dist/types/services/task/state-machine/guards.d.ts +103 -0
  177. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  178. package/dist/types/services/task/state-machine/types.d.ts +277 -0
  179. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  180. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  181. package/dist/types/services/task/types.d.ts +790 -66
  182. package/dist/types/services/task/voice/Voice.d.ts +241 -0
  183. package/dist/types/services/task/voice/WebRTC.d.ts +54 -0
  184. package/dist/types/services/task/voice/wxAppOfferObservability.d.ts +39 -0
  185. package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +68 -0
  186. package/dist/types/services/wxAppDiagnosticLogging.d.ts +63 -0
  187. package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
  188. package/dist/types/types.d.ts +213 -11
  189. package/dist/types/utils/PageCache.d.ts +20 -3
  190. package/dist/types/webex.d.ts +1 -0
  191. package/dist/types.js +168 -6
  192. package/dist/types.js.map +1 -1
  193. package/dist/utils/PageCache.js +19 -5
  194. package/dist/utils/PageCache.js.map +1 -1
  195. package/dist/webex.js +22 -2
  196. package/dist/webex.js.map +1 -1
  197. package/package.json +16 -12
  198. package/src/cc.ts +1338 -121
  199. package/src/config.ts +13 -0
  200. package/src/constants.ts +41 -1
  201. package/src/index.ts +62 -15
  202. package/src/metrics/MetricsManager.ts +16 -0
  203. package/src/metrics/ai-docs/AGENTS.md +350 -0
  204. package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
  205. package/src/metrics/ai-docs/metrics-spec.md +971 -0
  206. package/src/metrics/behavioral-events.ts +218 -0
  207. package/src/metrics/constants.ts +63 -4
  208. package/src/services/AddressBook.ts +17 -6
  209. package/src/services/AnswerCallOnWebexService.ts +239 -0
  210. package/src/services/ApiAiAssistant.ts +470 -15
  211. package/src/services/EntryPoint.ts +59 -60
  212. package/src/services/Queue.ts +29 -12
  213. package/src/services/UserPreference.ts +509 -0
  214. package/src/services/WebexCrossClientService.ts +298 -0
  215. package/src/services/WxAppTelephonyMercurySync.ts +142 -0
  216. package/src/services/agent/ai-docs/AGENTS.md +240 -0
  217. package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
  218. package/src/services/agent/ai-docs/agent-spec.md +505 -0
  219. package/src/services/ai-docs/AGENTS.md +386 -0
  220. package/src/services/ai-docs/services-spec.md +505 -0
  221. package/src/services/config/Util.ts +54 -84
  222. package/src/services/config/ai-docs/AGENTS.md +250 -0
  223. package/src/services/config/ai-docs/ARCHITECTURE.md +413 -0
  224. package/src/services/config/ai-docs/config-spec.md +669 -0
  225. package/src/services/config/constants.ts +63 -85
  226. package/src/services/config/index.ts +116 -277
  227. package/src/services/config/types.ts +233 -125
  228. package/src/services/core/Err.ts +3 -0
  229. package/src/services/core/Utils.ts +127 -37
  230. package/src/services/core/WebexRequest.ts +3 -1
  231. package/src/services/core/ai-docs/AGENTS.md +381 -0
  232. package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
  233. package/src/services/core/ai-docs/core-spec.md +787 -0
  234. package/src/services/core/aqm-reqs.ts +30 -15
  235. package/src/services/core/types.ts +33 -1
  236. package/src/services/core/websocket/WebSocketManager.ts +2 -0
  237. package/src/services/core/websocket/types.ts +1 -1
  238. package/src/services/index.ts +1 -1
  239. package/src/services/task/Task.ts +1211 -0
  240. package/src/services/task/TaskFactory.ts +82 -0
  241. package/src/services/task/TaskManager.ts +1584 -643
  242. package/src/services/task/TaskUtils.ts +316 -25
  243. package/src/services/task/WebexCallingUtils.ts +136 -0
  244. package/src/services/task/ai-docs/AGENTS.md +457 -0
  245. package/src/services/task/ai-docs/ARCHITECTURE.md +595 -0
  246. package/src/services/task/ai-docs/task-spec.md +1501 -0
  247. package/src/services/task/constants.ts +20 -0
  248. package/src/services/task/contact.ts +30 -0
  249. package/src/services/task/dialer.ts +80 -0
  250. package/src/services/task/digital/Digital.ts +102 -0
  251. package/src/services/task/state-machine/TaskStateMachine.ts +1320 -0
  252. package/src/services/task/state-machine/actions.ts +741 -0
  253. package/src/services/task/state-machine/ai-docs/AGENTS.md +460 -0
  254. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1156 -0
  255. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2247 -0
  256. package/src/services/task/state-machine/constants.ts +172 -0
  257. package/src/services/task/state-machine/guards.ts +442 -0
  258. package/src/services/task/state-machine/index.ts +28 -0
  259. package/src/services/task/state-machine/types.ts +258 -0
  260. package/src/services/task/state-machine/uiControlsComputer.ts +1135 -0
  261. package/src/services/task/taskDataNormalizer.ts +137 -0
  262. package/src/services/task/types.ts +974 -70
  263. package/src/services/task/voice/Voice.ts +1878 -0
  264. package/src/services/task/voice/WebRTC.ts +194 -0
  265. package/src/services/task/voice/wxAppOfferObservability.ts +204 -0
  266. package/src/services/task/voice/wxAppVoiceMethods.ts +575 -0
  267. package/src/services/wxAppDiagnosticLogging.ts +286 -0
  268. package/src/services/wxAppTelephonyUtils.ts +14 -0
  269. package/src/types.ts +272 -13
  270. package/src/utils/AGENTS.md +289 -0
  271. package/src/utils/PageCache.ts +38 -5
  272. package/src/utils/ai-docs/utils-spec.md +391 -0
  273. package/src/webex.js +10 -0
  274. package/test/unit/fixtures/aiSummaryTestUtils.ts +40 -0
  275. package/test/unit/spec/cc.ts +3705 -150
  276. package/test/unit/spec/index.ts +885 -0
  277. package/test/unit/spec/logger-proxy.ts +70 -0
  278. package/test/unit/spec/metrics/MetricsManager.ts +25 -0
  279. package/test/unit/spec/metrics/behavioral-events.ts +60 -0
  280. package/test/unit/spec/services/AddressBook.ts +37 -6
  281. package/test/unit/spec/services/AnswerCallOnWebexService.ts +264 -0
  282. package/test/unit/spec/services/ApiAiAssistant.ts +429 -23
  283. package/test/unit/spec/services/EntryPoint.ts +87 -40
  284. package/test/unit/spec/services/Queue.ts +123 -12
  285. package/test/unit/spec/services/UserPreference.ts +401 -0
  286. package/test/unit/spec/services/WebCallingService.ts +7 -1
  287. package/test/unit/spec/services/WebexCrossClientService.ts +509 -0
  288. package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +136 -0
  289. package/test/unit/spec/services/config/Util.ts +501 -0
  290. package/test/unit/spec/services/config/index.ts +317 -547
  291. package/test/unit/spec/services/core/Utils.ts +425 -8
  292. package/test/unit/spec/services/core/WebexRequest.ts +8 -7
  293. package/test/unit/spec/services/core/aqm-reqs.ts +113 -1
  294. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +66 -40
  295. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  296. package/test/unit/spec/services/task/Task.ts +2723 -0
  297. package/test/unit/spec/services/task/TaskFactory.ts +116 -0
  298. package/test/unit/spec/services/task/TaskManager.ts +4781 -1585
  299. package/test/unit/spec/services/task/TaskUtils.ts +307 -0
  300. package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
  301. package/test/unit/spec/services/task/contact.ts +33 -0
  302. package/test/unit/spec/services/task/dialer.ts +190 -0
  303. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  304. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +4060 -0
  305. package/test/unit/spec/services/task/state-machine/guards.ts +839 -0
  306. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  307. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +3101 -0
  308. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  309. package/test/unit/spec/services/task/voice/Voice.ts +2355 -0
  310. package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
  311. package/test/unit/spec/services/task/voice/wxAppOfferObservability.ts +361 -0
  312. package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +719 -0
  313. package/test/unit/spec/services/wxAppDiagnosticLogging.ts +179 -0
  314. package/test/unit/spec/wellnessSampleUtils.ts +288 -0
  315. package/typedoc.md +1 -1
  316. package/umd/contact-center.min.js +2 -2
  317. package/umd/contact-center.min.js.map +1 -1
  318. package/dist/services/task/index.js +0 -1530
  319. package/dist/services/task/index.js.map +0 -1
  320. package/dist/types/services/task/index.d.ts +0 -650
  321. package/src/services/task/index.ts +0 -1806
  322. package/test/unit/spec/services/task/index.ts +0 -2205
@@ -239,5 +239,195 @@ describe('AQM routing dialer', () => {
239
239
  ).rejects.toThrow('Request Timeout');
240
240
  });
241
241
  });
242
+
243
+ describe('skipPreviewContact', () => {
244
+ it('should construct the correct URL with campaignId and interactionId', () => {
245
+ const dialer = aqmDialer(fakeAqm as any);
246
+ const config = dialer.skipPreviewContact({data: previewPayload}) as any;
247
+
248
+ expect(config.url).toBe(
249
+ `/v1/dialer/campaign/${previewPayload.campaignId}/preview-task/${previewPayload.interactionId}/skip`
250
+ );
251
+ });
252
+
253
+ it('should URL-encode campaignId when it contains reserved characters', () => {
254
+ const dialer = aqmDialer(fakeAqm as any);
255
+ const payloadWithSpecialChars = {
256
+ interactionId: 'interaction-456',
257
+ campaignId: 'My Campaign/Test #1',
258
+ };
259
+ const config = dialer.skipPreviewContact({data: payloadWithSpecialChars}) as any;
260
+
261
+ expect(config.url).toBe(
262
+ `/v1/dialer/campaign/${encodeURIComponent(
263
+ payloadWithSpecialChars.campaignId
264
+ )}/preview-task/${payloadWithSpecialChars.interactionId}/skip`
265
+ );
266
+ expect(config.url).toContain('My%20Campaign%2FTest%20%231');
267
+ });
268
+
269
+ it('should call the skipPreviewContact api', () => {
270
+ const fakeAqm = {
271
+ req: () =>
272
+ jest.fn().mockResolvedValue(() => {
273
+ Promise.resolve({data: 'skip preview success'});
274
+ }),
275
+ evt: jest.fn(),
276
+ };
277
+
278
+ const dialer = aqmDialer(fakeAqm as any);
279
+
280
+ dialer
281
+ .skipPreviewContact({data: previewPayload})
282
+ .then((response) => {
283
+ expect(response.data).toBe('skip preview success');
284
+ })
285
+ .catch(() => {
286
+ expect(true).toBe(true);
287
+ });
288
+
289
+ expect(dialer.skipPreviewContact).toHaveBeenCalled();
290
+ });
291
+
292
+ it('should handle network errors', () => {
293
+ const fakeAqm = {
294
+ req: () => jest.fn().mockRejectedValue(new Error('Network Error')),
295
+ evt: jest.fn(),
296
+ };
297
+
298
+ const dialer = aqmDialer(fakeAqm as any);
299
+
300
+ return expect(
301
+ dialer.skipPreviewContact({
302
+ data: previewPayload,
303
+ })
304
+ ).rejects.toThrow('Network Error');
305
+ });
306
+
307
+ it('should handle server errors', () => {
308
+ const fakeAqm = {
309
+ req: () => jest.fn().mockRejectedValue(new Error('Server Error')),
310
+ evt: jest.fn(),
311
+ };
312
+
313
+ const dialer = aqmDialer(fakeAqm as any);
314
+
315
+ return expect(
316
+ dialer.skipPreviewContact({
317
+ data: previewPayload,
318
+ })
319
+ ).rejects.toThrow('Server Error');
320
+ });
321
+
322
+ it('should handle timeout scenarios', () => {
323
+ const fakeAqm = {
324
+ req: () => jest.fn().mockRejectedValue(new Error('Request Timeout')),
325
+ evt: jest.fn(),
326
+ };
327
+
328
+ const dialer = aqmDialer(fakeAqm as any);
329
+
330
+ return expect(
331
+ dialer.skipPreviewContact({
332
+ data: previewPayload,
333
+ })
334
+ ).rejects.toThrow('Request Timeout');
335
+ });
336
+ });
337
+
338
+ describe('removePreviewContact', () => {
339
+ it('should construct the correct URL with campaignId and interactionId', () => {
340
+ const dialer = aqmDialer(fakeAqm as any);
341
+ const config = dialer.removePreviewContact({data: previewPayload}) as any;
342
+
343
+ expect(config.url).toBe(
344
+ `/v1/dialer/campaign/${previewPayload.campaignId}/preview-task/${previewPayload.interactionId}/remove`
345
+ );
346
+ });
347
+
348
+ it('should URL-encode campaignId when it contains reserved characters', () => {
349
+ const dialer = aqmDialer(fakeAqm as any);
350
+ const payloadWithSpecialChars = {
351
+ interactionId: 'interaction-456',
352
+ campaignId: 'My Campaign/Test #1',
353
+ };
354
+ const config = dialer.removePreviewContact({data: payloadWithSpecialChars}) as any;
355
+
356
+ expect(config.url).toBe(
357
+ `/v1/dialer/campaign/${encodeURIComponent(
358
+ payloadWithSpecialChars.campaignId
359
+ )}/preview-task/${payloadWithSpecialChars.interactionId}/remove`
360
+ );
361
+ expect(config.url).toContain('My%20Campaign%2FTest%20%231');
362
+ });
363
+
364
+ it('should call the removePreviewContact api', () => {
365
+ const fakeAqm = {
366
+ req: () =>
367
+ jest.fn().mockResolvedValue(() => {
368
+ Promise.resolve({data: 'remove preview success'});
369
+ }),
370
+ evt: jest.fn(),
371
+ };
372
+
373
+ const dialer = aqmDialer(fakeAqm as any);
374
+
375
+ dialer
376
+ .removePreviewContact({data: previewPayload})
377
+ .then((response) => {
378
+ expect(response.data).toBe('remove preview success');
379
+ })
380
+ .catch(() => {
381
+ expect(true).toBe(true);
382
+ });
383
+
384
+ expect(dialer.removePreviewContact).toHaveBeenCalled();
385
+ });
386
+
387
+ it('should handle network errors', () => {
388
+ const fakeAqm = {
389
+ req: () => jest.fn().mockRejectedValue(new Error('Network Error')),
390
+ evt: jest.fn(),
391
+ };
392
+
393
+ const dialer = aqmDialer(fakeAqm as any);
394
+
395
+ return expect(
396
+ dialer.removePreviewContact({
397
+ data: previewPayload,
398
+ })
399
+ ).rejects.toThrow('Network Error');
400
+ });
401
+
402
+ it('should handle server errors', () => {
403
+ const fakeAqm = {
404
+ req: () => jest.fn().mockRejectedValue(new Error('Server Error')),
405
+ evt: jest.fn(),
406
+ };
407
+
408
+ const dialer = aqmDialer(fakeAqm as any);
409
+
410
+ return expect(
411
+ dialer.removePreviewContact({
412
+ data: previewPayload,
413
+ })
414
+ ).rejects.toThrow('Server Error');
415
+ });
416
+
417
+ it('should handle timeout scenarios', () => {
418
+ const fakeAqm = {
419
+ req: () => jest.fn().mockRejectedValue(new Error('Request Timeout')),
420
+ evt: jest.fn(),
421
+ };
422
+
423
+ const dialer = aqmDialer(fakeAqm as any);
424
+
425
+ return expect(
426
+ dialer.removePreviewContact({
427
+ data: previewPayload,
428
+ })
429
+ ).rejects.toThrow('Request Timeout');
430
+ });
431
+ });
242
432
  });
243
433
  });
@@ -0,0 +1,105 @@
1
+ import Digital from '../../../../../../src/services/task/digital/Digital';
2
+ import {MEDIA_CHANNEL, TaskData, TaskResponse} from '../../../../../../src/services/task/types';
3
+ import {TaskEvent, TaskEventPayload} from '../../../../../../src/services/task/state-machine';
4
+
5
+ jest.mock('../../../../../../src/services/core/WebexRequest', () => ({
6
+ __esModule: true,
7
+ default: {
8
+ getInstance: () => ({ uploadLogs: jest.fn() }),
9
+ },
10
+ }));
11
+
12
+ const sendStateEvents = (task: Digital, events: TaskEventPayload[]) => {
13
+ events.forEach((event) => {
14
+ if (!event) {
15
+ throw new Error('Task event payload is required');
16
+ }
17
+ task.stateMachineService?.send(event);
18
+ });
19
+ };
20
+
21
+ describe('Digital Task', () => {
22
+ const dummyData = {
23
+ interactionId: 'dig1',
24
+ interaction: {isTerminated: false, mediaType: MEDIA_CHANNEL.CHAT},
25
+ } as TaskData;
26
+ let dummyContact: { accept: jest.Mock<Promise<TaskResponse>> };
27
+
28
+ beforeEach(() => {
29
+ dummyContact = {
30
+ accept: jest.fn().mockResolvedValue({ status: 'ok' }),
31
+ };
32
+ });
33
+
34
+ it('accept() calls contact.accept with interactionId', async () => {
35
+ const task = new Digital(dummyContact, dummyData);
36
+ const res = await task.accept();
37
+ expect(dummyContact.accept).toHaveBeenCalledWith({ interactionId: 'dig1' });
38
+ expect(res).toEqual({ status: 'ok' });
39
+ });
40
+
41
+ it('accept() throws an error when contact.accept rejects', async () => {
42
+ const error = new Error('Error while performing accept');
43
+ (dummyContact.accept as jest.Mock).mockRejectedValue(error);
44
+ const task = new Digital(dummyContact, dummyData);
45
+ await expect(task.accept()).rejects.toThrow('Error while performing accept');
46
+ });
47
+
48
+ it('constructor shows accept when offered', () => {
49
+ const task = new Digital(dummyContact, dummyData);
50
+ sendStateEvents(task, [{type: TaskEvent.TASK_INCOMING, taskData: dummyData}]);
51
+ expect(task.uiControls.main.accept.isVisible).toBe(true);
52
+ expect(task.uiControls.main.accept.isEnabled).toBe(true);
53
+ });
54
+
55
+ describe('UI controls derived from state machine events', () => {
56
+ it('connected state shows transfer and end', () => {
57
+ const task = new Digital(dummyContact, dummyData);
58
+ sendStateEvents(task, [
59
+ {type: TaskEvent.TASK_INCOMING, taskData: dummyData},
60
+ {type: TaskEvent.ASSIGN, taskData: dummyData},
61
+ ]);
62
+ expect(task.uiControls.main.accept.isVisible).toBe(false);
63
+ expect(task.uiControls.main.transfer.isVisible).toBe(true);
64
+ expect(task.uiControls.main.end.isVisible).toBe(true);
65
+ expect(task.uiControls.main.wrapup.isVisible).toBe(false);
66
+ });
67
+
68
+ it('wrapup state hides transfer/end and shows wrapup button', () => {
69
+ const task = new Digital(dummyContact, dummyData);
70
+ sendStateEvents(task, [
71
+ {type: TaskEvent.TASK_INCOMING, taskData: dummyData},
72
+ {type: TaskEvent.ASSIGN, taskData: dummyData},
73
+ {type: TaskEvent.TASK_WRAPUP},
74
+ ]);
75
+ expect(task.uiControls.main.transfer.isVisible).toBe(false);
76
+ expect(task.uiControls.main.end.isVisible).toBe(false);
77
+ expect(task.uiControls.main.wrapup.isVisible).toBe(true);
78
+ });
79
+
80
+ it('terminated interaction toggles wrapup visibility even before END event', () => {
81
+ const task = new Digital(dummyContact, dummyData);
82
+ const terminatedData = {
83
+ ...dummyData,
84
+ interaction: {...(dummyData.interaction as any), isTerminated: true},
85
+ } as TaskData;
86
+ task.updateTaskData(terminatedData);
87
+ sendStateEvents(task, [
88
+ {type: TaskEvent.TASK_INCOMING, taskData: dummyData},
89
+ {type: TaskEvent.ASSIGN, taskData: terminatedData},
90
+ ]);
91
+ expect(task.uiControls.main.wrapup.isVisible).toBe(true);
92
+ });
93
+
94
+ it('rona hides accept controls', () => {
95
+ const task = new Digital(dummyContact, dummyData);
96
+ sendStateEvents(task, [
97
+ {type: TaskEvent.TASK_INCOMING, taskData: dummyData},
98
+ {type: TaskEvent.RONA},
99
+ ]);
100
+ expect(task.uiControls.main.accept.isVisible).toBe(false);
101
+ expect(task.uiControls.main.transfer.isVisible).toBe(false);
102
+ expect(task.uiControls.main.end.isVisible).toBe(false);
103
+ });
104
+ });
105
+ });