@webex/calling 3.11.0 → 3.12.0

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 (188) hide show
  1. package/dist/CallHistory/CallHistory.js +596 -0
  2. package/dist/CallHistory/CallHistory.js.map +1 -0
  3. package/dist/CallHistory/CallHistory.test.js +916 -0
  4. package/dist/CallHistory/CallHistory.test.js.map +1 -0
  5. package/dist/CallHistory/callHistoryFixtures.js +650 -0
  6. package/dist/CallHistory/callHistoryFixtures.js.map +1 -0
  7. package/dist/CallHistory/constants.js +38 -0
  8. package/dist/CallHistory/constants.js.map +1 -0
  9. package/dist/CallHistory/types.js +7 -0
  10. package/dist/CallHistory/types.js.map +1 -0
  11. package/dist/CallSettings/CallSettings.js +311 -0
  12. package/dist/CallSettings/CallSettings.js.map +1 -0
  13. package/dist/CallSettings/CallSettings.test.js +122 -0
  14. package/dist/CallSettings/CallSettings.test.js.map +1 -0
  15. package/dist/CallSettings/UcmBackendConnector.js +308 -0
  16. package/dist/CallSettings/UcmBackendConnector.js.map +1 -0
  17. package/dist/CallSettings/UcmBackendConnector.test.js +411 -0
  18. package/dist/CallSettings/UcmBackendConnector.test.js.map +1 -0
  19. package/dist/CallSettings/WxCallBackendConnector.js +597 -0
  20. package/dist/CallSettings/WxCallBackendConnector.js.map +1 -0
  21. package/dist/CallSettings/WxCallBackendConnector.test.js +904 -0
  22. package/dist/CallSettings/WxCallBackendConnector.test.js.map +1 -0
  23. package/dist/CallSettings/constants.js +31 -0
  24. package/dist/CallSettings/constants.js.map +1 -0
  25. package/dist/CallSettings/testFixtures.js +68 -0
  26. package/dist/CallSettings/testFixtures.js.map +1 -0
  27. package/dist/CallSettings/types.js +7 -0
  28. package/dist/CallSettings/types.js.map +1 -0
  29. package/dist/CallingClient/CallingClient.js +1119 -0
  30. package/dist/CallingClient/CallingClient.js.map +1 -0
  31. package/dist/CallingClient/CallingClient.test.js +1266 -0
  32. package/dist/CallingClient/CallingClient.test.js.map +1 -0
  33. package/dist/CallingClient/callRecordFixtures.js +101 -0
  34. package/dist/CallingClient/callRecordFixtures.js.map +1 -0
  35. package/dist/CallingClient/calling/CallerId/index.js +275 -0
  36. package/dist/CallingClient/calling/CallerId/index.js.map +1 -0
  37. package/dist/CallingClient/calling/CallerId/index.test.js +275 -0
  38. package/dist/CallingClient/calling/CallerId/index.test.js.map +1 -0
  39. package/dist/CallingClient/calling/CallerId/types.js +7 -0
  40. package/dist/CallingClient/calling/CallerId/types.js.map +1 -0
  41. package/dist/CallingClient/calling/call.js +3486 -0
  42. package/dist/CallingClient/calling/call.js.map +1 -0
  43. package/dist/CallingClient/calling/call.test.js +3612 -0
  44. package/dist/CallingClient/calling/call.test.js.map +1 -0
  45. package/dist/CallingClient/calling/callManager.js +460 -0
  46. package/dist/CallingClient/calling/callManager.js.map +1 -0
  47. package/dist/CallingClient/calling/callManager.test.js +741 -0
  48. package/dist/CallingClient/calling/callManager.test.js.map +1 -0
  49. package/dist/CallingClient/calling/index.js +30 -0
  50. package/dist/CallingClient/calling/index.js.map +1 -0
  51. package/dist/CallingClient/calling/types.js +74 -0
  52. package/dist/CallingClient/calling/types.js.map +1 -0
  53. package/dist/CallingClient/callingClientFixtures.js +143 -0
  54. package/dist/CallingClient/callingClientFixtures.js.map +1 -0
  55. package/dist/CallingClient/constants.js +243 -0
  56. package/dist/CallingClient/constants.js.map +1 -0
  57. package/dist/CallingClient/line/index.js +332 -0
  58. package/dist/CallingClient/line/index.js.map +1 -0
  59. package/dist/CallingClient/line/line.test.js +327 -0
  60. package/dist/CallingClient/line/line.test.js.map +1 -0
  61. package/dist/CallingClient/line/types.js +21 -0
  62. package/dist/CallingClient/line/types.js.map +1 -0
  63. package/dist/CallingClient/registration/index.js +19 -0
  64. package/dist/CallingClient/registration/index.js.map +1 -0
  65. package/dist/CallingClient/registration/register.js +1686 -0
  66. package/dist/CallingClient/registration/register.js.map +1 -0
  67. package/dist/CallingClient/registration/register.test.js +1885 -0
  68. package/dist/CallingClient/registration/register.test.js.map +1 -0
  69. package/dist/CallingClient/registration/registerFixtures.js +36 -0
  70. package/dist/CallingClient/registration/registerFixtures.js.map +1 -0
  71. package/dist/CallingClient/registration/types.js +7 -0
  72. package/dist/CallingClient/registration/types.js.map +1 -0
  73. package/dist/CallingClient/registration/webWorker.js +130 -0
  74. package/dist/CallingClient/registration/webWorker.js.map +1 -0
  75. package/dist/CallingClient/registration/webWorker.test.js +303 -0
  76. package/dist/CallingClient/registration/webWorker.test.js.map +1 -0
  77. package/dist/CallingClient/registration/webWorkerStr.js +15 -0
  78. package/dist/CallingClient/registration/webWorkerStr.js.map +1 -0
  79. package/dist/CallingClient/types.js +7 -0
  80. package/dist/CallingClient/types.js.map +1 -0
  81. package/dist/CallingClient/windowsChromiumIceWarmupUtils.js +142 -0
  82. package/dist/CallingClient/windowsChromiumIceWarmupUtils.js.map +1 -0
  83. package/dist/Contacts/ContactsClient.js +1206 -0
  84. package/dist/Contacts/ContactsClient.js.map +1 -0
  85. package/dist/Contacts/ContactsClient.test.js +1004 -0
  86. package/dist/Contacts/ContactsClient.test.js.map +1 -0
  87. package/dist/Contacts/constants.js +40 -0
  88. package/dist/Contacts/constants.js.map +1 -0
  89. package/dist/Contacts/contactFixtures.js +430 -0
  90. package/dist/Contacts/contactFixtures.js.map +1 -0
  91. package/dist/Contacts/types.js +43 -0
  92. package/dist/Contacts/types.js.map +1 -0
  93. package/dist/Errors/catalog/CallError.js +89 -0
  94. package/dist/Errors/catalog/CallError.js.map +1 -0
  95. package/dist/Errors/catalog/CallingDeviceError.js +83 -0
  96. package/dist/Errors/catalog/CallingDeviceError.js.map +1 -0
  97. package/dist/Errors/catalog/ExtendedError.js +42 -0
  98. package/dist/Errors/catalog/ExtendedError.js.map +1 -0
  99. package/dist/Errors/catalog/LineError.js +85 -0
  100. package/dist/Errors/catalog/LineError.js.map +1 -0
  101. package/dist/Errors/index.js +28 -0
  102. package/dist/Errors/index.js.map +1 -0
  103. package/dist/Errors/types.js +59 -0
  104. package/dist/Errors/types.js.map +1 -0
  105. package/dist/Events/impl/index.js +79 -0
  106. package/dist/Events/impl/index.js.map +1 -0
  107. package/dist/Events/types.js +107 -0
  108. package/dist/Events/types.js.map +1 -0
  109. package/dist/Logger/index.js +228 -0
  110. package/dist/Logger/index.js.map +1 -0
  111. package/dist/Logger/index.test.js +87 -0
  112. package/dist/Logger/index.test.js.map +1 -0
  113. package/dist/Logger/types.js +34 -0
  114. package/dist/Logger/types.js.map +1 -0
  115. package/dist/Metrics/index.js +534 -0
  116. package/dist/Metrics/index.js.map +1 -0
  117. package/dist/Metrics/index.test.js +463 -0
  118. package/dist/Metrics/index.test.js.map +1 -0
  119. package/dist/Metrics/types.js +64 -0
  120. package/dist/Metrics/types.js.map +1 -0
  121. package/dist/SDKConnector/index.js +102 -0
  122. package/dist/SDKConnector/index.js.map +1 -0
  123. package/dist/SDKConnector/index.test.js +9 -0
  124. package/dist/SDKConnector/index.test.js.map +1 -0
  125. package/dist/SDKConnector/types.js +7 -0
  126. package/dist/SDKConnector/types.js.map +1 -0
  127. package/dist/SDKConnector/utils.js +39 -0
  128. package/dist/SDKConnector/utils.js.map +1 -0
  129. package/dist/SDKConnector/utils.test.js +9 -0
  130. package/dist/SDKConnector/utils.test.js.map +1 -0
  131. package/dist/Voicemail/BroadworksBackendConnector.js +699 -0
  132. package/dist/Voicemail/BroadworksBackendConnector.js.map +1 -0
  133. package/dist/Voicemail/BroadworksBackendConnector.test.js +820 -0
  134. package/dist/Voicemail/BroadworksBackendConnector.test.js.map +1 -0
  135. package/dist/Voicemail/UcmBackendConnector.js +628 -0
  136. package/dist/Voicemail/UcmBackendConnector.js.map +1 -0
  137. package/dist/Voicemail/UcmBackendConnector.test.js +738 -0
  138. package/dist/Voicemail/UcmBackendConnector.test.js.map +1 -0
  139. package/dist/Voicemail/Voicemail.js +472 -0
  140. package/dist/Voicemail/Voicemail.js.map +1 -0
  141. package/dist/Voicemail/Voicemail.test.js +391 -0
  142. package/dist/Voicemail/Voicemail.test.js.map +1 -0
  143. package/dist/Voicemail/WxCallBackendConnector.js +657 -0
  144. package/dist/Voicemail/WxCallBackendConnector.js.map +1 -0
  145. package/dist/Voicemail/WxCallBackendConnector.test.js +1225 -0
  146. package/dist/Voicemail/WxCallBackendConnector.test.js.map +1 -0
  147. package/dist/Voicemail/constants.js +61 -0
  148. package/dist/Voicemail/constants.js.map +1 -0
  149. package/dist/Voicemail/types.js +7 -0
  150. package/dist/Voicemail/types.js.map +1 -0
  151. package/dist/Voicemail/voicemailFixture.js +524 -0
  152. package/dist/Voicemail/voicemailFixture.js.map +1 -0
  153. package/dist/api.js +157 -0
  154. package/dist/api.js.map +1 -0
  155. package/dist/common/Utils.js +1483 -0
  156. package/dist/common/Utils.js.map +1 -0
  157. package/dist/common/Utils.test.js +1989 -0
  158. package/dist/common/Utils.test.js.map +1 -0
  159. package/dist/common/constants.js +62 -0
  160. package/dist/common/constants.js.map +1 -0
  161. package/dist/common/index.js +19 -0
  162. package/dist/common/index.js.map +1 -0
  163. package/dist/common/testUtil.js +983 -0
  164. package/dist/common/testUtil.js.map +1 -0
  165. package/dist/common/types.js +75 -0
  166. package/dist/common/types.js.map +1 -0
  167. package/dist/index.js +321 -0
  168. package/dist/index.js.map +1 -0
  169. package/dist/module/CallHistory/CallHistory.js +28 -17
  170. package/dist/module/CallingClient/CallingClient.js +43 -1
  171. package/dist/module/CallingClient/calling/call.js +3 -2
  172. package/dist/module/CallingClient/constants.js +2 -0
  173. package/dist/module/CallingClient/registration/register.js +8 -0
  174. package/dist/types/CallHistory/CallHistory.d.ts.map +1 -1
  175. package/dist/types/CallingClient/CallingClient.d.ts +2 -1
  176. package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
  177. package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
  178. package/dist/types/CallingClient/constants.d.ts +2 -0
  179. package/dist/types/CallingClient/constants.d.ts.map +1 -1
  180. package/dist/types/CallingClient/registration/register.d.ts +2 -1
  181. package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
  182. package/dist/types/CallingClient/registration/types.d.ts +2 -1
  183. package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
  184. package/dist/types/CallingClient/types.d.ts +2 -1
  185. package/dist/types/CallingClient/types.d.ts.map +1 -1
  186. package/dist/types/common/types.d.ts +4 -0
  187. package/dist/types/common/types.d.ts.map +1 -1
  188. package/package.json +4 -4
@@ -0,0 +1,1989 @@
1
+ "use strict";
2
+
3
+ var _Object$keys = require("@babel/runtime-corejs2/core-js/object/keys");
4
+ var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
5
+ var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
6
+ var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
7
+ var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
8
+ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
9
+ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
10
+ var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
11
+ var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
12
+ var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
13
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
14
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
15
+ var _uuid = require("uuid");
16
+ var _calling = require("../CallingClient/calling");
17
+ var _Errors = require("../Errors");
18
+ var _testUtil = require("./testUtil");
19
+ var _types = require("./types");
20
+ var _Logger = _interopRequireDefault(require("../Logger"));
21
+ var _constants = require("../CallingClient/constants");
22
+ var _types2 = require("../Errors/types");
23
+ var _Utils = require("./Utils");
24
+ var _voicemailFixture = require("../Voicemail/voicemailFixture");
25
+ var _constants2 = require("./constants");
26
+ var _types3 = require("../Events/types");
27
+ var _SDKConnector = _interopRequireDefault(require("../SDKConnector"));
28
+ function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
29
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; } /* eslint-disable no-underscore-dangle */
30
+ // Mock uuid
31
+ jest.mock('uuid', function () {
32
+ return {
33
+ v4: jest.fn()
34
+ };
35
+ });
36
+ var mockUuid = _uuid.v4;
37
+ var mockSubmitRegistrationMetric = jest.fn();
38
+ var mockEmitterCb = jest.fn();
39
+ var mockRestoreCb = jest.fn();
40
+ var mock429RetryCb = jest.fn();
41
+ var webex = (0, _testUtil.getTestUtilsWebex)();
42
+ _SDKConnector.default.setWebex(webex);
43
+ webex.internal.metrics.submitClientMetrics = mockSubmitRegistrationMetric;
44
+ describe('Mobius service discovery tests', function () {
45
+ it('test filter mobius uris', function () {
46
+ var defaultMobiusUrl = 'https://mobius.webex.com/api/v1/calling/web';
47
+ var callingContext = '/calling/web/';
48
+ var discoveryResponse = (0, _testUtil.getMobiusDiscoveryResponse)();
49
+
50
+ // add a duplicate which will be filtered out
51
+ discoveryResponse.backup.uris.push(discoveryResponse.backup.uris[0]);
52
+ var filteredUris = (0, _Utils.filterMobiusUris)(discoveryResponse, defaultMobiusUrl);
53
+ expect(filteredUris.primary.length).toBe(1);
54
+ expect(filteredUris.backup.length).toBe(2);
55
+ expect(filteredUris.primary[0]).toBe(discoveryResponse.primary.uris[0] + callingContext);
56
+ expect(filteredUris.backup[0]).toBe(discoveryResponse.backup.uris[0] + callingContext);
57
+ expect(filteredUris.backup[1]).toBe(defaultMobiusUrl + callingContext);
58
+
59
+ /** Remove Uris and test if the defaultUrls is returned */
60
+ discoveryResponse.backup.uris = [];
61
+ discoveryResponse.primary.uris = [];
62
+ filteredUris = (0, _Utils.filterMobiusUris)(discoveryResponse, defaultMobiusUrl);
63
+ expect(filteredUris.primary.length).toBe(1);
64
+ expect(filteredUris.primary[0]).toBe(defaultMobiusUrl + callingContext);
65
+ expect(filteredUris.backup.length).toBe(0);
66
+ });
67
+ });
68
+ describe('Call Tests - keepalive (handleCallEstablished) cases', function () {
69
+ var logObj = {
70
+ file: _constants.CALL_FILE,
71
+ method: 'handleCallErrors'
72
+ };
73
+ var dummyCorrelationId = '8a67806f-fc4d-446b-a131-31e71ea5b010';
74
+ beforeEach(function () {
75
+ jest.clearAllMocks();
76
+ });
77
+ it('401 during keepalive emits token error and ends call', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
78
+ var emitted, retrySpy, payload, abort;
79
+ return _regenerator.default.wrap(function (_context) {
80
+ while (1) switch (_context.prev = _context.next) {
81
+ case 0:
82
+ emitted = false;
83
+ retrySpy = jest.fn();
84
+ payload = {
85
+ statusCode: 401,
86
+ headers: {
87
+ trackingid: 't'
88
+ },
89
+ body: {
90
+ device: {
91
+ deviceId: 'd'
92
+ },
93
+ errorCode: 0
94
+ }
95
+ };
96
+ _context.next = 1;
97
+ return (0, _Utils.handleCallErrors)(function () {
98
+ emitted = true;
99
+ }, _types2.ERROR_LAYER.CALL_CONTROL, retrySpy, dummyCorrelationId, payload, 'handleCallEstablished', logObj.file);
100
+ case 1:
101
+ abort = _context.sent;
102
+ expect(emitted).toBe(true);
103
+ expect(abort).toBe(true);
104
+ expect(retrySpy).not.toHaveBeenCalled();
105
+ case 2:
106
+ case "end":
107
+ return _context.stop();
108
+ }
109
+ }, _callee);
110
+ })));
111
+ it('403 during keepalive emits error and ends call', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
112
+ var emitted, retrySpy, payload, abort;
113
+ return _regenerator.default.wrap(function (_context2) {
114
+ while (1) switch (_context2.prev = _context2.next) {
115
+ case 0:
116
+ emitted = false;
117
+ retrySpy = jest.fn();
118
+ payload = {
119
+ statusCode: 403,
120
+ headers: {
121
+ trackingid: 't'
122
+ },
123
+ body: {
124
+ device: {
125
+ deviceId: 'd'
126
+ },
127
+ errorCode: 0
128
+ }
129
+ };
130
+ _context2.next = 1;
131
+ return (0, _Utils.handleCallErrors)(function () {
132
+ emitted = true;
133
+ }, _types2.ERROR_LAYER.CALL_CONTROL, retrySpy, dummyCorrelationId, payload, 'handleCallEstablished', logObj.file);
134
+ case 1:
135
+ abort = _context2.sent;
136
+ expect(emitted).toBe(true);
137
+ expect(abort).toBe(true);
138
+ expect(retrySpy).not.toHaveBeenCalled();
139
+ case 2:
140
+ case "end":
141
+ return _context2.stop();
142
+ }
143
+ }, _callee2);
144
+ })));
145
+ it('500 during keepalive with retry-after triggers retryCb with interval', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
146
+ var emitted, endSpy, retrySpy, payload;
147
+ return _regenerator.default.wrap(function (_context3) {
148
+ while (1) switch (_context3.prev = _context3.next) {
149
+ case 0:
150
+ emitted = false;
151
+ endSpy = jest.fn();
152
+ retrySpy = jest.fn();
153
+ payload = {
154
+ statusCode: 500,
155
+ headers: {
156
+ trackingid: 't',
157
+ 'retry-after': 2
158
+ },
159
+ body: {
160
+ device: {
161
+ deviceId: 'd'
162
+ },
163
+ errorCode: 0
164
+ }
165
+ };
166
+ _context3.next = 1;
167
+ return (0, _Utils.handleCallErrors)(function () {
168
+ emitted = true;
169
+ }, _types2.ERROR_LAYER.CALL_CONTROL, retrySpy, dummyCorrelationId, payload, 'handleCallEstablished', logObj.file, endSpy);
170
+ case 1:
171
+ expect(emitted).toBe(true);
172
+ expect(endSpy).not.toHaveBeenCalled();
173
+ expect(retrySpy).toHaveBeenCalledWith(2);
174
+ case 2:
175
+ case "end":
176
+ return _context3.stop();
177
+ }
178
+ }, _callee3);
179
+ })));
180
+ it('500 during keepalive without retry-after triggers retryCb without args', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
181
+ var emitted, retrySpy, payload, abort;
182
+ return _regenerator.default.wrap(function (_context4) {
183
+ while (1) switch (_context4.prev = _context4.next) {
184
+ case 0:
185
+ emitted = false;
186
+ retrySpy = jest.fn();
187
+ payload = {
188
+ statusCode: 500,
189
+ headers: {
190
+ trackingid: 't'
191
+ },
192
+ body: {
193
+ device: {
194
+ deviceId: 'd'
195
+ },
196
+ errorCode: 0
197
+ }
198
+ };
199
+ _context4.next = 1;
200
+ return (0, _Utils.handleCallErrors)(function () {
201
+ emitted = true;
202
+ }, _types2.ERROR_LAYER.CALL_CONTROL, retrySpy, dummyCorrelationId, payload, 'handleCallEstablished', logObj.file);
203
+ case 1:
204
+ abort = _context4.sent;
205
+ expect(abort).toBe(false);
206
+ expect(emitted).toBe(true);
207
+ expect(retrySpy).toHaveBeenCalledWith(_constants.DEFAULT_KEEPALIVE_INTERVAL);
208
+ case 2:
209
+ case "end":
210
+ return _context4.stop();
211
+ }
212
+ }, _callee4);
213
+ })));
214
+ it('404 during keepalive emits not found and ends call (no retry)', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5() {
215
+ var emitted, retrySpy, payload, abort;
216
+ return _regenerator.default.wrap(function (_context5) {
217
+ while (1) switch (_context5.prev = _context5.next) {
218
+ case 0:
219
+ emitted = false;
220
+ retrySpy = jest.fn();
221
+ payload = {
222
+ statusCode: 404,
223
+ headers: {
224
+ trackingid: 't'
225
+ },
226
+ body: {
227
+ device: {
228
+ deviceId: 'd'
229
+ }
230
+ }
231
+ };
232
+ _context5.next = 1;
233
+ return (0, _Utils.handleCallErrors)(function () {
234
+ emitted = true;
235
+ }, _types2.ERROR_LAYER.CALL_CONTROL, retrySpy, dummyCorrelationId, payload, 'handleCallEstablished', logObj.file);
236
+ case 1:
237
+ abort = _context5.sent;
238
+ expect(emitted).toBe(true);
239
+ expect(abort).toBe(true);
240
+ expect(retrySpy).not.toHaveBeenCalled();
241
+ case 2:
242
+ case "end":
243
+ return _context5.stop();
244
+ }
245
+ }, _callee5);
246
+ })));
247
+ it('503 during keepalive with retry-after does not invoke emitterCb and retries with interval', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6() {
248
+ var emitted, retrySpy, payload, abort;
249
+ return _regenerator.default.wrap(function (_context6) {
250
+ while (1) switch (_context6.prev = _context6.next) {
251
+ case 0:
252
+ emitted = false;
253
+ retrySpy = jest.fn();
254
+ payload = {
255
+ statusCode: 503,
256
+ headers: {
257
+ trackingid: 't',
258
+ 'retry-after': 7
259
+ },
260
+ body: {
261
+ device: {
262
+ deviceId: 'd'
263
+ },
264
+ errorCode: 0
265
+ }
266
+ };
267
+ _context6.next = 1;
268
+ return (0, _Utils.handleCallErrors)(function () {
269
+ emitted = true;
270
+ }, _types2.ERROR_LAYER.CALL_CONTROL, retrySpy, dummyCorrelationId, payload, 'handleCallEstablished', logObj.file);
271
+ case 1:
272
+ abort = _context6.sent;
273
+ expect(abort).toBe(false);
274
+ expect(emitted).toBe(false);
275
+ expect(retrySpy).toHaveBeenCalledWith(7);
276
+ case 2:
277
+ case "end":
278
+ return _context6.stop();
279
+ }
280
+ }, _callee6);
281
+ })));
282
+ it('503 during keepalive without retry-after invokes emitterCb and triggers retryCb without args', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee7() {
283
+ var emitted, retrySpy, payload, abort;
284
+ return _regenerator.default.wrap(function (_context7) {
285
+ while (1) switch (_context7.prev = _context7.next) {
286
+ case 0:
287
+ emitted = false;
288
+ retrySpy = jest.fn();
289
+ payload = {
290
+ statusCode: 503,
291
+ headers: {
292
+ trackingid: 't'
293
+ },
294
+ body: {
295
+ device: {
296
+ deviceId: 'd'
297
+ },
298
+ errorCode: 111
299
+ }
300
+ };
301
+ _context7.next = 1;
302
+ return (0, _Utils.handleCallErrors)(function () {
303
+ emitted = true;
304
+ }, _types2.ERROR_LAYER.CALL_CONTROL, retrySpy, dummyCorrelationId, payload, 'handleCallEstablished', logObj.file);
305
+ case 1:
306
+ abort = _context7.sent;
307
+ expect(abort).toBe(false);
308
+ expect(emitted).toBe(true);
309
+ expect(retrySpy).toHaveBeenCalledWith(_constants.DEFAULT_KEEPALIVE_INTERVAL);
310
+ case 2:
311
+ case "end":
312
+ return _context7.stop();
313
+ }
314
+ }, _callee7);
315
+ })));
316
+ });
317
+ describe('Registration Tests', function () {
318
+ /**
319
+ * TestCase inputs
320
+ * name: TestCase name
321
+ * code: Response code of type ERROR_CODE
322
+ * bodyPresent: Indicates if response has a body
323
+ * subErrorCode: sub error code of type CALL_ERROR_CODE
324
+ * retryAfter: Indicates if retry-after header is present
325
+ * message: Custom message for the error context
326
+ * type: Error type based on the response code
327
+ * errorLayer: Call control or media layer
328
+ * cbExpected: Indicates if event emitter callback is expected
329
+ * logMsg: log message.
330
+ */
331
+ var errorCodes = [{
332
+ name: 'verify 429 error response',
333
+ statusCode: _types2.ERROR_CODE.TOO_MANY_REQUESTS,
334
+ deviceErrorCode: 0,
335
+ retryAfter: 30,
336
+ message: '',
337
+ errorType: _types2.ERROR_TYPE.REGISTRATION_ERROR,
338
+ emitterCbExpected: false,
339
+ finalError: false,
340
+ retry429CbExpected: true,
341
+ restoreCbExpected: false,
342
+ logMsg: '429 Too Many Requests'
343
+ }, {
344
+ name: 'verify 404 error response',
345
+ statusCode: _types2.ERROR_CODE.DEVICE_NOT_FOUND,
346
+ deviceErrorCode: 0,
347
+ message: 'Webex Calling is unable to find your device. Sign out, then sign back in',
348
+ errorType: _types2.ERROR_TYPE.NOT_FOUND,
349
+ emitterCbExpected: true,
350
+ finalError: true,
351
+ restoreCbExpected: false,
352
+ retry429CbExpected: false,
353
+ logMsg: '404 Device Not Found'
354
+ }, {
355
+ name: 'verify 500 error response',
356
+ statusCode: _types2.ERROR_CODE.INTERNAL_SERVER_ERROR,
357
+ deviceErrorCode: 0,
358
+ message: 'An unknown error occurred while placing the request. Wait a moment and try again.',
359
+ errorType: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
360
+ emitterCbExpected: true,
361
+ finalError: false,
362
+ restoreCbExpected: false,
363
+ retry429CbExpected: false,
364
+ logMsg: '500 Internal Server Error'
365
+ }, {
366
+ name: 'verify 503 error response',
367
+ statusCode: _types2.ERROR_CODE.SERVICE_UNAVAILABLE,
368
+ deviceErrorCode: 0,
369
+ message: 'An error occurred on the server while processing the request. Wait a moment and try again.',
370
+ errorType: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
371
+ emitterCbExpected: true,
372
+ finalError: false,
373
+ restoreCbExpected: false,
374
+ retry429CbExpected: false,
375
+ logMsg: '503 Service Unavailable'
376
+ }, {
377
+ name: 'verify 403 response with no response body',
378
+ statusCode: _types2.ERROR_CODE.FORBIDDEN,
379
+ deviceErrorCode: 0,
380
+ message: 'An unauthorized action has been received. This action has been blocked. Please contact the administrator if this persists.',
381
+ errorType: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
382
+ emitterCbExpected: true,
383
+ finalError: false,
384
+ restoreCbExpected: false,
385
+ retry429CbExpected: false,
386
+ logMsg: 'Error response has no body, throwing default error',
387
+ customBodyPresent: true,
388
+ body: undefined
389
+ }, {
390
+ name: 'verify 403 response with unknown device.errorCode',
391
+ statusCode: _types2.ERROR_CODE.FORBIDDEN,
392
+ deviceErrorCode: 0,
393
+ message: 'An unknown error occurred. Wait a moment and try again. Please contact the administrator if the problem persists.',
394
+ errorType: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
395
+ emitterCbExpected: true,
396
+ finalError: false,
397
+ restoreCbExpected: false,
398
+ retry429CbExpected: false,
399
+ logMsg: 'Error code found : 0'
400
+ }, {
401
+ name: 'verify 403 response with code 101',
402
+ statusCode: _types2.ERROR_CODE.FORBIDDEN,
403
+ deviceErrorCode: _types2.DEVICE_ERROR_CODE.DEVICE_LIMIT_EXCEEDED,
404
+ message: 'User device limit exceeded',
405
+ errorType: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
406
+ emitterCbExpected: false,
407
+ finalError: false,
408
+ restoreCbExpected: true,
409
+ retry429CbExpected: false,
410
+ logMsg: 'User device limit exceeded'
411
+ }, {
412
+ name: 'verify 403 response with code 102',
413
+ statusCode: _types2.ERROR_CODE.FORBIDDEN,
414
+ deviceErrorCode: _types2.DEVICE_ERROR_CODE.DEVICE_CREATION_DISABLED,
415
+ message: 'User is not configured for WebRTC calling. Please contact the administrator to resolve this issue.',
416
+ errorType: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
417
+ emitterCbExpected: true,
418
+ finalError: true,
419
+ restoreCbExpected: false,
420
+ retry429CbExpected: false,
421
+ logMsg: 'User is not configured for WebRTC calling. Please contact the administrator to resolve this issue.'
422
+ }, {
423
+ name: 'verify 403 response with code 103',
424
+ statusCode: _types2.ERROR_CODE.FORBIDDEN,
425
+ deviceErrorCode: _types2.DEVICE_ERROR_CODE.DEVICE_CREATION_FAILED,
426
+ message: 'An unknown error occurred while provisioning the device. Wait a moment and try again.',
427
+ errorType: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
428
+ emitterCbExpected: true,
429
+ finalError: false,
430
+ restoreCbExpected: false,
431
+ retry429CbExpected: false,
432
+ logMsg: 'An unknown error occurred while provisioning the device. Wait a moment and try again.'
433
+ }, {
434
+ name: 'verify 401 error response',
435
+ statusCode: _types2.ERROR_CODE.UNAUTHORIZED,
436
+ deviceErrorCode: 0,
437
+ message: 'User is unauthorized due to an expired token. Sign out, then sign back in.',
438
+ errorType: _types2.ERROR_TYPE.TOKEN_ERROR,
439
+ emitterCbExpected: true,
440
+ finalError: true,
441
+ restoreCbExpected: false,
442
+ retry429CbExpected: false,
443
+ logMsg: '401 Unauthorized'
444
+ }, {
445
+ name: 'verify 400 error response',
446
+ statusCode: _types2.ERROR_CODE.BAD_REQUEST,
447
+ deviceErrorCode: 0,
448
+ message: 'Invalid input. Please verify the required parameters, sign out and then sign back in with the valid data',
449
+ errorType: _types2.ERROR_TYPE.SERVER_ERROR,
450
+ emitterCbExpected: true,
451
+ finalError: true,
452
+ restoreCbExpected: false,
453
+ retry429CbExpected: false,
454
+ logMsg: '400 Bad Request'
455
+ }, {
456
+ name: 'verify unknown error response',
457
+ statusCode: 206,
458
+ deviceErrorCode: 0,
459
+ message: 'Unknown error',
460
+ errorType: _types2.ERROR_TYPE.DEFAULT,
461
+ emitterCbExpected: true,
462
+ finalError: false,
463
+ restoreCbExpected: false,
464
+ retry429CbExpected: false,
465
+ logMsg: 'Unknown Error'
466
+ }].map(function (stat) {
467
+ return (0, _assign.default)(stat, {
468
+ toString: function toString() {
469
+ return this.name;
470
+ }
471
+ });
472
+ });
473
+ var logSpy = jest.spyOn(_Logger.default, 'warn');
474
+ var logObj = {
475
+ file: 'CallingClient',
476
+ method: _constants.REGISTER_UTIL
477
+ };
478
+
479
+ /* eslint-disable @typescript-eslint/no-explicit-any */
480
+ it.each(errorCodes)('%s', function (codeObj) {
481
+ var webexPayload = {
482
+ statusCode: codeObj.statusCode,
483
+ headers: _objectSpread({
484
+ trackingid: 'webex-js-sdk_b5812e58-7246-4a9b-bf64-831bdf13b0cd_31'
485
+ }, codeObj.retryAfter && {
486
+ 'retry-after': codeObj.retryAfter.toString()
487
+ }),
488
+ body: {
489
+ device: {
490
+ deviceId: '8a67806f-fc4d-446b-a131-31e71ea5b010'
491
+ },
492
+ userId: '8a67806f-fc4d-446b-a131-31e71ea5b0e9',
493
+ errorCode: codeObj.deviceErrorCode,
494
+ devices: [{
495
+ deviceId: '8a67806f-fc4d-446b-a131-31e71ea5b010',
496
+ uri: 'https://mobius.webex.com/api/v1/calling/web/',
497
+ status: 'active',
498
+ lastSeen: '2022-04-07T18:00:40Z',
499
+ addresses: ['sip:sipAddress@webex.com']
500
+ }]
501
+ }
502
+ };
503
+ if (codeObj.customBodyPresent) {
504
+ webexPayload.body = codeObj.body;
505
+ }
506
+ var mockErrorEvent = {
507
+ type: codeObj.errorType,
508
+ message: codeObj.message,
509
+ context: logObj
510
+ };
511
+ var callClientError = new _Errors.CallingClientError(mockErrorEvent.message, mockErrorEvent.context, mockErrorEvent.type, _types.RegistrationStatus.ACTIVE);
512
+ (0, _Utils.handleRegistrationErrors)(webexPayload, mockEmitterCb, logObj, mock429RetryCb, mockRestoreCb);
513
+ if (codeObj.emitterCbExpected) {
514
+ expect(mockEmitterCb).toBeCalledOnceWith(callClientError, codeObj.finalError);
515
+ }
516
+ if (codeObj.restoreCbExpected) {
517
+ expect(mockRestoreCb).toBeCalledOnceWith(webexPayload.body, logObj.method);
518
+ } else {
519
+ expect(mockRestoreCb).not.toHaveBeenCalled();
520
+ }
521
+ if (codeObj.retry429CbExpected) {
522
+ expect(mock429RetryCb).toBeCalledOnceWith(codeObj.retryAfter, logObj.method);
523
+ } else {
524
+ expect(mock429RetryCb).not.toHaveBeenCalled();
525
+ }
526
+ expect(logSpy).toHaveBeenCalledWith("Status code: -> ".concat(codeObj.statusCode), logObj);
527
+ expect(logSpy).toHaveBeenCalledWith(codeObj.logMsg, logObj);
528
+ });
529
+ });
530
+ describe('CallingClient Error Tests', function () {
531
+ var logSpy = jest.spyOn(_Logger.default, 'warn');
532
+ var logObj = {
533
+ file: 'CallingClient',
534
+ method: 'handleCallingClientErrors'
535
+ };
536
+ beforeEach(function () {
537
+ jest.clearAllMocks();
538
+ });
539
+ it('verify 401 error response for calling client', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee8() {
540
+ var statusCode, message, errorType, finalError, webexPayload, mockErrorEvent, callClientError, result;
541
+ return _regenerator.default.wrap(function (_context8) {
542
+ while (1) switch (_context8.prev = _context8.next) {
543
+ case 0:
544
+ statusCode = _types2.ERROR_CODE.UNAUTHORIZED;
545
+ message = 'User is unauthorized due to an expired token.';
546
+ errorType = _types2.ERROR_TYPE.TOKEN_ERROR;
547
+ finalError = true;
548
+ webexPayload = {
549
+ statusCode: statusCode,
550
+ headers: {
551
+ trackingid: 'webex-js-sdk_b5812e58-7246-4a9b-bf64-831bdf13b0cd_31'
552
+ },
553
+ body: {
554
+ device: {
555
+ deviceId: '8a67806f-fc4d-446b-a131-31e71ea5b010'
556
+ },
557
+ userId: '8a67806f-fc4d-446b-a131-31e71ea5b0e9',
558
+ errorCode: 0
559
+ }
560
+ };
561
+ mockErrorEvent = {
562
+ type: errorType,
563
+ message: message,
564
+ context: logObj
565
+ };
566
+ callClientError = new _Errors.CallingClientError(mockErrorEvent.message, mockErrorEvent.context, mockErrorEvent.type, _types.RegistrationStatus.ACTIVE);
567
+ _context8.next = 1;
568
+ return (0, _Utils.handleCallingClientErrors)(webexPayload, mockEmitterCb, logObj);
569
+ case 1:
570
+ result = _context8.sent;
571
+ expect(mockEmitterCb).toHaveBeenCalledWith(callClientError, finalError);
572
+ expect(result).toBe(finalError);
573
+ expect(logSpy).toHaveBeenCalledWith("Status code: -> ".concat(statusCode), logObj);
574
+ expect(logSpy).toHaveBeenCalledWith('401 Unauthorized', logObj);
575
+ case 2:
576
+ case "end":
577
+ return _context8.stop();
578
+ }
579
+ }, _callee8);
580
+ })));
581
+ it('verify 500 error response for calling client', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee9() {
582
+ var statusCode, message, errorType, finalError, webexPayload, mockErrorEvent, callClientError, result;
583
+ return _regenerator.default.wrap(function (_context9) {
584
+ while (1) switch (_context9.prev = _context9.next) {
585
+ case 0:
586
+ statusCode = _types2.ERROR_CODE.INTERNAL_SERVER_ERROR;
587
+ message = 'An unknown error occurred while placing the request. Wait a moment and try again.';
588
+ errorType = _types2.ERROR_TYPE.SERVICE_UNAVAILABLE;
589
+ finalError = false;
590
+ webexPayload = {
591
+ statusCode: statusCode,
592
+ headers: {
593
+ trackingid: 'webex-js-sdk_b5812e58-7246-4a9b-bf64-831bdf13b0cd_31'
594
+ },
595
+ body: {
596
+ device: {
597
+ deviceId: '8a67806f-fc4d-446b-a131-31e71ea5b010'
598
+ },
599
+ userId: '8a67806f-fc4d-446b-a131-31e71ea5b0e9',
600
+ errorCode: 0
601
+ }
602
+ };
603
+ mockErrorEvent = {
604
+ type: errorType,
605
+ message: message,
606
+ context: logObj
607
+ };
608
+ callClientError = new _Errors.CallingClientError(mockErrorEvent.message, mockErrorEvent.context, mockErrorEvent.type, _types.RegistrationStatus.ACTIVE);
609
+ _context9.next = 1;
610
+ return (0, _Utils.handleCallingClientErrors)(webexPayload, mockEmitterCb, logObj);
611
+ case 1:
612
+ result = _context9.sent;
613
+ expect(mockEmitterCb).toHaveBeenCalledWith(callClientError, finalError);
614
+ expect(result).toBe(finalError);
615
+ expect(logSpy).toHaveBeenCalledWith("Status code: -> ".concat(statusCode), logObj);
616
+ expect(logSpy).toHaveBeenCalledWith('500 Internal Server Error', logObj);
617
+ case 2:
618
+ case "end":
619
+ return _context9.stop();
620
+ }
621
+ }, _callee9);
622
+ })));
623
+ it('verify unknown error response for calling client', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee0() {
624
+ var statusCode, message, errorType, finalError, webexPayload, mockErrorEvent, callClientError, result;
625
+ return _regenerator.default.wrap(function (_context0) {
626
+ while (1) switch (_context0.prev = _context0.next) {
627
+ case 0:
628
+ statusCode = 206;
629
+ message = 'Unknown error';
630
+ errorType = _types2.ERROR_TYPE.DEFAULT;
631
+ finalError = false;
632
+ webexPayload = {
633
+ statusCode: statusCode,
634
+ headers: {
635
+ trackingid: 'webex-js-sdk_b5812e58-7246-4a9b-bf64-831bdf13b0cd_31'
636
+ },
637
+ body: {
638
+ device: {
639
+ deviceId: '8a67806f-fc4d-446b-a131-31e71ea5b010'
640
+ },
641
+ userId: '8a67806f-fc4d-446b-a131-31e71ea5b0e9',
642
+ errorCode: 0
643
+ }
644
+ };
645
+ mockErrorEvent = {
646
+ type: errorType,
647
+ message: message,
648
+ context: logObj
649
+ };
650
+ callClientError = new _Errors.CallingClientError(mockErrorEvent.message, mockErrorEvent.context, mockErrorEvent.type, _types.RegistrationStatus.ACTIVE);
651
+ _context0.next = 1;
652
+ return (0, _Utils.handleCallingClientErrors)(webexPayload, mockEmitterCb, logObj);
653
+ case 1:
654
+ result = _context0.sent;
655
+ expect(mockEmitterCb).toHaveBeenCalledWith(callClientError, finalError);
656
+ expect(result).toBe(finalError);
657
+ expect(logSpy).toHaveBeenCalledWith("Status code: -> ".concat(statusCode), logObj);
658
+ expect(logSpy).toHaveBeenCalledWith('Unknown Error', logObj);
659
+ case 2:
660
+ case "end":
661
+ return _context0.stop();
662
+ }
663
+ }, _callee0);
664
+ })));
665
+ });
666
+ describe('Call Tests', function () {
667
+ /* Error flows tests starts */
668
+ var logSpy = jest.spyOn(_Logger.default, 'warn');
669
+ var logObj = {
670
+ file: _constants.CALL_FILE,
671
+ method: 'handleCallErrors'
672
+ };
673
+ var deviceId = '55dfb53f-bed2-36da-8e85-cee7f02aa68e';
674
+ var dest = {
675
+ type: _types.CallType.URI,
676
+ address: 'tel:5003'
677
+ };
678
+ var deleteCallFromCollection = jest.fn();
679
+ var retryCallback = jest.fn();
680
+ var activeUrl = 'FakeActiveUrl';
681
+ var defaultServiceIndicator = _types.ServiceIndicator.CALLING;
682
+ var call = new _calling.Call(activeUrl, webex, dest, _types.CallDirection.OUTBOUND, deviceId, deleteCallFromCollection, defaultServiceIndicator);
683
+ var dummyCorrelationId = '8a67806f-fc4d-446b-a131-31e71ea5b010';
684
+ beforeEach(function () {
685
+ jest.clearAllTimers();
686
+ jest.useFakeTimers();
687
+ call.removeAllListeners(_types3.CALL_EVENT_KEYS.CALL_ERROR);
688
+ });
689
+
690
+ /**
691
+ * TestCase inputs
692
+ * name: TestCase name
693
+ * code: Response code of type ERROR_CODE
694
+ * bodyPresent: Indicates if response has a body
695
+ * subErrorCode: sub error code of type CALL_ERROR_CODE
696
+ * retryAfter: Indicates if retry-after header is present
697
+ * message: Custom message for the error context
698
+ * type: Error type based on the response code
699
+ * errorLayer: Call control or media layer
700
+ * cbExpected: Indicates if event emitter callback is expected
701
+ * logMsg: log message.
702
+ */
703
+ var errorCodes = [/* 401 Unauthorized. */
704
+ {
705
+ name: 'verify 401 error response',
706
+ code: 401,
707
+ bodyPresent: true,
708
+ subErrorCode: 0,
709
+ retryAfter: 0,
710
+ message: 'User is unauthorized due to an expired token. Sign out, then sign back in.',
711
+ type: _types2.ERROR_TYPE.TOKEN_ERROR,
712
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
713
+ cbExpected: true,
714
+ logMsg: '401 Unauthorized'
715
+ }, /* 403 error code from here. */
716
+ // Without body
717
+ {
718
+ name: 'verify 403 error response without body',
719
+ code: 403,
720
+ bodyPresent: false,
721
+ subErrorCode: 0,
722
+ retryAfter: 0,
723
+ message: 'An unauthorized action has been received. This action has been blocked. Please contact the administrator if this persists.',
724
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
725
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
726
+ cbExpected: true,
727
+ logMsg: 'Error response has no body, throwing default error'
728
+ },
729
+ // error body with sub error code 111
730
+ {
731
+ name: 'verify 403 error response with code 111',
732
+ code: 403,
733
+ bodyPresent: true,
734
+ subErrorCode: _types2.CALL_ERROR_CODE.INVALID_STATUS_UPDATE,
735
+ retryAfter: 0,
736
+ message: 'An invalid status update has been received for the call. Wait a moment and try again.',
737
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
738
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
739
+ cbExpected: true,
740
+ logMsg: 'Status code: ->403'
741
+ },
742
+ // error body with sub error code 112
743
+ {
744
+ name: 'verify 403 error response with code 112',
745
+ code: 403,
746
+ bodyPresent: true,
747
+ subErrorCode: _types2.CALL_ERROR_CODE.DEVICE_NOT_REGISTERED,
748
+ retryAfter: 0,
749
+ message: 'The client has unregistered. Please wait for the client to register before attempting the call. If error persists, sign out, sign back in and attempt the call.',
750
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
751
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
752
+ cbExpected: true,
753
+ logMsg: 'Status code: ->403'
754
+ },
755
+ // error body with sub error code 113
756
+ {
757
+ name: 'verify 403 error response with code 113',
758
+ code: 403,
759
+ bodyPresent: true,
760
+ subErrorCode: _types2.CALL_ERROR_CODE.CALL_NOT_FOUND,
761
+ retryAfter: 0,
762
+ message: 'Call is not found on the server. Wait a moment and try again.',
763
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
764
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
765
+ cbExpected: true,
766
+ logMsg: 'Status code: ->403'
767
+ },
768
+ // error body with sub error code 114
769
+ {
770
+ name: 'verify 403 error response with code 114',
771
+ code: 403,
772
+ bodyPresent: true,
773
+ subErrorCode: _types2.CALL_ERROR_CODE.ERROR_PROCESSING,
774
+ retryAfter: 0,
775
+ message: 'An error occurred while processing the call on the server. Wait a moment and try again.',
776
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
777
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
778
+ cbExpected: true,
779
+ logMsg: 'Status code: ->403'
780
+ },
781
+ // error body with sub error code 115
782
+ {
783
+ name: 'verify 403 error response with code 115',
784
+ code: 403,
785
+ bodyPresent: true,
786
+ subErrorCode: _types2.CALL_ERROR_CODE.USER_BUSY,
787
+ retryAfter: 0,
788
+ message: 'Called user is busy.',
789
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
790
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
791
+ cbExpected: true,
792
+ logMsg: 'Status code: ->403'
793
+ },
794
+ // error body with sub error code 116
795
+ {
796
+ name: 'verify 403 error response with code 116',
797
+ code: 403,
798
+ bodyPresent: true,
799
+ subErrorCode: _types2.CALL_ERROR_CODE.PARSING_ERROR,
800
+ retryAfter: 0,
801
+ message: 'An error occurred while parsing the provided information. Wait a moment and try again.',
802
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
803
+ errorLayer: _types2.ERROR_LAYER.MEDIA,
804
+ cbExpected: true,
805
+ logMsg: 'Status code: ->403'
806
+ },
807
+ // error body with sub error code 118
808
+ {
809
+ name: 'verify 403 error response with code 118',
810
+ code: 403,
811
+ bodyPresent: true,
812
+ subErrorCode: _types2.CALL_ERROR_CODE.NOT_ACCEPTABLE,
813
+ retryAfter: 0,
814
+ message: 'An error occurred on the server while accepting the call. Wait a moment and try again. Please contact the administrator if this persists.',
815
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
816
+ errorLayer: _types2.ERROR_LAYER.MEDIA,
817
+ cbExpected: true,
818
+ logMsg: 'Status code: ->403'
819
+ },
820
+ // error body with sub error code 119
821
+ {
822
+ name: 'verify 403 error response with code 119',
823
+ code: 403,
824
+ bodyPresent: true,
825
+ subErrorCode: _types2.CALL_ERROR_CODE.CALL_REJECTED,
826
+ retryAfter: 0,
827
+ message: 'Call rejected by the server. Wait a moment and try again. Please contact the administrator if this persists.',
828
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
829
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
830
+ cbExpected: true,
831
+ logMsg: 'Status code: ->403'
832
+ },
833
+ // error body with sub error code 120
834
+ {
835
+ name: 'verify 403 error response with code 120',
836
+ code: 403,
837
+ bodyPresent: true,
838
+ subErrorCode: _types2.CALL_ERROR_CODE.NOT_AVAILABLE,
839
+ retryAfter: 0,
840
+ message: 'Calling services not available. Wait a moment and try again. Please contact the administrator if this persists.',
841
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
842
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
843
+ cbExpected: true,
844
+ logMsg: 'Status code: ->403'
845
+ },
846
+ // error body with unknown/unhandled sub error code
847
+ {
848
+ name: 'verify 403 error response with unknown error code',
849
+ code: 403,
850
+ bodyPresent: true,
851
+ subErrorCode: 999,
852
+ retryAfter: 0,
853
+ message: 'An unknown error occurred. Wait a moment and try again.',
854
+ type: _types2.ERROR_TYPE.FORBIDDEN_ERROR,
855
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
856
+ cbExpected: true,
857
+ logMsg: 'Status code: ->403'
858
+ }, /* 403 error code till here. */
859
+ /* 503 error code from here. */
860
+ // Without body
861
+ {
862
+ name: 'verify 503 error response without body',
863
+ code: 503,
864
+ bodyPresent: false,
865
+ subErrorCode: 0,
866
+ retryAfter: 0,
867
+ message: 'An error occurred on the server while processing the request. Wait a moment and try again.',
868
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
869
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
870
+ cbExpected: true,
871
+ logMsg: 'Error response has no body, throwing default error'
872
+ },
873
+ // error body with sub error code 111
874
+ {
875
+ name: 'verify 503 error response with code 111',
876
+ code: 503,
877
+ bodyPresent: true,
878
+ subErrorCode: _types2.CALL_ERROR_CODE.INVALID_STATUS_UPDATE,
879
+ retryAfter: 0,
880
+ message: 'An invalid status update has been received for the call. Wait a moment and try again.',
881
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
882
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
883
+ cbExpected: true,
884
+ logMsg: 'Status code: ->503'
885
+ },
886
+ // error body with sub error code 112
887
+ {
888
+ name: 'verify 503 error response with code 112',
889
+ code: 503,
890
+ bodyPresent: true,
891
+ subErrorCode: _types2.CALL_ERROR_CODE.DEVICE_NOT_REGISTERED,
892
+ retryAfter: 0,
893
+ message: 'The client has unregistered. Please wait for the client to register before attempting the call. If error persists, sign out, sign back in and attempt the call.',
894
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
895
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
896
+ cbExpected: true,
897
+ logMsg: 'Status code: ->503'
898
+ },
899
+ // error body with sub error code 113
900
+ {
901
+ name: 'verify 503 error response with code 113',
902
+ code: 503,
903
+ bodyPresent: true,
904
+ subErrorCode: _types2.CALL_ERROR_CODE.CALL_NOT_FOUND,
905
+ retryAfter: 0,
906
+ message: 'Call is not found on the server. Wait a moment and try again.',
907
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
908
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
909
+ cbExpected: true,
910
+ logMsg: 'Status code: ->503'
911
+ },
912
+ // error body with sub error code 114
913
+ {
914
+ name: 'verify 503 error response with code 114',
915
+ code: 503,
916
+ bodyPresent: true,
917
+ subErrorCode: _types2.CALL_ERROR_CODE.ERROR_PROCESSING,
918
+ retryAfter: 0,
919
+ message: 'An error occurred while processing the call on the server. Wait a moment and try again.',
920
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
921
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
922
+ cbExpected: true,
923
+ logMsg: 'Status code: ->503'
924
+ },
925
+ // error body with sub error code 115
926
+ {
927
+ name: 'verify 503 error response with code 115',
928
+ code: 503,
929
+ bodyPresent: true,
930
+ subErrorCode: _types2.CALL_ERROR_CODE.USER_BUSY,
931
+ retryAfter: 0,
932
+ message: 'Called user is busy.',
933
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
934
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
935
+ cbExpected: true,
936
+ logMsg: 'Status code: ->503'
937
+ },
938
+ // error body with sub error code 116
939
+ {
940
+ name: 'verify 503 error response with code 116',
941
+ code: 503,
942
+ bodyPresent: true,
943
+ subErrorCode: _types2.CALL_ERROR_CODE.PARSING_ERROR,
944
+ retryAfter: 0,
945
+ message: 'An error occurred while parsing the provided information. Wait a moment and try again.',
946
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
947
+ errorLayer: _types2.ERROR_LAYER.MEDIA,
948
+ cbExpected: true,
949
+ logMsg: 'Status code: ->503'
950
+ },
951
+ // error body with sub error code 118
952
+ {
953
+ name: 'verify 503 error response with code 118',
954
+ code: 503,
955
+ bodyPresent: true,
956
+ subErrorCode: _types2.CALL_ERROR_CODE.NOT_ACCEPTABLE,
957
+ retryAfter: 0,
958
+ message: 'An error occurred on the server while accepting the call. Wait a moment and try again. Please contact the administrator if this persists.',
959
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
960
+ errorLayer: _types2.ERROR_LAYER.MEDIA,
961
+ cbExpected: true,
962
+ logMsg: 'Status code: ->503'
963
+ },
964
+ // error body with sub error code 119
965
+ {
966
+ name: 'verify 503 error response with code 119',
967
+ code: 503,
968
+ bodyPresent: true,
969
+ subErrorCode: _types2.CALL_ERROR_CODE.CALL_REJECTED,
970
+ retryAfter: 0,
971
+ message: 'Call rejected by the server. Wait a moment and try again. Please contact the administrator if this persists.',
972
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
973
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
974
+ cbExpected: true,
975
+ logMsg: 'Status code: ->503'
976
+ },
977
+ // error body with sub error code 120
978
+ {
979
+ name: 'verify 503 error response with code 120',
980
+ code: 503,
981
+ bodyPresent: true,
982
+ subErrorCode: _types2.CALL_ERROR_CODE.NOT_AVAILABLE,
983
+ retryAfter: 0,
984
+ message: 'Calling services not available. Wait a moment and try again. Please contact the administrator if this persists.',
985
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
986
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
987
+ cbExpected: true,
988
+ logMsg: 'Status code: ->503'
989
+ },
990
+ // error body with unknown/unhandled sub error code
991
+ {
992
+ name: 'verify 503 error response with unknown error code',
993
+ code: 503,
994
+ bodyPresent: true,
995
+ subErrorCode: 999,
996
+ retryAfter: 0,
997
+ message: 'An unknown error occurred. Wait a moment and try again.',
998
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
999
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
1000
+ cbExpected: true,
1001
+ logMsg: 'Status code: ->503'
1002
+ },
1003
+ // with retry-after
1004
+ {
1005
+ name: 'verify 503 error response with retry-after',
1006
+ code: 503,
1007
+ bodyPresent: true,
1008
+ subErrorCode: 0,
1009
+ retryAfter: 60,
1010
+ message: 'An unknown error occurred. Wait a moment and try again.',
1011
+ type: _types2.ERROR_TYPE.SERVICE_UNAVAILABLE,
1012
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
1013
+ cbExpected: false,
1014
+ logMsg: 'Retry Interval received: 60'
1015
+ }, /* 503 error code till here. */
1016
+ /* 404 Not Found. */
1017
+ {
1018
+ name: 'verify 404 error response',
1019
+ code: 404,
1020
+ bodyPresent: true,
1021
+ subErrorCode: 0,
1022
+ retryAfter: 0,
1023
+ message: 'Call is no longer active. Wait a moment and try again.',
1024
+ type: _types2.ERROR_TYPE.NOT_FOUND,
1025
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
1026
+ cbExpected: true,
1027
+ logMsg: '404 Call Not Found'
1028
+ }, /* 500 Internal Server Error. */
1029
+ {
1030
+ name: 'verify 500 error response',
1031
+ code: 500,
1032
+ bodyPresent: true,
1033
+ subErrorCode: 0,
1034
+ retryAfter: 0,
1035
+ message: 'An unknown error occurred in the call. Wait a moment and try again.',
1036
+ type: _types2.ERROR_TYPE.SERVER_ERROR,
1037
+ errorLayer: _types2.ERROR_LAYER.MEDIA,
1038
+ cbExpected: true,
1039
+ logMsg: '500 Internal Server Error'
1040
+ }, /* Unknown error code. */
1041
+ {
1042
+ name: 'verify unknown error response',
1043
+ code: 0,
1044
+ bodyPresent: true,
1045
+ subErrorCode: 0,
1046
+ retryAfter: 0,
1047
+ message: 'An unknown error occurred in the call.',
1048
+ type: _types2.ERROR_TYPE.DEFAULT,
1049
+ errorLayer: _types2.ERROR_LAYER.CALL_CONTROL,
1050
+ cbExpected: true,
1051
+ logMsg: 'Unknown Error'
1052
+ }].map(function (stat) {
1053
+ return (0, _assign.default)(stat, {
1054
+ toString: function toString() {
1055
+ return this.name;
1056
+ }
1057
+ });
1058
+ });
1059
+
1060
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1061
+ it.each(errorCodes)('%s', function (codeObj, done) {
1062
+ var cbTriggered = false;
1063
+ var mockPayload = _objectSpread({
1064
+ statusCode: codeObj.code,
1065
+ headers: _objectSpread({
1066
+ trackingid: 'webex-js-sdk_b5812e58-7246-4a9b-bf64-831bdf13b0cd_31'
1067
+ }, codeObj.retryAfter && {
1068
+ 'retry-after': codeObj.retryAfter
1069
+ })
1070
+ }, codeObj.bodyPresent && {
1071
+ body: _objectSpread({
1072
+ device: {
1073
+ deviceId: '8a67806f-fc4d-446b-a131-31e71ea5b010'
1074
+ }
1075
+ }, codeObj.subErrorCode ? {
1076
+ errorCode: codeObj.subErrorCode
1077
+ } : {})
1078
+ });
1079
+ var mockErrorEvent = {
1080
+ type: codeObj.type,
1081
+ message: codeObj.message,
1082
+ context: logObj,
1083
+ correlationId: dummyCorrelationId,
1084
+ errorLayer: codeObj.errorLayer
1085
+ };
1086
+ if (codeObj.cbExpected) {
1087
+ call.on(_types3.CALL_EVENT_KEYS.CALL_ERROR, function (errObj) {
1088
+ expect(errObj).toMatchObject(mockErrorEvent);
1089
+ done();
1090
+ });
1091
+ } else {
1092
+ done();
1093
+ }
1094
+ (0, _Utils.handleCallErrors)(function (error) {
1095
+ call.emit(_types3.CALL_EVENT_KEYS.CALL_ERROR, error);
1096
+ cbTriggered = true;
1097
+ }, codeObj.errorLayer, retryCallback, dummyCorrelationId, mockPayload, logObj.method, logObj.file);
1098
+ expect(cbTriggered).toBe(codeObj.cbExpected);
1099
+ expect(logSpy).toBeCalledWith(codeObj.logMsg, logObj);
1100
+ if (codeObj.retryAfter) {
1101
+ expect(retryCallback).toBeCalledOnceWith(codeObj.retryAfter);
1102
+ } else {
1103
+ expect(retryCallback).not.toBeCalled();
1104
+ }
1105
+ });
1106
+ });
1107
+ describe('parseMediaQualityStatistics tests', function () {
1108
+ var logSpyObj = jest.spyOn(_Logger.default, 'log');
1109
+ var infoSpyObj = jest.spyOn(_Logger.default, 'info');
1110
+ var warnSpyObj = jest.spyOn(_Logger.default, 'warn');
1111
+ var logObj = {
1112
+ file: _constants.UTILS_FILE,
1113
+ method: _Utils.parseMediaQualityStatistics.name
1114
+ };
1115
+ var stats = (0, _testUtil.getSampleRawAndParsedMediaStats)();
1116
+ var statsWithVoOneWayDelayAndNw = stats.statsWithVoOneWayDelayAndNw;
1117
+ var statsWithoutVoOneWayDelayAndNw = stats.statsWithoutVoOneWayDelayAndNw;
1118
+
1119
+ /**
1120
+ * TestCase inputs
1121
+ * name: TestCase name
1122
+ * original: Original RTCStatsReport
1123
+ * parsed: Parsed stats in form of CallRtpStats
1124
+ * logSpy: SpyInstance on the log object
1125
+ * logMsg: Expected log message.
1126
+ */
1127
+ var mqStats = [{
1128
+ name: 'Valid stats with non-zero VoOneWayDelayMs and networkType vpn',
1129
+ original: statsWithVoOneWayDelayAndNw.raw,
1130
+ parsed: statsWithVoOneWayDelayAndNw.parsed,
1131
+ logSpy: logSpyObj,
1132
+ logMsg: (0, _stringify.default)(statsWithVoOneWayDelayAndNw.parsed)
1133
+ }, {
1134
+ name: 'Valid stats with zero VoOneWayDelayMs and undefined networkType',
1135
+ original: statsWithoutVoOneWayDelayAndNw.raw,
1136
+ parsed: statsWithoutVoOneWayDelayAndNw.parsed,
1137
+ logSpy: logSpyObj,
1138
+ logMsg: (0, _stringify.default)(statsWithoutVoOneWayDelayAndNw.parsed)
1139
+ }, {
1140
+ name: 'undefined stats passed to parse function',
1141
+ original: undefined,
1142
+ parsed: _constants.DUMMY_METRICS,
1143
+ logSpy: infoSpyObj,
1144
+ logMsg: 'RTCStatsReport is null, adding dummy stats'
1145
+ }, {
1146
+ name: 'invalid metrics passed when outbound call is disconnected before a connect',
1147
+ original: {
1148
+ size: 26
1149
+ },
1150
+ parsed: _constants.DUMMY_METRICS,
1151
+ logSpy: warnSpyObj,
1152
+ logMsg: 'Caught error while parsing RTP stats, TypeError: stats.forEach is not a function'
1153
+ }].map(function (stat) {
1154
+ return (0, _assign.default)(stat, {
1155
+ toString: function toString() {
1156
+ return this.name;
1157
+ }
1158
+ });
1159
+ });
1160
+ it.each(mqStats)('%s', function (stat) {
1161
+ var result = (0, _Utils.parseMediaQualityStatistics)(stat.original);
1162
+ expect(result).toStrictEqual(stat.parsed);
1163
+ expect(stat.logSpy).toBeCalledOnceWith(stat.logMsg, logObj);
1164
+ });
1165
+ });
1166
+ describe('Voicemail Sorting Tests', function () {
1167
+ /* Tests Voicemail sorting in ascending and descending orders */
1168
+
1169
+ it('verify VoiceMails sorting in Ascending order', function () {
1170
+ var voiceMailList = _voicemailFixture.getVoicemailListJsonWXC.body.VoiceMessagingMessages.messageInfoList.messageInfo;
1171
+ var sortedVoicemail = (0, _Utils.getSortedVoicemailList)(voiceMailList, _types.SORT.ASC);
1172
+ var voiceMailListAscOrder = _voicemailFixture.getAscVoicemailListJsonWXC.body.VoiceMessagingMessages.messageInfoList.messageInfo;
1173
+ expect(sortedVoicemail).toStrictEqual(voiceMailListAscOrder);
1174
+ });
1175
+ it('verify VoiceMails sorting in Descending Order', function () {
1176
+ var voiceMailList = _voicemailFixture.getVoicemailListJsonWXC.body.VoiceMessagingMessages.messageInfoList.messageInfo;
1177
+ var sortedVoicemail = (0, _Utils.getSortedVoicemailList)(voiceMailList, _types.SORT.DESC);
1178
+ var voiceMailListDescOrder = _voicemailFixture.getDescVoicemailListJsonWXC.body.VoiceMessagingMessages.messageInfoList.messageInfo;
1179
+ expect(sortedVoicemail).toStrictEqual(voiceMailListDescOrder);
1180
+ });
1181
+ });
1182
+ describe('resolveContact tests', function () {
1183
+ var scimUrl = "".concat(_constants2.WEBEX_API_BTS, "/").concat(_constants2.IDENTITY_ENDPOINT_RESOURCE, "/").concat(_constants2.SCIM_ENDPOINT_RESOURCE, "/").concat(webex.internal.device.orgId, "/").concat(_constants2.SCIM_USER_FILTER);
1184
+ it('Invalid CallingPartyInfo', function () {
1185
+ var callingPartyInfo = {};
1186
+ (0, _Utils.resolveContact)(callingPartyInfo).then(function (result) {
1187
+ expect(result).toBeNull();
1188
+ });
1189
+ });
1190
+ it('Resolve by userExternalId', function () {
1191
+ var callingPartyInfo = {};
1192
+ var webexSpy = jest.spyOn(webex, 'request').mockResolvedValue({
1193
+ statusCode: 200,
1194
+ body: (0, _testUtil.getSampleScimResponse)()
1195
+ });
1196
+ callingPartyInfo.userExternalId = {
1197
+ $: 'userExternalId'
1198
+ };
1199
+ (0, _Utils.resolveContact)(callingPartyInfo).then(function (displayInfo) {
1200
+ var _callingPartyInfo$use;
1201
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.name).toStrictEqual('Cathy');
1202
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.num).toStrictEqual('5008');
1203
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.avatarSrc).toStrictEqual((0, _testUtil.getSampleScimResponse)().Resources[0].photos[0].value);
1204
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.id).toStrictEqual((0, _testUtil.getSampleScimResponse)().Resources[0].id);
1205
+ var query = scimUrl + encodeURIComponent("id eq \"".concat((_callingPartyInfo$use = callingPartyInfo.userExternalId) === null || _callingPartyInfo$use === void 0 ? void 0 : _callingPartyInfo$use.$, "\""));
1206
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1207
+ uri: query
1208
+ }));
1209
+ });
1210
+ });
1211
+ it('Resolve by userExternalId - SCIM exception', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee1() {
1212
+ var _callingPartyInfo$use2;
1213
+ var callingPartyInfo, warnSpy, webexSpy, displayInfo, query;
1214
+ return _regenerator.default.wrap(function (_context1) {
1215
+ while (1) switch (_context1.prev = _context1.next) {
1216
+ case 0:
1217
+ callingPartyInfo = {};
1218
+ warnSpy = jest.spyOn(_Logger.default, 'warn');
1219
+ webexSpy = jest.spyOn(webex, 'request').mockRejectedValueOnce({
1220
+ statusCode: 500
1221
+ });
1222
+ callingPartyInfo.userExternalId = {
1223
+ $: 'userExternalId'
1224
+ };
1225
+ _context1.next = 1;
1226
+ return (0, _Utils.resolveContact)(callingPartyInfo);
1227
+ case 1:
1228
+ displayInfo = _context1.sent;
1229
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.name).toBeUndefined();
1230
+ expect(warnSpy).toHaveBeenCalledWith('Error response: - 500', {
1231
+ file: _constants.UTILS_FILE,
1232
+ method: 'resolveCallerIdDisplay'
1233
+ });
1234
+ query = scimUrl + encodeURIComponent("id eq \"".concat((_callingPartyInfo$use2 = callingPartyInfo.userExternalId) === null || _callingPartyInfo$use2 === void 0 ? void 0 : _callingPartyInfo$use2.$, "\""));
1235
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1236
+ uri: query
1237
+ }));
1238
+ case 2:
1239
+ case "end":
1240
+ return _context1.stop();
1241
+ }
1242
+ }, _callee1);
1243
+ })));
1244
+ it('Resolve by userExternalId - totalResults zero', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee10() {
1245
+ var _callingPartyInfo$use3;
1246
+ var callingPartyInfo, scimResponse, webexSpy, displayInfo, query;
1247
+ return _regenerator.default.wrap(function (_context10) {
1248
+ while (1) switch (_context10.prev = _context10.next) {
1249
+ case 0:
1250
+ callingPartyInfo = {};
1251
+ scimResponse = (0, _testUtil.getSampleScimResponse)();
1252
+ scimResponse.totalResults = '0';
1253
+ webexSpy = jest.spyOn(webex, 'request').mockResolvedValueOnce({
1254
+ statusCode: 200,
1255
+ body: scimResponse
1256
+ });
1257
+ callingPartyInfo.userExternalId = {
1258
+ $: 'userExternalId'
1259
+ };
1260
+ _context10.next = 1;
1261
+ return (0, _Utils.resolveContact)(callingPartyInfo);
1262
+ case 1:
1263
+ displayInfo = _context10.sent;
1264
+ query = scimUrl + encodeURIComponent("id eq \"".concat((_callingPartyInfo$use3 = callingPartyInfo.userExternalId) === null || _callingPartyInfo$use3 === void 0 ? void 0 : _callingPartyInfo$use3.$, "\""));
1265
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.name).toBeUndefined();
1266
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1267
+ uri: query
1268
+ }));
1269
+ scimResponse.totalResults = '1';
1270
+ case 2:
1271
+ case "end":
1272
+ return _context10.stop();
1273
+ }
1274
+ }, _callee10);
1275
+ })));
1276
+ it('Resolve by userExternalId - no primary number and no phone numbers', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee11() {
1277
+ var _callingPartyInfo$use4, _displayInfo, _displayInfo2;
1278
+ var callingPartyInfo, scimResponse, webexSpy, displayInfo, query, phoneNumbers;
1279
+ return _regenerator.default.wrap(function (_context11) {
1280
+ while (1) switch (_context11.prev = _context11.next) {
1281
+ case 0:
1282
+ callingPartyInfo = {};
1283
+ scimResponse = (0, _testUtil.getSampleScimResponse)();
1284
+ scimResponse.Resources[0].phoneNumbers[1].primary = false;
1285
+ webexSpy = jest.spyOn(webex, 'request').mockResolvedValueOnce({
1286
+ statusCode: 200,
1287
+ body: scimResponse
1288
+ });
1289
+ callingPartyInfo.userExternalId = {
1290
+ $: 'userExternalId'
1291
+ };
1292
+ _context11.next = 1;
1293
+ return (0, _Utils.resolveContact)(callingPartyInfo);
1294
+ case 1:
1295
+ displayInfo = _context11.sent;
1296
+ query = scimUrl + encodeURIComponent("id eq \"".concat((_callingPartyInfo$use4 = callingPartyInfo.userExternalId) === null || _callingPartyInfo$use4 === void 0 ? void 0 : _callingPartyInfo$use4.$, "\""));
1297
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1298
+ uri: query
1299
+ }));
1300
+ expect((_displayInfo = displayInfo) === null || _displayInfo === void 0 ? void 0 : _displayInfo.num).toStrictEqual('5008');
1301
+ webexSpy.mockReset();
1302
+ scimResponse.Resources[0].phoneNumbers[1].primary = true;
1303
+
1304
+ /* No phone numbers */
1305
+ phoneNumbers = scimResponse.Resources[0].phoneNumbers;
1306
+ scimResponse.Resources[0].phoneNumbers = [];
1307
+ webex.request.mockResolvedValueOnce({
1308
+ statusCode: 200,
1309
+ body: scimResponse
1310
+ });
1311
+ _context11.next = 2;
1312
+ return (0, _Utils.resolveContact)(callingPartyInfo);
1313
+ case 2:
1314
+ displayInfo = _context11.sent;
1315
+ expect((_displayInfo2 = displayInfo) === null || _displayInfo2 === void 0 ? void 0 : _displayInfo2.num).toBeUndefined();
1316
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1317
+ uri: query
1318
+ }));
1319
+ scimResponse.Resources[0].phoneNumbers = phoneNumbers;
1320
+ case 3:
1321
+ case "end":
1322
+ return _context11.stop();
1323
+ }
1324
+ }, _callee11);
1325
+ })));
1326
+ it('Resolve by userExternalId - no photo', function () {
1327
+ var callingPartyInfo = {};
1328
+ var scimResponse = (0, _testUtil.getSampleScimResponse)();
1329
+ scimResponse.Resources[0].photos = [];
1330
+ var webexSpy = jest.spyOn(webex, 'request').mockResolvedValue({
1331
+ statusCode: 200,
1332
+ body: scimResponse
1333
+ });
1334
+ callingPartyInfo.userExternalId = {
1335
+ $: 'userExternalId'
1336
+ };
1337
+ (0, _Utils.resolveContact)(callingPartyInfo).then(function (displayInfo) {
1338
+ var _callingPartyInfo$use5;
1339
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.name).toStrictEqual('Cathy');
1340
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.num).toStrictEqual('5008');
1341
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.avatarSrc).toStrictEqual('unknown');
1342
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.id).toStrictEqual((0, _testUtil.getSampleScimResponse)().Resources[0].id);
1343
+ var query = scimUrl + encodeURIComponent("id eq \"".concat((_callingPartyInfo$use5 = callingPartyInfo.userExternalId) === null || _callingPartyInfo$use5 === void 0 ? void 0 : _callingPartyInfo$use5.$, "\""));
1344
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1345
+ uri: query
1346
+ }));
1347
+ });
1348
+ });
1349
+ it('Resolve with minimal response from SCIM', function () {
1350
+ var callingPartyInfo = {};
1351
+ var scimResponse = (0, _testUtil.getSampleMinimumScimResponse)();
1352
+
1353
+ // scimResponse.Resources[0].photos = [];
1354
+ var webexSpy = jest.spyOn(webex, 'request').mockResolvedValue({
1355
+ statusCode: 200,
1356
+ body: scimResponse
1357
+ });
1358
+ callingPartyInfo.userExternalId = {
1359
+ $: 'userExternalId'
1360
+ };
1361
+ (0, _Utils.resolveContact)(callingPartyInfo).then(function (displayInfo) {
1362
+ var _callingPartyInfo$use6;
1363
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.name).toBeUndefined();
1364
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.num).toBeUndefined();
1365
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.avatarSrc).toStrictEqual('unknown');
1366
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.id).toStrictEqual((0, _testUtil.getSampleMinimumScimResponse)().Resources[0].id);
1367
+ var query = scimUrl + encodeURIComponent("id eq \"".concat((_callingPartyInfo$use6 = callingPartyInfo.userExternalId) === null || _callingPartyInfo$use6 === void 0 ? void 0 : _callingPartyInfo$use6.$, "\""));
1368
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1369
+ uri: query
1370
+ }));
1371
+ });
1372
+ });
1373
+ it('Resolve by name', function () {
1374
+ var callingPartyInfo = {};
1375
+ var webexSpy = jest.spyOn(webex.people, 'list').mockResolvedValue((0, _testUtil.getSamplePeopleListResponse)());
1376
+ callingPartyInfo.name = {
1377
+ $: 'Name'
1378
+ };
1379
+ (0, _Utils.resolveContact)(callingPartyInfo).then(function (displayInfo) {
1380
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.name).toStrictEqual((0, _testUtil.getSamplePeopleListResponse)().items[0].displayName);
1381
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.num).toStrictEqual((0, _testUtil.getSamplePeopleListResponse)().items[0].phoneNumbers[0].value);
1382
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.avatarSrc).toStrictEqual((0, _testUtil.getSamplePeopleListResponse)().items[0].avatar);
1383
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.id).toStrictEqual(Buffer.from((0, _testUtil.getSamplePeopleListResponse)().items[0].id, 'base64').toString('binary').split('/').pop());
1384
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1385
+ displayName: 'Name'
1386
+ }));
1387
+ });
1388
+ });
1389
+ it('Resolve by name - Empty Info', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee12() {
1390
+ var callingPartyInfo, peopleListResponse, items, webexSpy, displayInfo;
1391
+ return _regenerator.default.wrap(function (_context12) {
1392
+ while (1) switch (_context12.prev = _context12.next) {
1393
+ case 0:
1394
+ callingPartyInfo = {};
1395
+ peopleListResponse = (0, _testUtil.getSamplePeopleListResponse)();
1396
+ items = peopleListResponse.items;
1397
+ peopleListResponse.items = [];
1398
+ webexSpy = jest.spyOn(webex.people, 'list').mockResolvedValueOnce(peopleListResponse);
1399
+ callingPartyInfo.name = {
1400
+ $: 'Name'
1401
+ };
1402
+ _context12.next = 1;
1403
+ return (0, _Utils.resolveContact)(callingPartyInfo);
1404
+ case 1:
1405
+ displayInfo = _context12.sent;
1406
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.name).toBeUndefined();
1407
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1408
+ displayName: 'Name'
1409
+ }));
1410
+ peopleListResponse.items = items;
1411
+ case 2:
1412
+ case "end":
1413
+ return _context12.stop();
1414
+ }
1415
+ }, _callee12);
1416
+ })));
1417
+ it('Resolve by name - ID as plain UUID instead of part of URI', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee13() {
1418
+ var _displayInfo3, _displayInfo4, _displayInfo5, _displayInfo6, _displayInfo7, _displayInfo8;
1419
+ var callingPartyInfo, peopleListResponse, id, webexSpy, displayInfo;
1420
+ return _regenerator.default.wrap(function (_context13) {
1421
+ while (1) switch (_context13.prev = _context13.next) {
1422
+ case 0:
1423
+ callingPartyInfo = {};
1424
+ peopleListResponse = (0, _testUtil.getSamplePeopleListResponse)();
1425
+ id = peopleListResponse.items[0].id;
1426
+ /* Yjg1M2JiZDEtMTEzNi00ZDI1LTkzOGQtMGMzNzUzMWIxMjMz -> b853bbd1-1136-4d25-938d-0c37531b1233 */
1427
+ peopleListResponse.items[0].id = 'Yjg1M2JiZDEtMTEzNi00ZDI1LTkzOGQtMGMzNzUzMWIxMjMz';
1428
+ webexSpy = jest.spyOn(webex.people, 'list').mockResolvedValueOnce(peopleListResponse);
1429
+ callingPartyInfo.name = {
1430
+ $: 'Name'
1431
+ };
1432
+ _context13.next = 1;
1433
+ return (0, _Utils.resolveContact)(callingPartyInfo);
1434
+ case 1:
1435
+ displayInfo = _context13.sent;
1436
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1437
+ displayName: 'Name'
1438
+ }));
1439
+ expect((_displayInfo3 = displayInfo) === null || _displayInfo3 === void 0 ? void 0 : _displayInfo3.name).toStrictEqual(peopleListResponse.items[0].displayName);
1440
+ expect((_displayInfo4 = displayInfo) === null || _displayInfo4 === void 0 ? void 0 : _displayInfo4.num).toStrictEqual(peopleListResponse.items[0].phoneNumbers[0].value);
1441
+ expect((_displayInfo5 = displayInfo) === null || _displayInfo5 === void 0 ? void 0 : _displayInfo5.avatarSrc).toStrictEqual(peopleListResponse.items[0].avatar);
1442
+ expect((_displayInfo6 = displayInfo) === null || _displayInfo6 === void 0 ? void 0 : _displayInfo6.id).toStrictEqual(Buffer.from(peopleListResponse.items[0].id, 'base64').toString('binary').split('/').pop());
1443
+ webexSpy.mockReset();
1444
+
1445
+ /* Also test empty id */
1446
+ peopleListResponse.items[0].id = '';
1447
+ webex.people.list.mockResolvedValueOnce(peopleListResponse);
1448
+ _context13.next = 2;
1449
+ return (0, _Utils.resolveContact)(callingPartyInfo);
1450
+ case 2:
1451
+ displayInfo = _context13.sent;
1452
+ expect((_displayInfo7 = displayInfo) === null || _displayInfo7 === void 0 ? void 0 : _displayInfo7.id).toStrictEqual('');
1453
+ expect((_displayInfo8 = displayInfo) === null || _displayInfo8 === void 0 ? void 0 : _displayInfo8.name).toStrictEqual(peopleListResponse.items[0].displayName);
1454
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1455
+ displayName: 'Name'
1456
+ }));
1457
+ peopleListResponse.items[0].id = id;
1458
+ case 3:
1459
+ case "end":
1460
+ return _context13.stop();
1461
+ }
1462
+ }, _callee13);
1463
+ })));
1464
+ it('Resolve by name - Phone numbers no match for type - work', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee14() {
1465
+ var callingPartyInfo, peopleListResponse, phoneNumbers, webexSpy, displayInfo;
1466
+ return _regenerator.default.wrap(function (_context14) {
1467
+ while (1) switch (_context14.prev = _context14.next) {
1468
+ case 0:
1469
+ callingPartyInfo = {};
1470
+ peopleListResponse = (0, _testUtil.getSamplePeopleListResponse)();
1471
+ phoneNumbers = peopleListResponse.items[0].phoneNumbers;
1472
+ peopleListResponse.items[0].phoneNumbers[0].type = 'mobile';
1473
+ peopleListResponse.items[0].phoneNumbers[1].type = 'mobile';
1474
+ webexSpy = jest.spyOn(webex.people, 'list').mockResolvedValueOnce(peopleListResponse);
1475
+ callingPartyInfo.name = {
1476
+ $: 'Name'
1477
+ };
1478
+ _context14.next = 1;
1479
+ return (0, _Utils.resolveContact)(callingPartyInfo);
1480
+ case 1:
1481
+ displayInfo = _context14.sent;
1482
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.name).toStrictEqual(peopleListResponse.items[0].displayName);
1483
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.num).toStrictEqual(peopleListResponse.items[0].phoneNumbers[0].value);
1484
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.avatarSrc).toStrictEqual(peopleListResponse.items[0].avatar);
1485
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1486
+ displayName: 'Name'
1487
+ }));
1488
+ peopleListResponse.items[0].phoneNumbers = phoneNumbers;
1489
+ case 2:
1490
+ case "end":
1491
+ return _context14.stop();
1492
+ }
1493
+ }, _callee14);
1494
+ })));
1495
+ it('Resolve by name - Phone numbers empty', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee15() {
1496
+ var callingPartyInfo, peopleListResponse, phoneNumbers, webexSpy, displayInfo;
1497
+ return _regenerator.default.wrap(function (_context15) {
1498
+ while (1) switch (_context15.prev = _context15.next) {
1499
+ case 0:
1500
+ callingPartyInfo = {};
1501
+ peopleListResponse = (0, _testUtil.getSamplePeopleListResponse)();
1502
+ phoneNumbers = peopleListResponse.items[0].phoneNumbers;
1503
+ peopleListResponse.items[0].phoneNumbers = [];
1504
+ webexSpy = jest.spyOn(webex.people, 'list').mockResolvedValueOnce(peopleListResponse);
1505
+ callingPartyInfo.name = {
1506
+ $: 'Name'
1507
+ };
1508
+ _context15.next = 1;
1509
+ return (0, _Utils.resolveContact)(callingPartyInfo);
1510
+ case 1:
1511
+ displayInfo = _context15.sent;
1512
+ expect(webexSpy).toBeCalledOnceWith(expect.objectContaining({
1513
+ displayName: 'Name'
1514
+ }));
1515
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.name).toStrictEqual(peopleListResponse.items[0].displayName);
1516
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.num).toBeUndefined();
1517
+ expect(displayInfo === null || displayInfo === void 0 ? void 0 : displayInfo.avatarSrc).toStrictEqual(peopleListResponse.items[0].avatar);
1518
+ peopleListResponse.items[0].phoneNumbers = phoneNumbers;
1519
+ case 2:
1520
+ case "end":
1521
+ return _context15.stop();
1522
+ }
1523
+ }, _callee15);
1524
+ })));
1525
+ });
1526
+ describe('Store and Fetch voicemail tests', function () {
1527
+ /* Tests Voicemail pagination - storing voicemail list to and fetching from session storage */
1528
+ var dummyContext = 'dummy';
1529
+ var logContext = {
1530
+ file: 'voicemail',
1531
+ method: 'fetchVoicemail'
1532
+ };
1533
+ var getEncryptedVoicemail = function getEncryptedVoicemail(vmList) {
1534
+ return Buffer.from((0, _stringify.default)(vmList), 'utf8').toString('base64');
1535
+ };
1536
+ var getDecryptedVoicemail = function getDecryptedVoicemail() {
1537
+ var decryptedList = JSON.parse(Buffer.from(sessionStorage.getItem(dummyContext), 'base64').toString('utf8'));
1538
+ return decryptedList;
1539
+ };
1540
+ beforeAll(function () {
1541
+ // Mock storage
1542
+ var vmListStorage = {};
1543
+ global.Storage.prototype.setItem = jest.fn(function (key, value) {
1544
+ vmListStorage[key] = value;
1545
+ });
1546
+ global.Storage.prototype.getItem = jest.fn(function (key) {
1547
+ return vmListStorage[key];
1548
+ });
1549
+ });
1550
+ it('verify saving Voicemails in session storage', function () {
1551
+ var voicemailList = _voicemailFixture.getVoicemailListJsonWXC.body.VoiceMessagingMessages.messageInfoList.messageInfo;
1552
+ (0, _Utils.storeVoicemailList)(dummyContext, voicemailList);
1553
+ var voicemailFromSessionStorage = getDecryptedVoicemail();
1554
+ expect(global.sessionStorage.setItem).toHaveBeenCalledTimes(1);
1555
+ expect(voicemailFromSessionStorage).toEqual(voicemailList);
1556
+ });
1557
+ it('verify fetching all 5 voicemails from session storage', function () {
1558
+ var voicemailList = _voicemailFixture.getVoicemailListJsonWXC.body.VoiceMessagingMessages.messageInfoList.messageInfo;
1559
+ var encryptedVm = getEncryptedVoicemail(voicemailList);
1560
+ global.sessionStorage.setItem(dummyContext, encryptedVm.toString());
1561
+ var voicemailFromSessionStorage = (0, _Utils.fetchVoicemailList)(dummyContext, 0, 5, logContext);
1562
+ expect(global.Storage.prototype.getItem).toHaveBeenCalledTimes(1);
1563
+ expect(voicemailFromSessionStorage).toEqual({
1564
+ messages: voicemailList,
1565
+ moreVMAvailable: false
1566
+ });
1567
+ });
1568
+ it('verify fetching first 3 VoiceMails from session storage', function () {
1569
+ var voicemailList = _voicemailFixture.getVoicemailListJsonWXC.body.VoiceMessagingMessages.messageInfoList.messageInfo;
1570
+ var encryptedVm = getEncryptedVoicemail(voicemailList);
1571
+ global.sessionStorage.setItem(dummyContext, encryptedVm.toString());
1572
+ var voicemailFromSessionStorage = (0, _Utils.fetchVoicemailList)(dummyContext, 0, 3, logContext);
1573
+ expect(global.Storage.prototype.getItem).toHaveBeenCalledTimes(1);
1574
+ expect(voicemailFromSessionStorage).toEqual({
1575
+ messages: voicemailList.slice(0, 3),
1576
+ moreVMAvailable: true
1577
+ });
1578
+ });
1579
+ it('verify fetching 2nd and 3rd Voicemails from session storage', function () {
1580
+ var voicemailList = _voicemailFixture.getVoicemailListJsonWXC.body.VoiceMessagingMessages.messageInfoList.messageInfo;
1581
+ var encryptedVm = getEncryptedVoicemail(voicemailList);
1582
+ global.sessionStorage.setItem(dummyContext, encryptedVm.toString());
1583
+ var voicemailFromSessionStorage = (0, _Utils.fetchVoicemailList)(dummyContext, 1, 2, logContext);
1584
+ expect(global.Storage.prototype.getItem).toHaveBeenCalledTimes(1);
1585
+ expect(voicemailFromSessionStorage).toEqual({
1586
+ messages: voicemailList.slice(1, 3),
1587
+ moreVMAvailable: true
1588
+ });
1589
+ });
1590
+ it('verify fetch Voicemails with offset limit more than the available ones from session storage', function () {
1591
+ var voicemailList = [];
1592
+ var encryptedVm = getEncryptedVoicemail(voicemailList);
1593
+ global.sessionStorage.setItem(dummyContext, encryptedVm.toString());
1594
+ var voicemailFromSessionStorage = (0, _Utils.fetchVoicemailList)(dummyContext, 1, 5, logContext);
1595
+ expect(global.Storage.prototype.getItem).toHaveBeenCalledTimes(1);
1596
+ expect(voicemailFromSessionStorage).toEqual({
1597
+ messages: voicemailList.slice(1, 5),
1598
+ moreVMAvailable: false
1599
+ });
1600
+ });
1601
+ it('verify fetching Voicemails when it is []', function () {
1602
+ var voicemailFromSessionStorage = (0, _Utils.fetchVoicemailList)(dummyContext, 1, 5, logContext);
1603
+ expect(global.Storage.prototype.getItem).toHaveBeenCalledTimes(1);
1604
+ expect(voicemailFromSessionStorage).toEqual({
1605
+ messages: [],
1606
+ moreVMAvailable: false
1607
+ });
1608
+ });
1609
+ it('verify fetching Voicemails when there is exception', function () {
1610
+ var voiceMailList = '$%%ˆ';
1611
+ var logSpy = jest.spyOn(_Logger.default, 'warn');
1612
+ global.sessionStorage.setItem(dummyContext, voiceMailList);
1613
+ var voicemailFromSessionStorage = (0, _Utils.fetchVoicemailList)(dummyContext, 1, 5, logContext);
1614
+ expect(global.Storage.prototype.getItem).toBeCalledOnceWith('dummy');
1615
+ expect(logSpy).toHaveBeenCalledTimes(2);
1616
+ expect(logSpy).toHaveBeenCalledWith('Caught exception while fetching voicemail from storage. SyntaxError: Unexpected end of JSON input', logContext);
1617
+ expect(logSpy).toHaveBeenCalledWith('422 Exception has occurred', {});
1618
+ expect(voicemailFromSessionStorage).toEqual({
1619
+ messages: [],
1620
+ moreVMAvailable: false
1621
+ });
1622
+ });
1623
+ });
1624
+ describe('Infer id from UUID Tests', function () {
1625
+ /* Tests conversion of UUID to hydra Id */
1626
+
1627
+ it('verify encoding of userId to personId', function () {
1628
+ var uuidVal = '14533573-f6aa-429d-b4fe-58aa04a2b631';
1629
+ var hydraId = (0, _Utils.inferIdFromUuid)(uuidVal, _types.DecodeType.PEOPLE);
1630
+ var uuidAgain = Buffer.from(hydraId, 'base64').toString('binary');
1631
+ expect("".concat(_constants2.INFER_ID_CONSTANT, "/").concat(_types.DecodeType.PEOPLE, "/").concat(uuidVal)).toStrictEqual(uuidAgain);
1632
+ });
1633
+ it('verify encoding of orgId', function () {
1634
+ var orgId = '24533573-f6aa-429d-b4fe-58aa04a2b630';
1635
+ var encodedOrgId = (0, _Utils.inferIdFromUuid)(orgId, _types.DecodeType.ORGANIZATION);
1636
+ var orgIdAgain = Buffer.from(encodedOrgId, 'base64').toString('binary');
1637
+ expect("".concat(_constants2.INFER_ID_CONSTANT, "/").concat(_types.DecodeType.ORGANIZATION, "/").concat(orgId)).toStrictEqual(orgIdAgain);
1638
+ });
1639
+ });
1640
+ describe('Get endpoint by CALLING_BACKEND tests', function () {
1641
+ it('verify invalid calling backend ucm for xsi endpoint', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee16() {
1642
+ var _t;
1643
+ return _regenerator.default.wrap(function (_context16) {
1644
+ while (1) switch (_context16.prev = _context16.next) {
1645
+ case 0:
1646
+ _t = expect;
1647
+ _context16.next = 1;
1648
+ return (0, _Utils.getXsiActionEndpoint)(webex, {
1649
+ file: 'testFile',
1650
+ method: 'testMethod'
1651
+ }, _types.CALLING_BACKEND.UCM);
1652
+ case 1:
1653
+ _t(_context16.sent).toBeInstanceOf(Error);
1654
+ case 2:
1655
+ case "end":
1656
+ return _context16.stop();
1657
+ }
1658
+ }, _callee16);
1659
+ })));
1660
+ it('verify invalid calling backend wxc for vg endpoint', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee17() {
1661
+ var _t2;
1662
+ return _regenerator.default.wrap(function (_context17) {
1663
+ while (1) switch (_context17.prev = _context17.next) {
1664
+ case 0:
1665
+ _t2 = expect;
1666
+ _context17.next = 1;
1667
+ return (0, _Utils.getVgActionEndpoint)(webex, _types.CALLING_BACKEND.WXC);
1668
+ case 1:
1669
+ _t2(_context17.sent).toBeInstanceOf(Error);
1670
+ case 2:
1671
+ case "end":
1672
+ return _context17.stop();
1673
+ }
1674
+ }, _callee17);
1675
+ })));
1676
+ });
1677
+ describe('Get XSI Action Endpoint tests', function () {
1678
+ var mockWebex = {
1679
+ request: jest.fn(),
1680
+ internal: {
1681
+ services: {
1682
+ _serviceUrls: {
1683
+ wdm: 'https://fake-webex-url.com'
1684
+ }
1685
+ }
1686
+ }
1687
+ };
1688
+ var loggerContext = {
1689
+ file: 'testFile',
1690
+ method: 'testMethod'
1691
+ };
1692
+ it('should return xsiEndpoint for BWRKS backend when URL ends with /v2.0', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee18() {
1693
+ var mockResponse, xsiEndpoint;
1694
+ return _regenerator.default.wrap(function (_context18) {
1695
+ while (1) switch (_context18.prev = _context18.next) {
1696
+ case 0:
1697
+ mockResponse = {
1698
+ body: {
1699
+ devices: [{
1700
+ settings: {
1701
+ broadworksXsiActionsUrl: 'https://fake-broadworks-url.com/v2.0'
1702
+ }
1703
+ }]
1704
+ }
1705
+ };
1706
+ mockWebex.request.mockResolvedValue(mockResponse);
1707
+ _context18.next = 1;
1708
+ return (0, _Utils.getXsiActionEndpoint)(mockWebex, loggerContext, _types.CALLING_BACKEND.BWRKS);
1709
+ case 1:
1710
+ xsiEndpoint = _context18.sent;
1711
+ expect(mockWebex.request).toHaveBeenCalledTimes(1);
1712
+ expect(xsiEndpoint).toBe('https://fake-broadworks-url.com');
1713
+ case 2:
1714
+ case "end":
1715
+ return _context18.stop();
1716
+ }
1717
+ }, _callee18);
1718
+ })));
1719
+ it('should return xsiEndpoint for BWRKS backend when URL ends with /v2.0/', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee19() {
1720
+ var mockResponse, xsiEndpoint;
1721
+ return _regenerator.default.wrap(function (_context19) {
1722
+ while (1) switch (_context19.prev = _context19.next) {
1723
+ case 0:
1724
+ mockResponse = {
1725
+ body: {
1726
+ devices: [{
1727
+ settings: {
1728
+ broadworksXsiActionsUrl: 'https://fake-broadworks-url.com/v2.0/'
1729
+ }
1730
+ }]
1731
+ }
1732
+ };
1733
+ mockWebex.request.mockResolvedValue(mockResponse);
1734
+ _context19.next = 1;
1735
+ return (0, _Utils.getXsiActionEndpoint)(mockWebex, loggerContext, _types.CALLING_BACKEND.BWRKS);
1736
+ case 1:
1737
+ xsiEndpoint = _context19.sent;
1738
+ expect(mockWebex.request).toHaveBeenCalledTimes(1);
1739
+ expect(xsiEndpoint).toBe('https://fake-broadworks-url.com');
1740
+ case 2:
1741
+ case "end":
1742
+ return _context19.stop();
1743
+ }
1744
+ }, _callee19);
1745
+ })));
1746
+ it('should return xsiEndpoint for BWRKS backend when URL does not end with any version', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee20() {
1747
+ var mockResponse, xsiEndpoint;
1748
+ return _regenerator.default.wrap(function (_context20) {
1749
+ while (1) switch (_context20.prev = _context20.next) {
1750
+ case 0:
1751
+ mockResponse = {
1752
+ body: {
1753
+ devices: [{
1754
+ settings: {
1755
+ broadworksXsiActionsUrl: 'https://fake-broadworks-url.com'
1756
+ }
1757
+ }]
1758
+ }
1759
+ };
1760
+ mockWebex.request.mockResolvedValue(mockResponse);
1761
+ _context20.next = 1;
1762
+ return (0, _Utils.getXsiActionEndpoint)(mockWebex, loggerContext, _types.CALLING_BACKEND.BWRKS);
1763
+ case 1:
1764
+ xsiEndpoint = _context20.sent;
1765
+ expect(mockWebex.request).toHaveBeenCalledTimes(1);
1766
+ expect(xsiEndpoint).toBe('https://fake-broadworks-url.com');
1767
+ case 2:
1768
+ case "end":
1769
+ return _context20.stop();
1770
+ }
1771
+ }, _callee20);
1772
+ })));
1773
+ });
1774
+ describe('modifySdpForIPv4', function () {
1775
+ it('should return original SDP if input is empty', function () {
1776
+ expect((0, _Utils.modifySdpForIPv4)('')).toBe('');
1777
+ });
1778
+ it('should return original SDP if there is no IPv6 c= line', function () {
1779
+ var sdp = "v=0\no=- 12345 67890 IN IP4 192.168.1.1\n\ns=Test Session";
1780
+ expect((0, _Utils.modifySdpForIPv4)(sdp)).toEqual(sdp);
1781
+ });
1782
+ it('should replace IPv6 c= line with default IPv4 if no IPv4 candidate exists', function () {
1783
+ var sdp = "v=0\n o=- 12345 67890 IN IP6 2001:db8::1\n s=Test Session\n c=IN IP6 2001:db8::1\n a=candidate:1 1 UDP 2122260223 2001:db8::1 3478 typ host";
1784
+ var expectedSdp = "v=0\no=- 12345 67890 IN IP6 2001:db8::1\ns=Test Session\nc=IN IP4 192.1.1.1\na=candidate:1 1 UDP 2122260223 2001:db8::1 3478 typ host\na=candidate:2 1 UDP 2122260223 192.1.1.1 3478 typ host generation 0 network-id 1 network-cost 10";
1785
+ var result = (0, _Utils.modifySdpForIPv4)(sdp);
1786
+ expect(result).toEqual(expectedSdp);
1787
+ });
1788
+ it('should replace IPv6 c= line with an existing IPv4 candidate address', function () {
1789
+ var sdp = "v=0\n o=- 12345 67890 IN IP6 2001:db8::1\n s=Test Session\n c=IN IP6 2001:db8::1\n a=candidate:1 1 UDP 2122260223 192.168.1.2 3478 typ host";
1790
+ var expectedSdp = "v=0\no=- 12345 67890 IN IP6 2001:db8::1\ns=Test Session\nc=IN IP4 192.168.1.2\na=candidate:1 1 UDP 2122260223 192.168.1.2 3478 typ host";
1791
+ expect((0, _Utils.modifySdpForIPv4)(sdp).trim()).toEqual(expectedSdp.trim());
1792
+ });
1793
+ it('should correctly handle both UDP and TCP candidates by adding only one IPv4 candidate UDP first', function () {
1794
+ var sdp = "v=0\n o=- 12345 67890 IN IP6 2001:db8::1\n s=Test Session\n c=IN IP6 2001:db8::1\n a=candidate:1 1 UDP 2122260223 2001:db8::1 3478 typ host\n a=candidate:2 1 TCP 2122260223 2001:db8::2 3479 typ host";
1795
+ var expectedSdp = "v=0\no=- 12345 67890 IN IP6 2001:db8::1\ns=Test Session\nc=IN IP4 192.1.1.1\na=candidate:1 1 UDP 2122260223 2001:db8::1 3478 typ host\na=candidate:2 1 UDP 2122260223 192.1.1.1 3478 typ host generation 0 network-id 1 network-cost 10\na=candidate:2 1 TCP 2122260223 2001:db8::2 3479 typ host\n";
1796
+ expect((0, _Utils.modifySdpForIPv4)(sdp).trim()).toEqual(expectedSdp.trim());
1797
+ });
1798
+ it('should correctly handle both UDP and TCP candidates by adding only one IPv4 candidate TCP first', function () {
1799
+ var sdp = "v=0\n o=- 12345 67890 IN IP6 2001:db8::1\n s=Test Session\n c=IN IP6 2001:db8::1\n a=candidate:1 1 TCP 2122260223 2001:db8::2 3479 typ host\n a=candidate:1 1 UDP 2122260223 2001:db8::1 3478 typ host";
1800
+ var expectedSdp = "v=0\no=- 12345 67890 IN IP6 2001:db8::1\ns=Test Session\nc=IN IP4 192.1.1.1\na=candidate:1 1 TCP 2122260223 2001:db8::2 3479 typ host\na=candidate:2 1 TCP 2122260223 192.1.1.1 3479 typ host generation 0 network-id 1 network-cost 10\na=candidate:1 1 UDP 2122260223 2001:db8::1 3478 typ host";
1801
+ expect((0, _Utils.modifySdpForIPv4)(sdp).trim()).toEqual(expectedSdp.trim());
1802
+ });
1803
+ it('should replace all IPv6 c= line if multiple exist', function () {
1804
+ var sdp = "v=0\n o=- 12345 67890 IN IP6 2001:db8::1\n s=Test Session\n c=IN IP6 2001:db8::1\n c=IN IP6 2001:db8::2\n a=candidate:1 1 UDP 2122260223 2001:db8::1 3478 typ host";
1805
+ var expectedSdp = "v=0\no=- 12345 67890 IN IP6 2001:db8::1\ns=Test Session\nc=IN IP4 192.1.1.1\nc=IN IP4 192.1.1.1\na=candidate:1 1 UDP 2122260223 2001:db8::1 3478 typ host\na=candidate:2 1 UDP 2122260223 192.1.1.1 3478 typ host generation 0 network-id 1 network-cost 10";
1806
+ expect((0, _Utils.modifySdpForIPv4)(sdp).trim()).toEqual(expectedSdp.trim());
1807
+ });
1808
+ it('should not modify SDP if IPv6 c= line is absent and IPv4 candidate already exists', function () {
1809
+ var sdp = "v=0\no=- 12345 67890 IN IP4 192.168.1.1\ns=Test Session\nc=IN IP4 192.168.1.1\na=candidate:1 1 UDP 2122260223 192.168.1.1 3478 typ host";
1810
+ expect((0, _Utils.modifySdpForIPv4)(sdp).trim()).toEqual(sdp.trim());
1811
+ });
1812
+ it('should handle malformed SDP gracefully and return unmodified input', function () {
1813
+ var malformedSdp = "random text without proper format";
1814
+ expect((0, _Utils.modifySdpForIPv4)(malformedSdp).trim()).toEqual(malformedSdp.trim());
1815
+ });
1816
+ it('should handle an SDP with both IP6 and IP4 c= lines correctly', function () {
1817
+ var sdp = "v=0\n o=- 12345 67890 IN IP6 2001:db8::1\n s=Test Session\n c=IN IP6 2001:db8::1\n c=IN IP4 192.168.1.3\n a=candidate:1 1 UDP 2122260223 192.168.1.3 3478 typ host";
1818
+ var expectedSdp = "v=0\no=- 12345 67890 IN IP6 2001:db8::1\ns=Test Session\nc=IN IP4 192.168.1.3\nc=IN IP4 192.168.1.3\na=candidate:1 1 UDP 2122260223 192.168.1.3 3478 typ host";
1819
+ expect((0, _Utils.modifySdpForIPv4)(sdp).trim()).toEqual(expectedSdp.trim());
1820
+ });
1821
+ });
1822
+ describe('uploadLogs', function () {
1823
+ var submitLogsMock;
1824
+ beforeEach(function () {
1825
+ // Mock uuid to return a consistent value
1826
+ mockUuid.mockReturnValue('mocked-uuid-12345');
1827
+ // Mock the metrics manager submit function directly
1828
+ mockSubmitRegistrationMetric.mockClear();
1829
+
1830
+ // Mock webex.internal.support.submitLogs
1831
+ submitLogsMock = jest.fn().mockResolvedValue({
1832
+ trackingid: '1234'
1833
+ });
1834
+ webex.internal.support = {
1835
+ submitLogs: submitLogsMock
1836
+ };
1837
+ });
1838
+ afterEach(function () {
1839
+ jest.clearAllMocks();
1840
+ });
1841
+ it('should upload logs and return the response', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee21() {
1842
+ var mockMetaData, logSpy, result;
1843
+ return _regenerator.default.wrap(function (_context21) {
1844
+ while (1) switch (_context21.prev = _context21.next) {
1845
+ case 0:
1846
+ mockMetaData = {
1847
+ correlationId: 'test-correlation'
1848
+ };
1849
+ logSpy = jest.spyOn(_Logger.default, 'info');
1850
+ _context21.next = 1;
1851
+ return (0, _Utils.uploadLogs)(mockMetaData, true);
1852
+ case 1:
1853
+ result = _context21.sent;
1854
+ expect(result).toEqual({
1855
+ trackingid: '1234',
1856
+ feedbackId: 'mocked-uuid-12345'
1857
+ });
1858
+ expect(logSpy).toHaveBeenCalledWith("Logs uploaded successfully with feedbackId: mocked-uuid-12345", {
1859
+ file: _constants.UTILS_FILE,
1860
+ method: 'uploadLogs'
1861
+ });
1862
+ expect(mockSubmitRegistrationMetric).toHaveBeenCalledWith('web-calling-sdk-upload-logs-success', {
1863
+ fields: {
1864
+ call_id: undefined,
1865
+ calling_sdk_version: 'unknown',
1866
+ correlation_id: 'test-correlation',
1867
+ device_url: undefined,
1868
+ feedback_id: 'mocked-uuid-12345',
1869
+ mobius_url: undefined,
1870
+ tracking_id: '1234'
1871
+ },
1872
+ tags: {
1873
+ action: 'upload_logs',
1874
+ device_id: undefined,
1875
+ service_indicator: 'calling'
1876
+ },
1877
+ type: 'behavioral'
1878
+ });
1879
+ expect(submitLogsMock).toHaveBeenCalledWith(_objectSpread(_objectSpread({}, mockMetaData), {}, {
1880
+ feedbackId: 'mocked-uuid-12345'
1881
+ }), undefined, {
1882
+ type: 'diff'
1883
+ });
1884
+ case 2:
1885
+ case "end":
1886
+ return _context21.stop();
1887
+ }
1888
+ }, _callee21);
1889
+ })));
1890
+ it('should log and throw an error if the upload fails', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee22() {
1891
+ var mockMetaData, mockError, logSpy, _t3;
1892
+ return _regenerator.default.wrap(function (_context22) {
1893
+ while (1) switch (_context22.prev = _context22.next) {
1894
+ case 0:
1895
+ mockMetaData = {
1896
+ correlationId: 'test-correlation'
1897
+ };
1898
+ mockError = new Error('Upload failed'); // Mock the submitLogs to fail
1899
+ submitLogsMock.mockRejectedValueOnce(mockError);
1900
+ logSpy = jest.spyOn(_Logger.default, 'error');
1901
+ _context22.prev = 1;
1902
+ _context22.next = 2;
1903
+ return (0, _Utils.uploadLogs)(mockMetaData, true);
1904
+ case 2:
1905
+ // If we get here, the test should fail since we expected an exception
1906
+ expect(true).toBe(false); // This will fail the test if no exception is thrown
1907
+ _context22.next = 4;
1908
+ break;
1909
+ case 3:
1910
+ _context22.prev = 3;
1911
+ _t3 = _context22["catch"](1);
1912
+ expect(_t3).toBe(mockError);
1913
+ expect(logSpy).toHaveBeenCalledWith("Failed to upload Logs ".concat((0, _stringify.default)(_t3)), {
1914
+ file: _constants.UTILS_FILE,
1915
+ method: 'uploadLogs'
1916
+ });
1917
+ expect(mockSubmitRegistrationMetric).toHaveBeenCalledWith('web-calling-sdk-upload-logs-failed', {
1918
+ fields: {
1919
+ device_url: undefined,
1920
+ mobius_url: undefined,
1921
+ calling_sdk_version: 'unknown',
1922
+ correlation_id: 'test-correlation',
1923
+ broadworksCorrelationInfo: undefined,
1924
+ tracking_id: undefined,
1925
+ feedback_id: 'mocked-uuid-12345',
1926
+ call_id: undefined,
1927
+ error: "Failed to upload Logs ".concat((0, _stringify.default)(_t3))
1928
+ },
1929
+ tags: {
1930
+ action: 'upload_logs',
1931
+ device_id: undefined,
1932
+ service_indicator: 'calling'
1933
+ },
1934
+ type: 'behavioral'
1935
+ });
1936
+ case 4:
1937
+ case "end":
1938
+ return _context22.stop();
1939
+ }
1940
+ }, _callee22, null, [[1, 3]]);
1941
+ })));
1942
+ it('should log error and not throw an error if the upload fails with throw exception false', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee23() {
1943
+ var mockMetaData, mockError, logSpy, result;
1944
+ return _regenerator.default.wrap(function (_context23) {
1945
+ while (1) switch (_context23.prev = _context23.next) {
1946
+ case 0:
1947
+ mockMetaData = {
1948
+ correlationId: 'test-correlation',
1949
+ broadworksCorrelationInfo: 'test-broadworks-correlation'
1950
+ };
1951
+ mockError = new Error('Upload failed'); // Mock the submitLogs to fail
1952
+ submitLogsMock.mockRejectedValueOnce(mockError);
1953
+ logSpy = jest.spyOn(_Logger.default, 'error');
1954
+ _context23.next = 1;
1955
+ return (0, _Utils.uploadLogs)(mockMetaData, false);
1956
+ case 1:
1957
+ result = _context23.sent;
1958
+ expect(result).toBeUndefined();
1959
+ expect(logSpy).toHaveBeenCalledWith("Failed to upload Logs ".concat((0, _stringify.default)(mockError)), {
1960
+ file: _constants.UTILS_FILE,
1961
+ method: 'uploadLogs'
1962
+ });
1963
+ expect(mockSubmitRegistrationMetric).toHaveBeenCalledWith('web-calling-sdk-upload-logs-failed', {
1964
+ fields: {
1965
+ device_url: undefined,
1966
+ mobius_url: undefined,
1967
+ calling_sdk_version: 'unknown',
1968
+ correlation_id: 'test-correlation',
1969
+ broadworksCorrelationInfo: 'test-broadworks-correlation',
1970
+ tracking_id: undefined,
1971
+ feedback_id: 'mocked-uuid-12345',
1972
+ call_id: undefined,
1973
+ error: "Failed to upload Logs ".concat((0, _stringify.default)(mockError))
1974
+ },
1975
+ tags: {
1976
+ action: 'upload_logs',
1977
+ device_id: undefined,
1978
+ service_indicator: 'calling'
1979
+ },
1980
+ type: 'behavioral'
1981
+ });
1982
+ case 2:
1983
+ case "end":
1984
+ return _context23.stop();
1985
+ }
1986
+ }, _callee23);
1987
+ })));
1988
+ });
1989
+ //# sourceMappingURL=Utils.test.js.map