cozy-sharing 13.2.0 → 13.3.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.
@@ -1,6 +1,6 @@
1
1
  import { models } from 'cozy-client'
2
2
 
3
- import { Contact, Group } from '../models'
3
+ import { Contact, Group, getDisplayName } from '../models'
4
4
 
5
5
  export const countNewRecipients = (currentRecipients, newRecipients) => {
6
6
  const newRecipientsNotAlreadyIncluded = newRecipients.filter(recipient => {
@@ -106,3 +106,48 @@ export const getSuccessMessage = (
106
106
  }
107
107
  }
108
108
  }
109
+
110
+ export const getErrorMessage = ({
111
+ t,
112
+ err,
113
+ documentType,
114
+ recipients,
115
+ selectedOption
116
+ }) => {
117
+ if (err.name === 'FetchError' && err.status === 400) {
118
+ const detail = JSON.parse(err.message).errors[0].detail
119
+ if (
120
+ detail.startsWith('A group member cannot be added as they are already in')
121
+ ) {
122
+ const sharingRights = t(
123
+ `Share.errors.sharingRights.${
124
+ selectedOption === 'readOnly' ? 'readWrite' : 'readOnly'
125
+ }`
126
+ )
127
+
128
+ if (recipients.length === 1 && recipients[0]._type === Contact.doctype) {
129
+ return [
130
+ 'Share.errors.contactAlreadyInSharing',
131
+ {
132
+ smart_count: recipients.length,
133
+ contactName: getDisplayName(recipients[0]),
134
+ sharingRights,
135
+ icon: false
136
+ }
137
+ ]
138
+ }
139
+
140
+ return [
141
+ 'Share.errors.groupMemberAlreadyInSharing',
142
+ {
143
+ smart_count: recipients.length,
144
+ groupName: recipients[0].name,
145
+ sharingRights,
146
+ icon: false
147
+ }
148
+ ]
149
+ }
150
+ }
151
+
152
+ return [`${documentType}.share.error.generic`]
153
+ }
@@ -0,0 +1,424 @@
1
+ import { getSuccessMessage, countNewRecipients, getErrorMessage } from './share'
2
+
3
+ describe('share', () => {
4
+ describe('getSuccessMessage', () => {
5
+ const props = {
6
+ currentRecipients: [{ email: 'sansa.stark@winterfell.westeros' }],
7
+ documentType: 'Files',
8
+ sharingDesc: 'fake-doc.odt',
9
+ onShare: jest.fn(),
10
+ createContact: jest.fn()
11
+ }
12
+
13
+ it('should return a success message and its params for multiple recipients', () => {
14
+ const recipientsAfter = [
15
+ { _type: 'io.cozy.contacts', email: 'jon.snow@thewall.westeros' },
16
+ { _type: 'io.cozy.contacts', email: 'arya.stark@winterfell.westeros' },
17
+ { _type: 'io.cozy.contacts', email: 'sansa.stark@winterfell.westeros' }
18
+ ]
19
+ const [message, params] = getSuccessMessage(
20
+ props.currentRecipients,
21
+ recipientsAfter,
22
+ props.documentType
23
+ )
24
+ expect(message).toEqual('Files.share.shareByEmail.contactSuccess')
25
+ expect(params).toEqual({ smart_count: 2 })
26
+ })
27
+
28
+ it('should return a success message and its params for one recipient with email', () => {
29
+ const recipientsBefore = props.currentRecipients
30
+ const [message, params] = getSuccessMessage(
31
+ recipientsBefore,
32
+ [{ email: 'jon.snow@thewall.westeros' }],
33
+ props.documentType
34
+ )
35
+ expect(message).toEqual('Files.share.shareByEmail.singleContactSuccess')
36
+ expect(params).toEqual({ email: 'jon.snow@thewall.westeros' })
37
+ })
38
+
39
+ it('should return a success message and its params for one recipient (contact) with email', () => {
40
+ const recipientsBefore = props.currentRecipients
41
+ const [message, params] = getSuccessMessage(
42
+ recipientsBefore,
43
+ [
44
+ {
45
+ _id: 'e8c0e15f-da7d',
46
+ _type: 'io.cozy.contacts',
47
+ fullname: 'Jon Snow',
48
+ email: [
49
+ {
50
+ address: 'jon.snow@thewall.westeros',
51
+ primary: true
52
+ },
53
+ {
54
+ address: 'jon.snow@winterfell.westeros',
55
+ primary: false
56
+ }
57
+ ]
58
+ }
59
+ ],
60
+ props.documentType
61
+ )
62
+ expect(message).toEqual('Files.share.shareByEmail.singleContactSuccess')
63
+ expect(params).toEqual({ email: 'jon.snow@thewall.westeros' })
64
+ })
65
+
66
+ it('should return a success message and its params for one recipient with cozy', () => {
67
+ const recipientsBefore = props.currentRecipients
68
+ const [message, params] = getSuccessMessage(
69
+ recipientsBefore,
70
+ [
71
+ {
72
+ cozy: [
73
+ {
74
+ url: 'https://doranmartell.mycozy.cloud'
75
+ }
76
+ ]
77
+ }
78
+ ],
79
+ props.documentType
80
+ )
81
+ expect(message).toEqual('Files.share.shareByEmail.singleContactSuccess')
82
+ expect(params).toEqual({ email: 'https://doranmartell.mycozy.cloud' })
83
+ })
84
+
85
+ it('should use contact success message if recipient has no email and no cozy', () => {
86
+ const recipientsBefore = props.currentRecipients
87
+ const [message, params] = getSuccessMessage(
88
+ recipientsBefore,
89
+ [
90
+ {
91
+ _id: 'fcb16b9e-7421'
92
+ }
93
+ ],
94
+ props.documentType
95
+ )
96
+ expect(message).toEqual('Files.share.shareByEmail.contactSuccess')
97
+ expect(params).toEqual({ smart_count: 1 })
98
+ })
99
+
100
+ it('should use single group success message if recipient is a group', () => {
101
+ const recipientsBefore = props.currentRecipients
102
+ const [message, params] = getSuccessMessage(
103
+ recipientsBefore,
104
+ [
105
+ {
106
+ _type: 'io.cozy.contacts.groups',
107
+ name: 'Stark family'
108
+ }
109
+ ],
110
+ props.documentType
111
+ )
112
+ expect(message).toEqual('Files.share.shareByEmail.singleGroupSuccess')
113
+ expect(params).toEqual({ groupName: 'Stark family' })
114
+ })
115
+
116
+ it('should use contact success message if recipient has only multiple contacts', () => {
117
+ const recipientsBefore = props.currentRecipients
118
+ const [message, params] = getSuccessMessage(
119
+ recipientsBefore,
120
+ [
121
+ {
122
+ _type: 'io.cozy.contacts'
123
+ },
124
+ {
125
+ _type: 'io.cozy.contacts'
126
+ },
127
+ {
128
+ _type: 'io.cozy.contacts'
129
+ }
130
+ ],
131
+ props.documentType
132
+ )
133
+ expect(message).toEqual('Files.share.shareByEmail.contactSuccess')
134
+ expect(params).toEqual({ smart_count: 3 })
135
+ })
136
+
137
+ it('should use group success message if recipient has only multiple groups', () => {
138
+ const recipientsBefore = props.currentRecipients
139
+ const [message, params] = getSuccessMessage(
140
+ recipientsBefore,
141
+ [
142
+ {
143
+ _type: 'io.cozy.contacts.groups'
144
+ },
145
+ {
146
+ _type: 'io.cozy.contacts.groups'
147
+ }
148
+ ],
149
+ props.documentType
150
+ )
151
+ expect(message).toEqual('Files.share.shareByEmail.groupSuccess')
152
+ expect(params).toEqual({ smart_count: 2 })
153
+ })
154
+
155
+ it('should use contact and group success message if recipient has multiple contacts and groups', () => {
156
+ const recipientsBefore = props.currentRecipients
157
+ const [message, params] = getSuccessMessage(
158
+ recipientsBefore,
159
+ [
160
+ {
161
+ _type: 'io.cozy.contacts'
162
+ },
163
+ {
164
+ _id: 'fcb16b9e-7421',
165
+ _type: 'io.cozy.contacts.groups'
166
+ },
167
+ {
168
+ _id: 'f45b16be-7523',
169
+ _type: 'io.cozy.contacts.groups'
170
+ }
171
+ ],
172
+ props.documentType
173
+ )
174
+ expect(message).toEqual('Files.share.shareByEmail.contactAndGroupSuccess')
175
+ expect(params).toEqual({ nbContact: 1, nbGroup: 2 })
176
+ })
177
+ })
178
+
179
+ describe('countNewRecipients', () => {
180
+ const currentRecipients = [
181
+ {
182
+ email: 'arya.stark@winterfell.westeros'
183
+ },
184
+ {
185
+ email: 'sansa.stark@winterfell.westeros'
186
+ },
187
+ {
188
+ email: 'jon.snow@thewall.westeros'
189
+ }
190
+ ]
191
+ const addedRecipients = [
192
+ {
193
+ _id: 'e8c0e15f-da7d',
194
+ _type: 'io.cozy.contacts',
195
+ fullname: 'Jon Snow',
196
+ email: [
197
+ {
198
+ address: 'jon.snow@thewall.westeros',
199
+ primary: true
200
+ },
201
+ {
202
+ address: 'jon.snow@winterfell.westeros',
203
+ primary: false
204
+ }
205
+ ]
206
+ },
207
+ {
208
+ _id: 'fcb16b9e-7421',
209
+ _type: 'io.cozy.contacts'
210
+ },
211
+ {
212
+ _id: 'f45b16be-7523',
213
+ _type: 'io.cozy.contacts',
214
+ cozy: [
215
+ {
216
+ url: 'https://doranmartell.mycozy.cloud'
217
+ }
218
+ ]
219
+ }
220
+ ]
221
+
222
+ it('should count the new recipients with email', () => {
223
+ const result = countNewRecipients(currentRecipients, addedRecipients)
224
+ expect(result.contact).toEqual(2)
225
+ expect(result.group).toEqual(0)
226
+ })
227
+
228
+ it('should count the new recipients with cozy url', () => {
229
+ const currentRecipients = [
230
+ {
231
+ instance: 'https://bran.mycozy.cloud'
232
+ },
233
+ {
234
+ instance: 'https://jon.mycozy.cloud'
235
+ }
236
+ ]
237
+ const addedRecipients = [
238
+ {
239
+ _type: 'io.cozy.contacts',
240
+ cozy: [
241
+ {
242
+ url: 'https://jon.mycozy.cloud',
243
+ type: 'primary'
244
+ }
245
+ ]
246
+ },
247
+ {
248
+ _type: 'io.cozy.contacts',
249
+ cozy: [
250
+ {
251
+ url: 'https://sansa.mycozy.cloud',
252
+ type: 'primary'
253
+ }
254
+ ]
255
+ },
256
+ {
257
+ _type: 'io.cozy.contacts',
258
+ cozy: [
259
+ {
260
+ url: 'https://bran.mycozy.cloud',
261
+ type: 'primary'
262
+ }
263
+ ]
264
+ },
265
+ {
266
+ _type: 'io.cozy.contacts',
267
+ cozy: [
268
+ {
269
+ url: 'https://arya.mycozy.cloud',
270
+ type: 'primary'
271
+ }
272
+ ]
273
+ }
274
+ ]
275
+ const result = countNewRecipients(currentRecipients, addedRecipients)
276
+ expect(result.contact).toEqual(2)
277
+ expect(result.group).toEqual(0)
278
+ })
279
+
280
+ it('should count the new recipients with groups', () => {
281
+ const result = countNewRecipients(currentRecipients, [
282
+ ...addedRecipients,
283
+ { _id: 'f45b16be-7523', _type: 'io.cozy.contacts.groups' }
284
+ ])
285
+ expect(result.contact).toEqual(2)
286
+ expect(result.group).toEqual(1)
287
+ })
288
+
289
+ it('should return 0 if there are no new recipients', () => {
290
+ const result = countNewRecipients(currentRecipients, [])
291
+ expect(result.contact).toEqual(0)
292
+ expect(result.group).toEqual(0)
293
+ })
294
+ })
295
+
296
+ describe('getErrorMessage', () => {
297
+ const t = key => key // Mock translation function
298
+ const documentType = 'document'
299
+ const recipients = [{ name: 'John Doe' }]
300
+ const selectedOption = 'readOnly'
301
+
302
+ it('should return generic error message for non-FetchError', () => {
303
+ const err = new Error('Some error')
304
+ const result = getErrorMessage({
305
+ t,
306
+ err,
307
+ documentType,
308
+ recipients,
309
+ selectedOption
310
+ })
311
+ expect(result).toEqual([`${documentType}.share.error.generic`])
312
+ })
313
+
314
+ it('should return specific error message for FetchError with status 400 and specific detail', () => {
315
+ const err = {
316
+ name: 'FetchError',
317
+ status: 400,
318
+ message: JSON.stringify({
319
+ errors: [
320
+ { detail: 'A group member cannot be added as they are already in' }
321
+ ]
322
+ })
323
+ }
324
+ const result = getErrorMessage({
325
+ t,
326
+ err,
327
+ documentType,
328
+ recipients,
329
+ selectedOption
330
+ })
331
+ expect(result).toEqual([
332
+ 'Share.errors.groupMemberAlreadyInSharing',
333
+ {
334
+ smart_count: recipients.length,
335
+ groupName: recipients[0].name,
336
+ sharingRights: 'Share.errors.sharingRights.readWrite',
337
+ icon: false
338
+ }
339
+ ])
340
+ })
341
+
342
+ it('should return opposite sharingRights for the other group when the group member already in sharing', () => {
343
+ const err = {
344
+ name: 'FetchError',
345
+ status: 400,
346
+ message: JSON.stringify({
347
+ errors: [
348
+ { detail: 'A group member cannot be added as they are already in' }
349
+ ]
350
+ })
351
+ }
352
+ const result = getErrorMessage({
353
+ t,
354
+ err,
355
+ documentType,
356
+ recipients,
357
+ selectedOption: 'readWrite'
358
+ })
359
+ expect(result).toEqual([
360
+ 'Share.errors.groupMemberAlreadyInSharing',
361
+ {
362
+ smart_count: recipients.length,
363
+ groupName: recipients[0].name,
364
+ sharingRights: 'Share.errors.sharingRights.readOnly',
365
+ icon: false
366
+ }
367
+ ])
368
+ })
369
+
370
+ it('should return specific text if there is only one recipient and it is a contact', () => {
371
+ const err = {
372
+ name: 'FetchError',
373
+ status: 400,
374
+ message: JSON.stringify({
375
+ errors: [
376
+ { detail: 'A group member cannot be added as they are already in' }
377
+ ]
378
+ })
379
+ }
380
+ const result = getErrorMessage({
381
+ t,
382
+ err,
383
+ documentType,
384
+ recipients: [
385
+ {
386
+ _type: 'io.cozy.contacts',
387
+ name: {
388
+ givenName: 'John',
389
+ familyName: 'Doe'
390
+ }
391
+ }
392
+ ],
393
+ selectedOption
394
+ })
395
+ expect(result).toEqual([
396
+ 'Share.errors.contactAlreadyInSharing',
397
+ {
398
+ smart_count: recipients.length,
399
+ contactName: 'John Doe',
400
+ sharingRights: 'Share.errors.sharingRights.readWrite',
401
+ icon: false
402
+ }
403
+ ])
404
+ })
405
+
406
+ it('should return generic error message for FetchError with status 400 and different detail', () => {
407
+ const err = {
408
+ name: 'FetchError',
409
+ status: 400,
410
+ message: JSON.stringify({
411
+ errors: [{ detail: 'Some other detail' }]
412
+ })
413
+ }
414
+ const result = getErrorMessage({
415
+ t,
416
+ err,
417
+ documentType,
418
+ recipients,
419
+ selectedOption
420
+ })
421
+ expect(result).toEqual([`${documentType}.share.error.generic`])
422
+ })
423
+ })
424
+ })