@wazo/sdk 0.37.22 → 0.37.26

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 (118) hide show
  1. package/dist/wazo-sdk.js +5 -5
  2. package/esm/__tests__/api-client.test.js +37 -6
  3. package/esm/__tests__/web-rtc-client.test.js +78 -68
  4. package/esm/api/call-logd.js +7 -0
  5. package/esm/api/calld.js +10 -0
  6. package/esm/api/chatd.js +7 -0
  7. package/esm/api/confd.js +13 -5
  8. package/esm/api/ctid-ng.js +10 -0
  9. package/esm/api/dird.js +4 -1
  10. package/esm/api-client.js +37 -6
  11. package/esm/checker/Checker.js +78 -68
  12. package/esm/checker/checks/aor.js +37 -6
  13. package/esm/checker/checks/api.js +37 -6
  14. package/esm/checker/checks/index.js +78 -68
  15. package/esm/checker/checks/webrtc-transport.js +78 -68
  16. package/esm/checker/checks/webrtc.js +78 -68
  17. package/esm/domain/AdHocAPIConference.js +37 -6
  18. package/esm/domain/Call.js +3 -0
  19. package/esm/domain/CallLog.js +7 -0
  20. package/esm/domain/ChatMessage.js +4 -0
  21. package/esm/domain/ChatRoom.js +3 -0
  22. package/esm/domain/Contact.js +4 -1
  23. package/esm/domain/Features.js +37 -6
  24. package/esm/domain/Meeting.js +15 -5
  25. package/esm/domain/Phone/CTIPhone.js +41 -6
  26. package/esm/domain/Phone/WebRTCPhone.js +41 -15
  27. package/esm/domain/Recording.js +3 -0
  28. package/esm/domain/Voicemail.js +3 -0
  29. package/esm/domain/__tests__/Call.test.js +3 -0
  30. package/esm/domain/__tests__/CallLog.test.js +7 -0
  31. package/esm/domain/__tests__/Contact.test.js +4 -1
  32. package/esm/domain/__tests__/Meeting.test.js +144 -0
  33. package/esm/domain/__tests__/Voicemail.test.js +3 -0
  34. package/esm/index.js +122 -82
  35. package/esm/lib/WazoSessionDescriptionHandler.js +0 -38
  36. package/esm/service/CallApi.js +37 -6
  37. package/esm/service/getApiClient.js +37 -6
  38. package/esm/simple/Auth.js +122 -82
  39. package/esm/simple/Configuration.js +122 -82
  40. package/esm/simple/Directory.js +37 -6
  41. package/esm/simple/Phone.js +122 -82
  42. package/esm/simple/index.js +122 -82
  43. package/esm/simple/room/LocalParticipant.js +122 -82
  44. package/esm/simple/room/Participant.js +122 -82
  45. package/esm/simple/room/RemoteParticipant.js +122 -82
  46. package/esm/simple/room/Room.js +122 -82
  47. package/esm/simple/room/SipRoom.js +122 -82
  48. package/esm/simple/room/Stream.js +122 -82
  49. package/esm/simple/room/__tests__/RemoteParticipant.test.js +122 -82
  50. package/esm/simple/utils.js +122 -82
  51. package/esm/types/WebSocketMessage.js +1 -1
  52. package/esm/web-rtc-client.js +78 -68
  53. package/lib/__tests__/api-client.test.js +37 -6
  54. package/lib/__tests__/web-rtc-client.test.js +78 -68
  55. package/lib/api/call-logd.js +7 -0
  56. package/lib/api/calld.js +10 -0
  57. package/lib/api/chatd.js +7 -0
  58. package/lib/api/confd.js +13 -5
  59. package/lib/api/ctid-ng.js +10 -0
  60. package/lib/api/dird.js +4 -1
  61. package/lib/api-client.js +37 -6
  62. package/lib/checker/Checker.js +78 -68
  63. package/lib/checker/checks/aor.js +37 -6
  64. package/lib/checker/checks/api.js +37 -6
  65. package/lib/checker/checks/index.js +78 -68
  66. package/lib/checker/checks/webrtc-transport.js +78 -68
  67. package/lib/checker/checks/webrtc.js +78 -68
  68. package/lib/domain/AdHocAPIConference.js +37 -6
  69. package/lib/domain/Call.js +3 -0
  70. package/lib/domain/CallLog.js +7 -0
  71. package/lib/domain/ChatMessage.js +4 -0
  72. package/lib/domain/ChatRoom.js +3 -0
  73. package/lib/domain/Contact.js +4 -1
  74. package/lib/domain/Features.js +37 -6
  75. package/lib/domain/Meeting.js +19 -5
  76. package/lib/domain/Phone/CTIPhone.js +41 -6
  77. package/lib/domain/Phone/WebRTCPhone.js +41 -15
  78. package/lib/domain/Recording.js +3 -0
  79. package/lib/domain/Voicemail.js +3 -0
  80. package/lib/domain/__tests__/Call.test.js +3 -0
  81. package/lib/domain/__tests__/CallLog.test.js +7 -0
  82. package/lib/domain/__tests__/Contact.test.js +4 -1
  83. package/lib/domain/__tests__/Meeting.test.js +150 -0
  84. package/lib/domain/__tests__/Voicemail.test.js +3 -0
  85. package/lib/index.js +122 -82
  86. package/lib/lib/WazoSessionDescriptionHandler.js +0 -38
  87. package/lib/service/CallApi.js +37 -6
  88. package/lib/service/getApiClient.js +37 -6
  89. package/lib/simple/Auth.js +122 -82
  90. package/lib/simple/Configuration.js +122 -82
  91. package/lib/simple/Directory.js +37 -6
  92. package/lib/simple/Phone.js +122 -82
  93. package/lib/simple/index.js +122 -82
  94. package/lib/simple/room/LocalParticipant.js +122 -82
  95. package/lib/simple/room/Participant.js +122 -82
  96. package/lib/simple/room/RemoteParticipant.js +122 -82
  97. package/lib/simple/room/Room.js +122 -82
  98. package/lib/simple/room/SipRoom.js +122 -82
  99. package/lib/simple/room/Stream.js +122 -82
  100. package/lib/simple/room/__tests__/RemoteParticipant.test.js +122 -82
  101. package/lib/simple/utils.js +122 -82
  102. package/lib/types/WebSocketMessage.js +2 -0
  103. package/lib/web-rtc-client.js +78 -68
  104. package/package.json +1 -1
  105. package/src/domain/Call.js +3 -0
  106. package/src/domain/CallLog.js +4 -0
  107. package/src/domain/ChatMessage.js +4 -0
  108. package/src/domain/ChatRoom.js +3 -0
  109. package/src/domain/Contact.js +4 -1
  110. package/src/domain/Meeting.js +15 -5
  111. package/src/domain/Phone/CTIPhone.js +4 -0
  112. package/src/domain/Phone/Phone.js +2 -0
  113. package/src/domain/Phone/WebRTCPhone.js +41 -15
  114. package/src/domain/Recording.js +3 -0
  115. package/src/domain/Voicemail.js +3 -0
  116. package/src/domain/__tests__/Meeting.test.js +50 -0
  117. package/src/lib/WazoSessionDescriptionHandler.js +1 -35
  118. package/src/web-rtc-client.js +41 -24
@@ -1,5 +1,11 @@
1
1
  'use strict';
2
2
 
3
+ var moment = require('moment');
4
+
5
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
6
+
7
+ var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
8
+
3
9
  //
4
10
 
5
11
  var newFrom = (instance , ToClass ) => {
@@ -20,8 +26,9 @@ var newFrom = (instance , ToClass ) => {
20
26
 
21
27
 
22
28
 
23
-
29
+
24
30
 
31
+
25
32
 
26
33
 
27
34
  class Meeting {
@@ -32,9 +39,10 @@ class Meeting {
32
39
 
33
40
 
34
41
 
35
-
42
+
36
43
 
37
44
 
45
+
38
46
 
39
47
  static parse(plain ) {
40
48
  return new Meeting({
@@ -44,12 +52,16 @@ class Meeting {
44
52
  ownerUuids: plain.owner_uuids,
45
53
  port: plain.port,
46
54
  uuid: plain.uuid,
47
- number: plain.number,
55
+ extension: plain.exten,
48
56
  persistent: plain.persistent,
57
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
49
58
  });
50
59
  }
51
60
 
52
61
  static parseMany(items ) {
62
+ if (!items) {
63
+ return [];
64
+ }
53
65
  return items.map(plain => Meeting.parse(plain));
54
66
  }
55
67
 
@@ -64,8 +76,9 @@ class Meeting {
64
76
  ownerUuids,
65
77
  port,
66
78
  uri,
67
- number,
79
+ extension,
68
80
  persistent,
81
+ creationTime,
69
82
  } = {}) {
70
83
  this.guestSipAuthorization = guestSipAuthorization;
71
84
  this.uri = uri;
@@ -73,8 +86,9 @@ class Meeting {
73
86
  this.ownerUuids = ownerUuids;
74
87
  this.port = port;
75
88
  this.uuid = uuid;
76
- this.number = number;
89
+ this.extension = extension;
77
90
  this.persistent = persistent;
91
+ this.creationTime = creationTime;
78
92
 
79
93
  // Useful to compare instead of instanceof with minified code
80
94
  this.type = 'Meeting';
@@ -853,6 +853,9 @@ class Contact {
853
853
  }
854
854
 
855
855
  static parseMany(response ) {
856
+ if (!response || !response.results) {
857
+ return [];
858
+ }
856
859
  return response.results.map(r => Contact.parse(r, response.column_types));
857
860
  }
858
861
 
@@ -1223,7 +1226,7 @@ class Contact {
1223
1226
  this[key] = old[key] || this[key];
1224
1227
  });
1225
1228
 
1226
- if (old.lineState && !this.lineState) {
1229
+ if (old.lineState) {
1227
1230
  this.lineState = old.lineState;
1228
1231
  }
1229
1232
 
@@ -1559,6 +1562,9 @@ class Call {
1559
1562
 
1560
1563
 
1561
1564
  static parseMany(plain ) {
1565
+ if (!plain) {
1566
+ return [];
1567
+ }
1562
1568
  return plain.map((plainCall ) => Call.parse(plainCall));
1563
1569
  }
1564
1570
 
@@ -2102,6 +2108,9 @@ class Recording {
2102
2108
 
2103
2109
 
2104
2110
  static parseMany(recordings = []) {
2111
+ if (!recordings) {
2112
+ return [];
2113
+ }
2105
2114
  return recordings.map(item => Recording.parse(item));
2106
2115
  }
2107
2116
 
@@ -2203,6 +2212,10 @@ class CallLog {
2203
2212
  }
2204
2213
 
2205
2214
  static parseMany(plain ) {
2215
+ if (!plain || !plain.items) {
2216
+ return [];
2217
+ }
2218
+
2206
2219
  return plain.items.map(item => CallLog.parse(item));
2207
2220
  }
2208
2221
 
@@ -3512,8 +3525,9 @@ class ExternalApp {
3512
3525
 
3513
3526
 
3514
3527
 
3515
-
3528
+
3516
3529
 
3530
+
3517
3531
 
3518
3532
 
3519
3533
  class Meeting {
@@ -3524,9 +3538,10 @@ class Meeting {
3524
3538
 
3525
3539
 
3526
3540
 
3527
-
3541
+
3528
3542
 
3529
3543
 
3544
+
3530
3545
 
3531
3546
  static parse(plain ) {
3532
3547
  return new Meeting({
@@ -3536,12 +3551,16 @@ class Meeting {
3536
3551
  ownerUuids: plain.owner_uuids,
3537
3552
  port: plain.port,
3538
3553
  uuid: plain.uuid,
3539
- number: plain.number,
3554
+ extension: plain.exten,
3540
3555
  persistent: plain.persistent,
3556
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
3541
3557
  });
3542
3558
  }
3543
3559
 
3544
3560
  static parseMany(items ) {
3561
+ if (!items) {
3562
+ return [];
3563
+ }
3545
3564
  return items.map(plain => Meeting.parse(plain));
3546
3565
  }
3547
3566
 
@@ -3556,8 +3575,9 @@ class Meeting {
3556
3575
  ownerUuids,
3557
3576
  port,
3558
3577
  uri,
3559
- number,
3578
+ extension,
3560
3579
  persistent,
3580
+ creationTime,
3561
3581
  } = {}) {
3562
3582
  this.guestSipAuthorization = guestSipAuthorization;
3563
3583
  this.uri = uri;
@@ -3565,8 +3585,9 @@ class Meeting {
3565
3585
  this.ownerUuids = ownerUuids;
3566
3586
  this.port = port;
3567
3587
  this.uuid = uuid;
3568
- this.number = number;
3588
+ this.extension = extension;
3569
3589
  this.persistent = persistent;
3590
+ this.creationTime = creationTime;
3570
3591
 
3571
3592
  // Useful to compare instead of instanceof with minified code
3572
3593
  this.type = 'Meeting';
@@ -3701,6 +3722,10 @@ class ChatMessage {
3701
3722
 
3702
3723
 
3703
3724
  static parseMany(plain ) {
3725
+ if (!plain || !plain.items) {
3726
+ return [];
3727
+ }
3728
+
3704
3729
  return plain.items.map(item => ChatMessage.parse(item));
3705
3730
  }
3706
3731
 
@@ -3810,6 +3835,9 @@ class Voicemail {
3810
3835
  }
3811
3836
 
3812
3837
  static parseMany(plain ) {
3838
+ if (!plain) {
3839
+ return [];
3840
+ }
3813
3841
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
3814
3842
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
3815
3843
 
@@ -4193,6 +4221,9 @@ class ChatRoom {
4193
4221
 
4194
4222
 
4195
4223
  static parseMany(plain ) {
4224
+ if (!plain || !plain.items) {
4225
+ return [];
4226
+ }
4196
4227
  return plain.items.map(item => ChatRoom.parse(item));
4197
4228
  }
4198
4229
 
@@ -5377,6 +5408,10 @@ class CTIPhone extends Emitter {
5377
5408
  return false;
5378
5409
  }
5379
5410
 
5411
+ hasAVideoTrack() {
5412
+ return false;
5413
+ }
5414
+
5380
5415
  getLocalStreamForCall() {
5381
5416
  return null;
5382
5417
  }
@@ -1060,6 +1060,7 @@ class WebRTCPhone extends Emitter {
1060
1060
  constraints,
1061
1061
  audioOnly,
1062
1062
  conference,
1063
+ iceRestart,
1063
1064
  });
1064
1065
 
1065
1066
  if (!sipSession) {
@@ -1163,6 +1164,11 @@ class WebRTCPhone extends Emitter {
1163
1164
 
1164
1165
  this.client.downgradeToAudio(sipSession);
1165
1166
 
1167
+ if (callSession) {
1168
+ callSession.cameraEnabled = false;
1169
+ this._updateCallSession(callSession);
1170
+ }
1171
+
1166
1172
  if (withMessage) {
1167
1173
  this._sendReinviteMessage(callSession, false);
1168
1174
  }
@@ -1190,6 +1196,11 @@ class WebRTCPhone extends Emitter {
1190
1196
 
1191
1197
  const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
1192
1198
 
1199
+ if (callSession) {
1200
+ callSession.cameraEnabled = true;
1201
+ this._updateCallSession(callSession);
1202
+ }
1203
+
1193
1204
  // If no stream is returned, it means we have to reinvite
1194
1205
  if (!newStream) {
1195
1206
  return true;
@@ -1426,18 +1437,20 @@ class WebRTCPhone extends Emitter {
1426
1437
  screenTrack,
1427
1438
  });
1428
1439
 
1429
- screenTrack.onended = () => {
1430
- logger.info('WebRTC phone - on screenshare ended', {
1431
- hadVideo,
1432
- id: this.getSipSessionId(sipSession),
1433
- screenTrack,
1434
- });
1435
-
1436
- this.eventEmitter.emit(
1437
- ON_SHARE_SCREEN_ENDING,
1438
- this._createCallSession(sipSession, callSession),
1439
- );
1440
- };
1440
+ if (screenTrack) {
1441
+ screenTrack.onended = () => {
1442
+ logger.info('WebRTC phone - on screenshare ended', {
1443
+ hadVideo,
1444
+ id: this.getSipSessionId(sipSession),
1445
+ screenTrack,
1446
+ });
1447
+
1448
+ this.eventEmitter.emit(
1449
+ ON_SHARE_SCREEN_ENDING,
1450
+ this._createCallSession(sipSession, callSession),
1451
+ );
1452
+ };
1453
+ }
1441
1454
 
1442
1455
  this.currentScreenShare = {
1443
1456
  stream: screenStream,
@@ -1457,7 +1470,7 @@ class WebRTCPhone extends Emitter {
1457
1470
  }
1458
1471
 
1459
1472
  _onCallAccepted(sipSession , cameraEnabled ) {
1460
- logger.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
1473
+ logger.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
1461
1474
 
1462
1475
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
1463
1476
  this.currentSipSession = sipSession;
@@ -1969,7 +1982,7 @@ class WebRTCPhone extends Emitter {
1969
1982
  // @TODO: line is not used here
1970
1983
  async makeCall(number , line , cameraEnabled ,
1971
1984
  audioOnly = false, conference = false) {
1972
- logger.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
1985
+ logger.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
1973
1986
  if (!number) {
1974
1987
  return Promise.resolve(null);
1975
1988
  }
@@ -2330,9 +2343,13 @@ class WebRTCPhone extends Emitter {
2330
2343
  if (this.shouldSendReinvite && this.currentSipSession
2331
2344
  && this.currentSipSession.state === sessionState.SessionState.Established) {
2332
2345
  this.shouldSendReinvite = false;
2346
+ const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
2347
+ const isConference = pc ? pc.sfu : false;
2348
+ const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
2349
+
2333
2350
  try {
2334
2351
  // Send reinvite with iceRestart
2335
- this.sendReinvite(this.currentCallSession, null, false, false, true);
2352
+ this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
2336
2353
  } catch (e) {
2337
2354
  logger.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
2338
2355
  }
@@ -2416,6 +2433,15 @@ class WebRTCPhone extends Emitter {
2416
2433
  return this.client.getSipSessionId(sipSession);
2417
2434
  }
2418
2435
 
2436
+ _updateCallSession(callSession ) {
2437
+ const sipSession = this.findSipSession(callSession);
2438
+ const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
2439
+
2440
+ if (sipSessionId) {
2441
+ this.callSessions[sipSessionId] = callSession;
2442
+ }
2443
+ }
2444
+
2419
2445
  _onMessage(message ) {
2420
2446
  if (!message || message.method !== 'MESSAGE') {
2421
2447
  return;
@@ -32,6 +32,9 @@ class Recording {
32
32
 
33
33
 
34
34
  static parseMany(recordings = []) {
35
+ if (!recordings) {
36
+ return [];
37
+ }
35
38
  return recordings.map(item => Recording.parse(item));
36
39
  }
37
40
 
@@ -77,6 +77,9 @@ class Voicemail {
77
77
  }
78
78
 
79
79
  static parseMany(plain ) {
80
+ if (!plain) {
81
+ return [];
82
+ }
80
83
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
81
84
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
82
85
 
@@ -77,6 +77,9 @@ class Call {
77
77
 
78
78
 
79
79
  static parseMany(plain ) {
80
+ if (!plain) {
81
+ return [];
82
+ }
80
83
  return plain.map((plainCall ) => Call.parse(plainCall));
81
84
  }
82
85
 
@@ -60,6 +60,9 @@ class Recording {
60
60
 
61
61
 
62
62
  static parseMany(recordings = []) {
63
+ if (!recordings) {
64
+ return [];
65
+ }
63
66
  return recordings.map(item => Recording.parse(item));
64
67
  }
65
68
 
@@ -161,6 +164,10 @@ class CallLog {
161
164
  }
162
165
 
163
166
  static parseMany(plain ) {
167
+ if (!plain || !plain.items) {
168
+ return [];
169
+ }
170
+
164
171
  return plain.items.map(item => CallLog.parse(item));
165
172
  }
166
173
 
@@ -327,6 +327,9 @@ class Contact {
327
327
  }
328
328
 
329
329
  static parseMany(response ) {
330
+ if (!response || !response.results) {
331
+ return [];
332
+ }
330
333
  return response.results.map(r => Contact.parse(r, response.column_types));
331
334
  }
332
335
 
@@ -697,7 +700,7 @@ class Contact {
697
700
  this[key] = old[key] || this[key];
698
701
  });
699
702
 
700
- if (old.lineState && !this.lineState) {
703
+ if (old.lineState) {
701
704
  this.lineState = old.lineState;
702
705
  }
703
706
 
@@ -0,0 +1,150 @@
1
+ 'use strict';
2
+
3
+ var moment = require('moment');
4
+
5
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
6
+
7
+ var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
8
+
9
+ //
10
+
11
+ var newFrom = (instance , ToClass ) => {
12
+ const args = {};
13
+ Object.getOwnPropertyNames(instance).forEach(prop => {
14
+ args[prop] = instance[prop];
15
+ });
16
+
17
+ return new ToClass(args);
18
+ };
19
+
20
+ //
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+ class Meeting {
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+ static parse(plain ) {
48
+ return new Meeting({
49
+ guestSipAuthorization: plain.guest_sip_authorization,
50
+ uri: plain.ingress_http_uri,
51
+ name: plain.name,
52
+ ownerUuids: plain.owner_uuids,
53
+ port: plain.port,
54
+ uuid: plain.uuid,
55
+ extension: plain.exten,
56
+ persistent: plain.persistent,
57
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
58
+ });
59
+ }
60
+
61
+ static parseMany(items ) {
62
+ if (!items) {
63
+ return [];
64
+ }
65
+ return items.map(plain => Meeting.parse(plain));
66
+ }
67
+
68
+ static newFrom(meeting ) {
69
+ return newFrom(meeting, Meeting);
70
+ }
71
+
72
+ constructor({
73
+ uuid,
74
+ name,
75
+ guestSipAuthorization,
76
+ ownerUuids,
77
+ port,
78
+ uri,
79
+ extension,
80
+ persistent,
81
+ creationTime,
82
+ } = {}) {
83
+ this.guestSipAuthorization = guestSipAuthorization;
84
+ this.uri = uri;
85
+ this.name = name;
86
+ this.ownerUuids = ownerUuids;
87
+ this.port = port;
88
+ this.uuid = uuid;
89
+ this.extension = extension;
90
+ this.persistent = persistent;
91
+ this.creationTime = creationTime;
92
+
93
+ // Useful to compare instead of instanceof with minified code
94
+ this.type = 'Meeting';
95
+ }
96
+
97
+ getGuestSipCredentials() {
98
+ // eslint-disable-next-line no-undef
99
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
100
+ return { username, secret };
101
+ }
102
+ }
103
+
104
+ //
105
+
106
+ describe('Meeting domain', () => {
107
+ it('can return username and secret from an base64 encrypted string', () => {
108
+ const USERNAME = 'username';
109
+ const SECRET = 'secret';
110
+
111
+ const args = {
112
+ guest_sip_authorization: btoa(`${USERNAME}:${SECRET}`),
113
+ creation_time: '',
114
+ ingress_http_uri: '',
115
+ name: '',
116
+ owner_uuids: [],
117
+ port: '',
118
+ uuid: '',
119
+ exten: '',
120
+ persistent: false,
121
+ };
122
+
123
+ const meeting = Meeting.parse(args);
124
+
125
+ const { username, secret } = meeting.getGuestSipCredentials();
126
+
127
+ expect(username).toEqual(USERNAME);
128
+ expect(secret).toEqual(SECRET);
129
+ });
130
+
131
+ it('should return a date from a string', () => {
132
+ const args = {
133
+ creation_time: '2021-12-21T15:56:42.880Z',
134
+ guest_sip_authorization: '',
135
+ ingress_http_uri: '',
136
+ name: '',
137
+ owner_uuids: [],
138
+ port: '',
139
+ uuid: '',
140
+ exten: '',
141
+ persistent: false,
142
+ };
143
+
144
+ const { creationTime } = Meeting.parse(args);
145
+
146
+ expect(creationTime.getDate()).toEqual(21);
147
+ expect(creationTime.getFullYear()).toEqual(2021);
148
+ expect(creationTime.getMonth()).toEqual(11);
149
+ });
150
+ });
@@ -77,6 +77,9 @@ class Voicemail {
77
77
  }
78
78
 
79
79
  static parseMany(plain ) {
80
+ if (!plain) {
81
+ return [];
82
+ }
80
83
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
81
84
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
82
85