cozy-sharing 33.3.3 → 33.4.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.
- package/CHANGELOG.md +17 -0
- package/dist/SharingProvider.js +176 -84
- package/dist/SharingProvider.spec.js +353 -54
- package/dist/components/FederatedFolder/FederatedFolderModal.js +70 -7
- package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +234 -85
- package/dist/components/ShareButton.js +1 -1
- package/dist/styles/button.styl +0 -5
- package/dist/stylesheet.css +0 -5
- package/package.json +4 -4
- package/src/SharingProvider.jsx +49 -7
- package/src/SharingProvider.spec.jsx +204 -0
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +44 -3
- package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +87 -2
- package/src/components/ShareButton.jsx +1 -1
- package/src/styles/button.styl +0 -5
|
@@ -291,6 +291,210 @@ describe('updateDocumentPermissions', () => {
|
|
|
291
291
|
})
|
|
292
292
|
})
|
|
293
293
|
|
|
294
|
+
describe('fetchSharedDriveSharingLinks', () => {
|
|
295
|
+
const PERM_DRIVE_FILE = {
|
|
296
|
+
type: 'io.cozy.permissions',
|
|
297
|
+
id: 'perm_drive_file',
|
|
298
|
+
attributes: {
|
|
299
|
+
type: 'share',
|
|
300
|
+
permissions: {
|
|
301
|
+
rule0: {
|
|
302
|
+
type: 'io.cozy.files',
|
|
303
|
+
verbs: ['GET'],
|
|
304
|
+
values: ['file_in_drive']
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
shortcodes: { code: 'shortcode123' }
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const driveFile = {
|
|
312
|
+
_id: 'file_in_drive',
|
|
313
|
+
id: 'file_in_drive',
|
|
314
|
+
driveId: 'drive_123'
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
it('fetches shared drive sharing links by file id', async () => {
|
|
318
|
+
const mockFindLinksByIds = jest
|
|
319
|
+
.fn()
|
|
320
|
+
.mockResolvedValue({ data: [PERM_DRIVE_FILE] })
|
|
321
|
+
const mockClient = createMockClient({})
|
|
322
|
+
mockClient.collection = jest.fn().mockReturnValue({
|
|
323
|
+
findLinksByIds: mockFindLinksByIds
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
const provider = new SharingProvider({ client: mockClient })
|
|
327
|
+
provider.state = reducer()
|
|
328
|
+
provider.dispatch = jest.fn(action => {
|
|
329
|
+
provider.state = reducer(provider.state, action)
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
const result = await provider.fetchSharedDriveSharingLinks(driveFile)
|
|
333
|
+
|
|
334
|
+
expect(mockClient.collection).toHaveBeenCalledWith('io.cozy.permissions', {
|
|
335
|
+
driveId: 'drive_123'
|
|
336
|
+
})
|
|
337
|
+
expect(mockFindLinksByIds).toHaveBeenCalledWith(['file_in_drive'])
|
|
338
|
+
expect(provider.dispatch).toHaveBeenCalled()
|
|
339
|
+
const permissions = getDocumentPermissions(provider.state, 'file_in_drive')
|
|
340
|
+
expect(permissions).toHaveLength(1)
|
|
341
|
+
expect(permissions[0].id).toBe(PERM_DRIVE_FILE.id)
|
|
342
|
+
expect(result).toEqual([PERM_DRIVE_FILE])
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
it('returns an empty array and skips the API call for non-shared-drive documents', async () => {
|
|
346
|
+
const mockClient = createMockClient({})
|
|
347
|
+
const findLinksByIds = jest.fn()
|
|
348
|
+
mockClient.collection = jest.fn().mockReturnValue({
|
|
349
|
+
findLinksByIds
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
const provider = new SharingProvider({ client: mockClient })
|
|
353
|
+
provider.dispatch = jest.fn()
|
|
354
|
+
|
|
355
|
+
const result = await provider.fetchSharedDriveSharingLinks({
|
|
356
|
+
_id: 'regular_file'
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
expect(result).toEqual([])
|
|
360
|
+
expect(findLinksByIds).not.toHaveBeenCalled()
|
|
361
|
+
expect(provider.dispatch).not.toHaveBeenCalled()
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
it('uses document.id as a fallback when _id is missing', async () => {
|
|
365
|
+
const mockFindLinksByIds = jest
|
|
366
|
+
.fn()
|
|
367
|
+
.mockResolvedValue({ data: [PERM_DRIVE_FILE] })
|
|
368
|
+
const mockClient = createMockClient({})
|
|
369
|
+
mockClient.collection = jest.fn().mockReturnValue({
|
|
370
|
+
findLinksByIds: mockFindLinksByIds
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
const provider = new SharingProvider({ client: mockClient })
|
|
374
|
+
provider.state = reducer()
|
|
375
|
+
provider.dispatch = jest.fn(action => {
|
|
376
|
+
provider.state = reducer(provider.state, action)
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
await provider.fetchSharedDriveSharingLinks({
|
|
380
|
+
id: 'file_in_drive',
|
|
381
|
+
driveId: 'drive_123'
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
expect(mockFindLinksByIds).toHaveBeenCalledWith(['file_in_drive'])
|
|
385
|
+
})
|
|
386
|
+
|
|
387
|
+
it('does not dispatch when the response has no data', async () => {
|
|
388
|
+
const mockFindLinksByIds = jest.fn().mockResolvedValue({ data: [] })
|
|
389
|
+
const mockClient = createMockClient({})
|
|
390
|
+
mockClient.collection = jest.fn().mockReturnValue({
|
|
391
|
+
findLinksByIds: mockFindLinksByIds
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
const provider = new SharingProvider({ client: mockClient })
|
|
395
|
+
provider.dispatch = jest.fn()
|
|
396
|
+
|
|
397
|
+
const result = await provider.fetchSharedDriveSharingLinks(driveFile)
|
|
398
|
+
|
|
399
|
+
expect(result).toEqual([])
|
|
400
|
+
expect(provider.dispatch).not.toHaveBeenCalled()
|
|
401
|
+
})
|
|
402
|
+
})
|
|
403
|
+
|
|
404
|
+
describe('shareByLink shared drive 409 recovery', () => {
|
|
405
|
+
const PERM_DRIVE_FILE = {
|
|
406
|
+
type: 'io.cozy.permissions',
|
|
407
|
+
id: 'perm_drive_file',
|
|
408
|
+
attributes: {
|
|
409
|
+
type: 'share',
|
|
410
|
+
permissions: {
|
|
411
|
+
rule0: {
|
|
412
|
+
type: 'io.cozy.files',
|
|
413
|
+
verbs: ['GET'],
|
|
414
|
+
values: ['file_in_drive']
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
shortcodes: { code: 'shortcode123' }
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const driveFile = {
|
|
422
|
+
_id: 'file_in_drive',
|
|
423
|
+
id: 'file_in_drive',
|
|
424
|
+
driveId: 'drive_123'
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
it('falls back to fetching existing links when create returns 409', async () => {
|
|
428
|
+
const conflict = Object.assign(new Error('Conflict'), { status: 409 })
|
|
429
|
+
const mockCreateSharingLink = jest.fn().mockRejectedValue(conflict)
|
|
430
|
+
const mockFindLinksByIds = jest
|
|
431
|
+
.fn()
|
|
432
|
+
.mockResolvedValue({ data: [PERM_DRIVE_FILE] })
|
|
433
|
+
const mockClient = createMockClient({})
|
|
434
|
+
mockClient.collection = jest.fn().mockReturnValue({
|
|
435
|
+
createSharingLink: mockCreateSharingLink,
|
|
436
|
+
findLinksByIds: mockFindLinksByIds
|
|
437
|
+
})
|
|
438
|
+
|
|
439
|
+
const provider = new SharingProvider({ client: mockClient })
|
|
440
|
+
provider.state = reducer()
|
|
441
|
+
provider.dispatch = jest.fn(action => {
|
|
442
|
+
provider.state = reducer(provider.state, action)
|
|
443
|
+
})
|
|
444
|
+
|
|
445
|
+
const resp = await provider.shareByLink(driveFile, { verbs: ['GET'] })
|
|
446
|
+
|
|
447
|
+
expect(mockCreateSharingLink).toHaveBeenCalled()
|
|
448
|
+
expect(mockFindLinksByIds).toHaveBeenCalledWith(['file_in_drive'])
|
|
449
|
+
expect(resp.data.id).toBe(PERM_DRIVE_FILE.id)
|
|
450
|
+
})
|
|
451
|
+
|
|
452
|
+
it('does not duplicate existing links when 409 recovery refetches them', async () => {
|
|
453
|
+
const conflict = Object.assign(new Error('Conflict'), { status: 409 })
|
|
454
|
+
const mockCreateSharingLink = jest.fn().mockRejectedValue(conflict)
|
|
455
|
+
const mockFindLinksByIds = jest
|
|
456
|
+
.fn()
|
|
457
|
+
.mockResolvedValue({ data: [PERM_DRIVE_FILE] })
|
|
458
|
+
const mockClient = createMockClient({})
|
|
459
|
+
mockClient.collection = jest.fn().mockReturnValue({
|
|
460
|
+
createSharingLink: mockCreateSharingLink,
|
|
461
|
+
findLinksByIds: mockFindLinksByIds
|
|
462
|
+
})
|
|
463
|
+
|
|
464
|
+
const provider = new SharingProvider({ client: mockClient })
|
|
465
|
+
provider.state = reducer(undefined, addSharingLink(PERM_DRIVE_FILE))
|
|
466
|
+
provider.dispatch = jest.fn(action => {
|
|
467
|
+
provider.state = reducer(provider.state, action)
|
|
468
|
+
})
|
|
469
|
+
|
|
470
|
+
const resp = await provider.shareByLink(driveFile, { verbs: ['GET'] })
|
|
471
|
+
|
|
472
|
+
const permissions = getDocumentPermissions(provider.state, 'file_in_drive')
|
|
473
|
+
expect(resp.data.id).toBe(PERM_DRIVE_FILE.id)
|
|
474
|
+
expect(provider.dispatch).not.toHaveBeenCalled()
|
|
475
|
+
expect(permissions).toHaveLength(1)
|
|
476
|
+
})
|
|
477
|
+
|
|
478
|
+
it('rethrows the original error when 409 happens and no link is found', async () => {
|
|
479
|
+
const conflict = Object.assign(new Error('Conflict'), { status: 409 })
|
|
480
|
+
const mockCreateSharingLink = jest.fn().mockRejectedValue(conflict)
|
|
481
|
+
const mockFindLinksByIds = jest.fn().mockResolvedValue({ data: [] })
|
|
482
|
+
const mockClient = createMockClient({})
|
|
483
|
+
mockClient.collection = jest.fn().mockReturnValue({
|
|
484
|
+
createSharingLink: mockCreateSharingLink,
|
|
485
|
+
findLinksByIds: mockFindLinksByIds
|
|
486
|
+
})
|
|
487
|
+
|
|
488
|
+
const provider = new SharingProvider({ client: mockClient })
|
|
489
|
+
provider.state = reducer()
|
|
490
|
+
provider.dispatch = jest.fn()
|
|
491
|
+
|
|
492
|
+
await expect(
|
|
493
|
+
provider.shareByLink(driveFile, { verbs: ['GET'] })
|
|
494
|
+
).rejects.toBe(conflict)
|
|
495
|
+
})
|
|
496
|
+
})
|
|
497
|
+
|
|
294
498
|
describe('updateSharingMemberType', () => {
|
|
295
499
|
const mockSharing = {
|
|
296
500
|
id: 'sharing-123',
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import PropTypes from 'prop-types'
|
|
2
|
-
import React, { useCallback, useState } from 'react'
|
|
2
|
+
import React, { useCallback, useEffect, useState } from 'react'
|
|
3
3
|
|
|
4
4
|
import { useClient } from 'cozy-client'
|
|
5
|
+
import minilog from 'cozy-minilog'
|
|
5
6
|
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
6
7
|
import { FixedDialog } from 'cozy-ui/transpiled/react/CozyDialogs'
|
|
7
8
|
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
@@ -21,6 +22,8 @@ import { default as DumbShareByEmail } from '../ShareByEmail'
|
|
|
21
22
|
import ShareByLink from '../ShareByLink'
|
|
22
23
|
import WhoHasAccess from '../WhoHasAccess'
|
|
23
24
|
|
|
25
|
+
const log = minilog('FederatedFolderModal')
|
|
26
|
+
|
|
24
27
|
const FederatedFolderModalContent = ({
|
|
25
28
|
onClose,
|
|
26
29
|
document: existingDocument,
|
|
@@ -34,6 +37,8 @@ const FederatedFolderModalContent = ({
|
|
|
34
37
|
getSharingById,
|
|
35
38
|
getSharingLink,
|
|
36
39
|
getFederatedShareLink,
|
|
40
|
+
getDocumentPermissions,
|
|
41
|
+
fetchSharedDriveSharingLinks,
|
|
37
42
|
getRecipients,
|
|
38
43
|
hasSharedChild,
|
|
39
44
|
hasSharedParent,
|
|
@@ -56,6 +61,9 @@ const FederatedFolderModalContent = ({
|
|
|
56
61
|
// in members before the modal closes. That's why when clicking on "Share"
|
|
57
62
|
// we do not use the reactive existingDocument and existingRecipients.
|
|
58
63
|
const [isSending, setIsSending] = useState(false)
|
|
64
|
+
const [isFetchingSharingLinks, setIsFetchingSharingLinks] = useState(false)
|
|
65
|
+
const [fetchedSharingLinksDocumentId, setFetchedSharingLinksDocumentId] =
|
|
66
|
+
useState(null)
|
|
59
67
|
const [frozenDoc, setFrozenDoc] = useState(null)
|
|
60
68
|
const [frozenRecipients, setFrozenRecipients] = useState(null)
|
|
61
69
|
|
|
@@ -169,13 +177,46 @@ const FederatedFolderModalContent = ({
|
|
|
169
177
|
}
|
|
170
178
|
}
|
|
171
179
|
|
|
172
|
-
const
|
|
173
|
-
|
|
180
|
+
const documentId = existingDocument?._id || existingDocument?.id
|
|
181
|
+
const existingRecipients = documentId ? getRecipients(documentId) : []
|
|
182
|
+
const documentPermissions = documentId
|
|
183
|
+
? getDocumentPermissions(documentId)
|
|
174
184
|
: []
|
|
175
185
|
const displayedLink = existingDocument?.driveId
|
|
176
186
|
? getFederatedShareLink(existingDocument)
|
|
177
187
|
: getSharingLink(existingDocument?._id)
|
|
178
188
|
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
if (!existingDocument?.driveId) return
|
|
191
|
+
if (!documentId) return
|
|
192
|
+
if (!fetchSharedDriveSharingLinks) return
|
|
193
|
+
if (documentPermissions.length > 0) return
|
|
194
|
+
if (isFetchingSharingLinks) return
|
|
195
|
+
if (fetchedSharingLinksDocumentId === documentId) return
|
|
196
|
+
|
|
197
|
+
const fetchSharingLinks = async () => {
|
|
198
|
+
setIsFetchingSharingLinks(true)
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
await fetchSharedDriveSharingLinks(existingDocument)
|
|
202
|
+
} catch (error) {
|
|
203
|
+
log.error('Failed to fetch shared drive sharing links', error)
|
|
204
|
+
} finally {
|
|
205
|
+
setFetchedSharingLinksDocumentId(documentId)
|
|
206
|
+
setIsFetchingSharingLinks(false)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
fetchSharingLinks()
|
|
211
|
+
}, [
|
|
212
|
+
documentId,
|
|
213
|
+
existingDocument,
|
|
214
|
+
documentPermissions.length,
|
|
215
|
+
fetchedSharingLinksDocumentId,
|
|
216
|
+
fetchSharedDriveSharingLinks,
|
|
217
|
+
isFetchingSharingLinks
|
|
218
|
+
])
|
|
219
|
+
|
|
179
220
|
const modalTitle = t('FederatedFolder.shareTitle', { name: folderName })
|
|
180
221
|
|
|
181
222
|
return (
|
|
@@ -17,6 +17,8 @@ const mockGetRecipients = jest.fn().mockReturnValue([])
|
|
|
17
17
|
const mockGetSharingById = jest.fn()
|
|
18
18
|
const mockHasSharedChild = jest.fn()
|
|
19
19
|
const mockHasSharedParent = jest.fn()
|
|
20
|
+
const mockFetchSharedDriveSharingLinks = jest.fn()
|
|
21
|
+
const mockGetDocumentPermissions = jest.fn().mockReturnValue([])
|
|
20
22
|
const mockShowAlert = jest.fn()
|
|
21
23
|
const mockOnClose = jest.fn()
|
|
22
24
|
|
|
@@ -27,7 +29,8 @@ jest.mock('../../hooks/useSharingContext', () => ({
|
|
|
27
29
|
revoke: mockRevoke,
|
|
28
30
|
getSharingLink: mockGetSharingLink,
|
|
29
31
|
getFederatedShareLink: mockGetFederatedShareLink,
|
|
30
|
-
getDocumentPermissions:
|
|
32
|
+
getDocumentPermissions: mockGetDocumentPermissions,
|
|
33
|
+
fetchSharedDriveSharingLinks: mockFetchSharedDriveSharingLinks,
|
|
31
34
|
getOwner: jest.fn(),
|
|
32
35
|
getRecipients: mockGetRecipients,
|
|
33
36
|
getSharingById: mockGetSharingById,
|
|
@@ -65,7 +68,8 @@ const createSharingContextValue = () => ({
|
|
|
65
68
|
hasWriteAccess: jest.fn(),
|
|
66
69
|
getRecipients: jest.fn(),
|
|
67
70
|
getSharingLink: mockGetSharingLink,
|
|
68
|
-
getDocumentPermissions:
|
|
71
|
+
getDocumentPermissions: mockGetDocumentPermissions,
|
|
72
|
+
fetchSharedDriveSharingLinks: mockFetchSharedDriveSharingLinks,
|
|
69
73
|
share: mockShare
|
|
70
74
|
})
|
|
71
75
|
|
|
@@ -96,6 +100,8 @@ describe('FederatedFolderModal', () => {
|
|
|
96
100
|
|
|
97
101
|
beforeEach(() => {
|
|
98
102
|
jest.clearAllMocks()
|
|
103
|
+
mockGetDocumentPermissions.mockReturnValue([])
|
|
104
|
+
mockFetchSharedDriveSharingLinks.mockResolvedValue([])
|
|
99
105
|
mockGetSharingLink.mockReturnValue('https://example.com/share/abc123')
|
|
100
106
|
mockGetFederatedShareLink.mockReturnValue(
|
|
101
107
|
'https://example.com/share/federated-abc123'
|
|
@@ -227,6 +233,85 @@ describe('FederatedFolderModal', () => {
|
|
|
227
233
|
})
|
|
228
234
|
})
|
|
229
235
|
|
|
236
|
+
describe('shared drive link fetch on mount', () => {
|
|
237
|
+
it('should fetch shared drive sharing links when document has a driveId and no permissions yet', async () => {
|
|
238
|
+
mockGetDocumentPermissions.mockReturnValue([])
|
|
239
|
+
|
|
240
|
+
setup({
|
|
241
|
+
document: { ...mockDocument, driveId: 'federated-folder-id' }
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
await waitFor(() => {
|
|
245
|
+
expect(mockFetchSharedDriveSharingLinks).toHaveBeenCalledTimes(1)
|
|
246
|
+
})
|
|
247
|
+
expect(mockFetchSharedDriveSharingLinks).toHaveBeenCalledWith(
|
|
248
|
+
expect.objectContaining({
|
|
249
|
+
_id: mockDocument._id,
|
|
250
|
+
driveId: 'federated-folder-id'
|
|
251
|
+
})
|
|
252
|
+
)
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
it('should use document.id when _id is missing', async () => {
|
|
256
|
+
const document = {
|
|
257
|
+
id: 'folder-id-only',
|
|
258
|
+
name: 'My Test Folder',
|
|
259
|
+
path: '/test/folder',
|
|
260
|
+
driveId: 'federated-folder-id'
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
setup({ document })
|
|
264
|
+
|
|
265
|
+
await waitFor(() => {
|
|
266
|
+
expect(mockFetchSharedDriveSharingLinks).toHaveBeenCalledWith(document)
|
|
267
|
+
})
|
|
268
|
+
expect(mockGetDocumentPermissions).toHaveBeenCalledWith('folder-id-only')
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
it('should not fetch shared drive sharing links when document has no driveId', async () => {
|
|
272
|
+
const { findByText } = setup({ document: mockDocument })
|
|
273
|
+
|
|
274
|
+
await findByText('Copy link')
|
|
275
|
+
|
|
276
|
+
expect(mockFetchSharedDriveSharingLinks).not.toHaveBeenCalled()
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
it('should not refetch after one attempt when permissions stay empty', async () => {
|
|
280
|
+
const document = { ...mockDocument, driveId: 'federated-folder-id' }
|
|
281
|
+
const { rerender } = setup({ document })
|
|
282
|
+
|
|
283
|
+
await waitFor(() => {
|
|
284
|
+
expect(mockFetchSharedDriveSharingLinks).toHaveBeenCalledTimes(1)
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
rerender(
|
|
288
|
+
<AppLike client={client} sharingContextValue={sharingContextValue}>
|
|
289
|
+
<FederatedFolderModal document={document} onClose={mockOnClose} />
|
|
290
|
+
</AppLike>
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
expect(mockFetchSharedDriveSharingLinks).toHaveBeenCalledTimes(1)
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
it('should not fetch shared drive sharing links when permissions are already loaded', async () => {
|
|
297
|
+
mockGetDocumentPermissions.mockReturnValue([
|
|
298
|
+
{
|
|
299
|
+
id: 'perm-1',
|
|
300
|
+
type: 'io.cozy.permissions',
|
|
301
|
+
attributes: { shortcodes: { code: 'abc' } }
|
|
302
|
+
}
|
|
303
|
+
])
|
|
304
|
+
|
|
305
|
+
const { findByText } = setup({
|
|
306
|
+
document: { ...mockDocument, driveId: 'federated-folder-id' }
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
await findByText('Copy link')
|
|
310
|
+
|
|
311
|
+
expect(mockFetchSharedDriveSharingLinks).not.toHaveBeenCalled()
|
|
312
|
+
})
|
|
313
|
+
})
|
|
314
|
+
|
|
230
315
|
describe('onSend callback', () => {
|
|
231
316
|
const pendingRecipient = { name: 'Alice', email: 'alice@example.com' }
|
|
232
317
|
|
|
@@ -22,7 +22,7 @@ export const ShareButton = ({ label, onClick, className, ...props }) => (
|
|
|
22
22
|
export const SharedByMeButton = ({ label, onClick, className, ...props }) => (
|
|
23
23
|
<Button
|
|
24
24
|
data-test-id="share-by-me-button"
|
|
25
|
-
className={
|
|
25
|
+
className={className}
|
|
26
26
|
onClick={() => onClick()}
|
|
27
27
|
icon={<Icon icon={ShareIcon} />}
|
|
28
28
|
label={label}
|
package/src/styles/button.styl
CHANGED
|
@@ -4,11 +4,6 @@
|
|
|
4
4
|
color: var(--primaryContrastTextColor)
|
|
5
5
|
transition all .2s ease-out
|
|
6
6
|
|
|
7
|
-
&:focus
|
|
8
|
-
&:not([disabled]):not([aria-disabled=true]):hover
|
|
9
|
-
border-color: var(--malachite)
|
|
10
|
-
background-color: var(--malachite)
|
|
11
|
-
|
|
12
7
|
.coz-btn-sharedWithMe
|
|
13
8
|
border-color: #B449E7
|
|
14
9
|
background-color: #B449E7
|