@wazo/sdk 0.43.12 → 0.43.14

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.
@@ -15,16 +15,16 @@ export interface NewContact {
15
15
  firstName: string;
16
16
  lastName: string;
17
17
  phoneNumber: string;
18
- email: string | null | undefined;
19
- address: string | null | undefined;
20
- entreprise: string | null | undefined;
21
- birthday: string | null | undefined;
22
- note: string | null | undefined;
18
+ email?: string;
19
+ address?: string;
20
+ entreprise?: string;
21
+ birthday?: string;
22
+ note?: string;
23
23
  sessions: Array<{
24
24
  uuid: string;
25
25
  mobile: boolean;
26
26
  }> | null | undefined;
27
- connected: boolean | null | undefined;
27
+ connected?: boolean;
28
28
  }
29
29
  export type ContactResponse = {
30
30
  source: string;
@@ -33,7 +33,7 @@ export type ContactResponse = {
33
33
  relations: {
34
34
  user_id: number;
35
35
  xivo_id: string;
36
- agent_id: number | null | undefined;
36
+ agent_id?: number | null;
37
37
  endpoint_id: number;
38
38
  user_uuid: string;
39
39
  source_entry_id: string;
@@ -47,22 +47,22 @@ export type ContactsResponse = {
47
47
  };
48
48
  export type ContactPersonalResponse = {
49
49
  id: string;
50
- firstName: string | null | undefined;
51
- lastName: string | null | undefined;
52
- number: string | null | undefined;
50
+ firstName?: string;
51
+ lastName?: string;
52
+ number?: string;
53
53
  numbers: Array<{
54
54
  label?: string;
55
55
  number: string;
56
56
  }> | null | undefined;
57
- email: string | null | undefined;
58
- entreprise: string | null | undefined;
59
- birthday: string | null | undefined;
60
- address: string | null | undefined;
61
- note: string | null | undefined;
57
+ email?: string;
58
+ entreprise?: string;
59
+ birthday?: string;
60
+ address?: string;
61
+ note?: string;
62
62
  // @TODO: legacy ?
63
- firstname: string | null | undefined;
64
- lastname: string | null | undefined;
65
- backend: string | null | undefined;
63
+ firstname?: string;
64
+ lastname?: string;
65
+ backend?: string;
66
66
  favorited: boolean;
67
67
  };
68
68
  export type ContactsGraphQlResponse = {
@@ -127,6 +127,8 @@ type ContactArguments = {
127
127
  id?: string;
128
128
  uuid?: string;
129
129
  name?: string;
130
+ firstName?: string;
131
+ lastName?: string;
130
132
  number?: string;
131
133
  numbers?: Array<{
132
134
  label?: string;
@@ -146,7 +148,7 @@ type ContactArguments = {
146
148
  personal?: boolean;
147
149
  state?: string;
148
150
  source?: string;
149
- sourceId?: string | null | undefined;
151
+ sourceId?: string;
150
152
  lineState?: string;
151
153
  previousPresential?: string;
152
154
  lastActivity?: string;
@@ -233,6 +235,8 @@ type GoogleResponse = {
233
235
  emails: string[];
234
236
  id: string;
235
237
  name: string;
238
+ firstname: string;
239
+ lastname: string;
236
240
  numbers: string[];
237
241
  numbers_by_label: any;
238
242
  };
@@ -243,57 +247,61 @@ export default class Contact {
243
247
 
244
248
  type: string;
245
249
 
246
- id: string | null | undefined;
250
+ id?: string;
251
+
252
+ uuid?: string;
247
253
 
248
- uuid: string | null | undefined;
254
+ name?: string;
249
255
 
250
- name: string | null | undefined;
256
+ firstName?: string;
251
257
 
252
- number: string | null | undefined;
258
+ lastName?: string;
259
+
260
+ number?: string;
253
261
 
254
262
  numbers: Array<{
255
263
  label?: string;
256
264
  number: string;
257
265
  }> | null | undefined;
258
266
 
259
- favorited: boolean | null | undefined;
267
+ favorited?: boolean;
260
268
 
261
- email: string | null | undefined;
269
+ email?: string;
262
270
 
263
271
  emails: Array<{
264
272
  label?: string;
265
273
  email: string;
266
274
  }> | null | undefined;
267
275
 
268
- entreprise: string | null | undefined;
276
+ entreprise?: string;
269
277
 
270
- birthday: string | null | undefined;
278
+ birthday?: string;
271
279
 
272
- address: string | null | undefined;
280
+ address?: string;
273
281
 
274
- note: string | null | undefined;
282
+ note?: string;
275
283
 
276
- endpointId: number | null | undefined;
284
+ endpointId?: number;
277
285
 
278
- personal: boolean | null | undefined;
286
+ personal?: boolean;
279
287
 
280
- state: string | null | undefined;
288
+ state?: string;
281
289
 
282
- lineState: string | null | undefined;
290
+ lineState?: string;
283
291
 
284
- previousPresential: string | null | undefined;
292
+ previousPresential?: string;
285
293
 
286
- lastActivity: string | null | undefined;
294
+ lastActivity?: string;
287
295
 
288
- mobile: boolean | null | undefined;
296
+ mobile?: boolean;
289
297
 
290
- source: string | null | undefined;
298
+ source?: string;
291
299
 
292
- sourceId: string | null | undefined;
300
+ sourceId?: string;
293
301
 
294
- status: string | null | undefined;
302
+ status?: string;
295
303
 
296
- backend: string | null | undefined;
304
+ backend?: string;
297
305
 
298
306
  personalStatus: string;
299
307
 
@@ -302,11 +310,11 @@ export default class Contact {
302
310
  mobile: boolean;
303
311
  }> | null | undefined;
304
312
 
305
- connected: boolean | null | undefined;
313
+ connected?: boolean;
306
314
 
307
- doNotDisturb: boolean | null | undefined;
315
+ doNotDisturb?: boolean;
308
316
 
309
- ringing: boolean | null | undefined;
317
+ ringing?: boolean;
310
318
 
311
319
  lines: Record<string, any>[];
312
320
 
@@ -357,6 +365,8 @@ export default class Contact {
357
365
  const name = edge.node.firstname && edge.node.lastname ? `${edge.node.firstname || ''} ${edge.node.lastname || ''}` : edge.node.wazoReverse;
358
366
  return new Contact({
359
367
  name,
368
+ firstName: edge.node.firstname,
369
+ lastName: edge.node.lastname,
360
370
  number: numbers[i],
361
371
  numbers: [{
362
372
  label: 'primary',
@@ -389,6 +399,8 @@ export default class Contact {
389
399
  const email = plain.column_values[columns.indexOf('email')];
390
400
  return new Contact({
391
401
  name: plain.column_values[columns.indexOf('name')],
402
+ firstName: plain.column_values[columns.indexOf('firstname')],
403
+ lastName: plain.column_values[columns.indexOf('lastname')],
392
404
  number: numbers.length ? numbers[0] : '',
393
405
  numbers: numbers.map((number, i) => ({
394
406
  label: i === 0 ? 'primary' : 'secondary',
@@ -420,6 +432,8 @@ export default class Contact {
420
432
  static parsePersonal(plain: ContactPersonalResponse): Contact {
421
433
  return new Contact({
422
434
  name: `${plain.firstName || plain.firstname || ''} ${plain.lastName || plain.lastname || ''}`,
435
+ firstName: plain.firstName || plain.firstname,
436
+ lastName: plain.lastName || plain.lastname,
423
437
  number: plain.number || '',
424
438
  numbers: plain.number ? [{
425
439
  label: 'primary',
@@ -458,6 +472,8 @@ export default class Contact {
458
472
 
459
473
  return new Contact({
460
474
  name,
475
+ firstName,
476
+ lastName,
461
477
  number: plain.phoneNumbers.length ? plain.phoneNumbers[0].number : '',
462
478
  // Make numbers unique
463
479
  numbers: [...new Map(plain.phoneNumbers.map(item => [item.number, item])).values()].map((item, idx) => ({
@@ -523,6 +539,8 @@ export default class Contact {
523
539
  return new Contact({
524
540
  sourceId: single.id || '',
525
541
  name: single.displayName || '',
542
+ firstName: single.givenName,
543
+ lastName: single.surname,
526
544
  number: numbers.length ? numbers[0].number : '',
527
545
  numbers,
528
546
  emails,
@@ -568,6 +586,8 @@ export default class Contact {
568
586
  return new Contact({
569
587
  sourceId: single.id || '',
570
588
  name: single.name || '',
589
+ firstName: single.lastname || '',
590
+ lastName: single.firstname || '',
571
591
  number: numbers.length ? numbers[0].number : '',
572
592
  numbers,
573
593
  emails,
@@ -609,6 +629,8 @@ export default class Contact {
609
629
  uuid: single.uuid,
610
630
  sourceId: String(single.id) || '',
611
631
  name: `${single.firstname}${single.lastname ? ` ${single.lastname}` : ''}`,
632
+ firstName: single.firstname,
633
+ lastName: single.lastname,
612
634
  number: numbers.length ? numbers[0].number : '',
613
635
  numbers,
614
636
  emails,
@@ -651,6 +673,8 @@ export default class Contact {
651
673
  id,
652
674
  uuid,
653
675
  name,
676
+ firstName,
677
+ lastName,
654
678
  number,
655
679
  numbers,
656
680
  email,
@@ -681,6 +705,8 @@ export default class Contact {
681
705
  this.id = id;
682
706
  this.uuid = uuid;
683
707
  this.name = name || '';
708
+ this.firstName = firstName || '';
709
+ this.lastName = lastName || '';
684
710
  this.number = number;
685
711
  this.numbers = numbers;
686
712
  this.email = email;
@@ -56,8 +56,6 @@ type Authorization = {
56
56
  };
57
57
 
58
58
  type SessionArguments = {
59
- acls?: string[];
60
- // deprecated
61
59
  acl?: string[];
62
60
  token: string;
63
61
  refreshToken?: string | null | undefined;
@@ -1,63 +1,203 @@
1
1
  import moment from 'moment';
2
- import CallLog from '../CallLog';
2
+ import CallLog, { Response, CallLogResponse, CALL_LOG_VALID_REQUESTED_VERSION } from '../CallLog';
3
3
  import Recording from '../Recording';
4
+ import Session from '../Session';
5
+ import Profile from '../Profile';
6
+ import Line from '../Line';
4
7
 
5
- describe('CallLog domain', () => {
6
- it('can parse a plain call log to domain', () => {
7
- const response = {
8
- filtered: 6,
9
- items: [{
10
- answer: moment('2017-08-07T13:51:18.892002+00:00').toDate(),
11
- answered: true,
12
- call_direction: 'outbound',
13
- source_extension: '8020',
14
- source_name: 'Jonathan Lessard',
15
- source_user_uuid: '123',
16
- destination_extension: '4182250459',
17
- destination_name: null,
18
- destination_user_uuid: '456',
19
- duration: 4,
20
- start: '2017-08-06T13:50:55.819057+00:00',
21
- end: '2017-08-08T13:51:23.822529+00:00',
22
- requested_extension: '',
23
- requested_name: '',
24
- id: 215,
25
- recordings: [{
26
- deleted: false,
27
- end_time: '2021-08-11T13:22:50.519733+00:00',
28
- filename: '2021-08-11T13_22_45UTC-61886-xxxx-5c72-4072-8503-e3ad9a41c0a0.wav',
29
- start_time: '2021-08-11T13:22:45.161954+00:00',
30
- uuid: '0394ad6f-5c72-4072-8503-e3ad9a41c0a0',
8
+ const ALICE_EXTENSION = '41';
9
+ const ALICE_UUID = '11111111-1111-1111-1111-111111111111';
10
+
11
+ const BOB_EXTENSION = '42';
12
+ const BOB_UUID = '22222222-2222-2222-2222-222222222222';
13
+
14
+ const CHARLIE_EXTENSION = '43';
15
+ const CHARLIE_UUID = '33333333-3333-3333-3333-333333333333';
16
+
17
+ // Default scenario: Alice > Bob (No anwser forward) > Charlie
18
+ const CALL_LOG_RESPONSE: CallLogResponse = {
19
+ id: 1,
20
+ answer: '2024-01-02T00:00:00.000000+00:00',
21
+ answered: true,
22
+ call_direction: 'internal',
23
+ source_name: 'Alice',
24
+ source_extension: ALICE_EXTENSION,
25
+ source_user_uuid: ALICE_UUID,
26
+ requested_name: 'Bob',
27
+ requested_extension: BOB_EXTENSION,
28
+ requested_user_uuid: BOB_UUID,
29
+ destination_name: 'Charlie',
30
+ destination_extension: CHARLIE_EXTENSION,
31
+ destination_user_uuid: CHARLIE_UUID,
32
+ duration: 4,
33
+ start: '2024-01-01T00:00:00.000000+00:00',
34
+ end: '2024-01-01T00:00:04.000000+00:00',
35
+ recordings: [{
36
+ uuid: '0394ad6f-5c72-4072-8503-e3ad9a41c0a0',
37
+ start_time: '2024-01-01T00:00:00.000000+00:00',
38
+ end_time: '2024-01-01T00:00:04.000000+00:00',
39
+ filename: '2024-01-01T00_00_04UTC-61886-0394ad6f-5c72-4072-8503-e3ad9a41c0a0.wav',
40
+ deleted: false,
41
+ }],
42
+ };
43
+ const CALL_LOG = CallLog.parse(CALL_LOG_RESPONSE);
44
+
45
+ const generateBobSession = (opts?: Partial<Session>): Session =>
46
+ new Session({
47
+ acl: [],
48
+ token: 'ref-12345',
49
+ uuid: BOB_UUID,
50
+ expiresAt: new Date(9999, 0, 1),
51
+ engineVersion: CALL_LOG_VALID_REQUESTED_VERSION,
52
+ profile: new Profile({
53
+ lines: [new Line({
54
+ id: 1,
55
+ extensions: [{
56
+ id: 1,
57
+ exten: BOB_EXTENSION,
58
+ context: 'internal',
31
59
  }],
32
- }],
33
- total: 233,
34
- };
35
- const logs = CallLog.parseMany(response as any);
36
- expect(logs).toEqual([new CallLog({
37
- answer: moment('2017-08-07T13:51:18.892002+00:00').toDate(),
38
- answered: true,
39
- callDirection: 'outbound',
40
- destination: {
41
- extension: '4182250459',
42
- name: '',
43
- uuid: '456',
44
- },
45
- source: {
46
- extension: '8020',
47
- name: 'Jonathan Lessard',
48
- uuid: '123',
49
- },
50
- id: 215,
51
- duration: 4000,
52
- start: moment('2017-08-06T13:50:55.819057+00:00').toDate(),
53
- end: moment('2017-08-08T13:51:23.822529+00:00').toDate(),
54
- recordings: [new Recording({
55
- deleted: false,
56
- end: moment('2021-08-11T13:22:50.519733+00:00').toDate(),
57
- fileName: '2021-08-11T13_22_45UTC-61886-xxxx-5c72-4072-8503-e3ad9a41c0a0.wav',
58
- start: moment('2021-08-11T13:22:45.161954+00:00').toDate(),
59
- uuid: '0394ad6f-5c72-4072-8503-e3ad9a41c0a0',
60
60
  })],
61
- })]);
61
+ } as any),
62
+ ...(opts || {}),
63
+ });
64
+
65
+ const BOB_SESSION = generateBobSession();
66
+
67
+ describe('CallLog Domain', () => {
68
+ describe('parseMany', () => {
69
+ it('can parse a plain call log to domain', () => {
70
+ const response: Response = {
71
+ filtered: 6,
72
+ items: [CALL_LOG_RESPONSE],
73
+ total: 233,
74
+ };
75
+
76
+ const logs = CallLog.parseMany(response);
77
+ expect(logs).toEqual([new CallLog({
78
+ id: 1,
79
+ answer: moment(CALL_LOG_RESPONSE.answer).toDate(),
80
+ answered: true,
81
+ callDirection: 'internal',
82
+ source: {
83
+ uuid: ALICE_UUID,
84
+ name: 'Alice',
85
+ extension: ALICE_EXTENSION,
86
+ },
87
+ requested: {
88
+ uuid: BOB_UUID,
89
+ name: 'Bob',
90
+ extension: BOB_EXTENSION,
91
+ },
92
+ destination: {
93
+ uuid: CHARLIE_UUID,
94
+ name: 'Bob',
95
+ extension: BOB_EXTENSION,
96
+ plainExtension: CHARLIE_EXTENSION,
97
+ plainName: 'Charlie',
98
+ },
99
+ duration: 4000,
100
+ start: moment(CALL_LOG_RESPONSE.start).toDate(),
101
+ end: moment(CALL_LOG_RESPONSE.end).toDate(),
102
+ recordings: [new Recording({
103
+ uuid: CALL_LOG_RESPONSE.recordings[0].uuid,
104
+ start: moment(CALL_LOG_RESPONSE.recordings[0].start_time).toDate(),
105
+ end: moment(CALL_LOG_RESPONSE.recordings[0].end_time).toDate(),
106
+ fileName: CALL_LOG_RESPONSE.recordings[0].filename,
107
+ deleted: false,
108
+ })],
109
+ })]);
110
+ });
111
+ });
112
+
113
+ describe('isIconming', () => {
114
+ it('should be TRUE', () => {
115
+ // When requested is set to the same user session extension
116
+ expect(CALL_LOG.isIncomingAndForwarded(BOB_SESSION)).toBe(true);
117
+
118
+ // When destination is set to the same user session extension
119
+ const destinationCallLog = CallLog.parse({
120
+ ...CALL_LOG_RESPONSE,
121
+ destination_extension: CALL_LOG_RESPONSE.requested_extension,
122
+ destination_name: CALL_LOG_RESPONSE.requested_name,
123
+ destination_user_uuid: CALL_LOG_RESPONSE.requested_user_uuid,
124
+ requested_extension: CALL_LOG_RESPONSE.destination_extension,
125
+ requested_name: CALL_LOG_RESPONSE.destination_name,
126
+ requested_user_uuid: CALL_LOG_RESPONSE.destination_user_uuid,
127
+ });
128
+ expect(destinationCallLog.isIncomingAndForwarded(BOB_SESSION)).toBe(true);
129
+
130
+ // When destination is set to the same user with a changed extension
131
+ const destinationExtensionChangedCallLog = CallLog.parse({
132
+ ...CALL_LOG_RESPONSE,
133
+ destination_extension: `${CALL_LOG_RESPONSE.requested_extension}9`,
134
+ destination_name: CALL_LOG_RESPONSE.requested_name,
135
+ destination_user_uuid: CALL_LOG_RESPONSE.requested_user_uuid,
136
+ requested_extension: `${CALL_LOG_RESPONSE.destination_extension}9`,
137
+ requested_name: CALL_LOG_RESPONSE.destination_name,
138
+ requested_user_uuid: CALL_LOG_RESPONSE.destination_user_uuid,
139
+ });
140
+ expect(destinationExtensionChangedCallLog.isIncomingAndForwarded(BOB_SESSION)).toBe(true);
141
+
142
+ // When call direction is inbound
143
+ const inboundCallLog = CallLog.parse({ ...CALL_LOG_RESPONSE, call_direction: 'inbound' });
144
+ expect(inboundCallLog.isIncomingAndForwarded(BOB_SESSION)).toBe(true);
145
+
146
+ });
147
+
148
+ it('should be FALSE', () => {
149
+ // When call direction is outbound
150
+ const outboundCallLog = CallLog.parse({ ...CALL_LOG_RESPONSE, call_direction: 'outbound' });
151
+ expect(outboundCallLog.isIncomingAndForwarded(BOB_SESSION)).toBe(false);
152
+ });
153
+ });
154
+
155
+ describe('isIncomingAndForwarded', () => {
156
+ it('should be TRUE when requested is current user extension and destination is another extesnion', () => {
157
+ // Internal call (requested contact)
158
+ expect(CALL_LOG.isIncomingAndForwarded(BOB_SESSION)).toBe(true);
159
+
160
+ // Inbound call (requested contact)
161
+ const inboundCallLog = CallLog.parse({
162
+ ...CALL_LOG_RESPONSE,
163
+ call_direction: 'inbound',
164
+ source_extension: '18004444444',
165
+ source_name: '',
166
+ source_user_uuid: null,
167
+ });
168
+ expect(inboundCallLog.isIncomingAndForwarded(BOB_SESSION)).toBe(true);
169
+
170
+ // Current user is the final destination
171
+ const destinationCallLog = CallLog.parse({
172
+ ...CALL_LOG_RESPONSE,
173
+ destination_extension: CALL_LOG_RESPONSE.requested_extension,
174
+ destination_name: CALL_LOG_RESPONSE.requested_name,
175
+ destination_user_uuid: CALL_LOG_RESPONSE.requested_user_uuid,
176
+ requested_extension: CALL_LOG_RESPONSE.destination_extension,
177
+ requested_name: CALL_LOG_RESPONSE.destination_name,
178
+ requested_user_uuid: CALL_LOG_RESPONSE.destination_user_uuid,
179
+ });
180
+ expect(destinationCallLog.isIncomingAndForwarded(BOB_SESSION)).toBe(true);
181
+ });
182
+
183
+ it('should be FALSE', () => {
184
+ // Requested and destination are same
185
+ const directCallLog = CallLog.parse({
186
+ ...CALL_LOG_RESPONSE,
187
+ requested_extension: CALL_LOG_RESPONSE.destination_extension,
188
+ requested_name: CALL_LOG_RESPONSE.destination_name,
189
+ requested_user_uuid: CALL_LOG_RESPONSE.destination_user_uuid,
190
+ });
191
+
192
+ expect(directCallLog.isIncomingAndForwarded(BOB_SESSION)).toBe(false);
193
+
194
+ // Not incoming call
195
+ const outboundCallLog = CallLog.parse({ ...CALL_LOG_RESPONSE, call_direction: 'outbound' });
196
+ expect(outboundCallLog.isIncomingAndForwarded(BOB_SESSION)).toBe(false);
197
+
198
+ // Stack version
199
+ const oldStackSession = generateBobSession({ engineVersion: CALL_LOG_VALID_REQUESTED_VERSION.replace('14', '10') });
200
+ expect(CALL_LOG.isIncomingAndForwarded(oldStackSession)).toBe(false);
201
+ });
62
202
  });
63
203
  });
@@ -3,6 +3,8 @@ import Contact from '../Contact';
3
3
  const genericContactResponse = {
4
4
  column_types: [
5
5
  'name',
6
+ 'firstname',
7
+ 'lastname',
6
8
  'number',
7
9
  'callable',
8
10
  'voicemail',
@@ -13,6 +15,8 @@ const genericContactResponse = {
13
15
  term: 'a',
14
16
  column_headers: [
15
17
  'Nom',
18
+ 'Pr\u00e9nom',
19
+ 'Nom de famille',
16
20
  'Num\u00e9ro',
17
21
  'Mobile',
18
22
  'Bo\u00eete vocale',
@@ -27,6 +31,8 @@ const contact1 = {
27
31
  source: 'internal',
28
32
  column_values: [
29
33
  'Jonathan Lessard',
34
+ 'Jonathan',
35
+ 'Lessard',
30
36
  '8020',
31
37
  '06800880',
32
38
  null,
@@ -49,6 +55,8 @@ const contact2 = {
49
55
  source: 'internal',
50
56
  column_values: [
51
57
  'John Doe',
58
+ 'John',
59
+ 'Doe',
52
60
  '8021',
53
61
  '06800881',
54
62
  null,
@@ -69,6 +77,8 @@ const contact2 = {
69
77
 
70
78
  const parsedContact1 = new Contact({
71
79
  name: 'Jonathan Lessard',
80
+ firstName: 'Jonathan',
81
+ lastName: 'Lessard',
72
82
  number: '8020',
73
83
  numbers: [
74
84
  {
@@ -102,6 +112,8 @@ const parsedContact1 = new Contact({
102
112
 
103
113
  const parsedContact2 = new Contact({
104
114
  name: 'John Doe',
115
+ firstName: 'John',
116
+ lastName: 'Doe',
105
117
  number: '8021',
106
118
  numbers: [
107
119
  {