cozy-sharing 32.1.2 → 32.3.2
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 +24 -0
- package/dist/components/FederatedFolder/FederatedFolderModal.js +96 -22
- package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +137 -219
- package/dist/components/Recipient/RecipientList.js +0 -15
- package/dist/components/ShareAutosuggest.js +1 -0
- package/dist/components/ShareAutosuggest.spec.js +12 -4
- package/dist/components/ShareDialogCozyToCozy.spec.js +55 -8
- package/dist/components/ShareDiscardChangesModal.js +35 -0
- package/dist/components/ShareModal/ShareModal.js +8 -8
- package/dist/components/ShareRecipientsInput.js +13 -3
- package/dist/components/ShareRecipientsInput.spec.js +63 -4
- package/dist/state.js +6 -1
- package/locales/en.json +10 -5
- package/locales/fr.json +10 -5
- package/locales/ru.json +10 -5
- package/locales/vi.json +10 -5
- package/package.json +2 -2
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +230 -138
- package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +59 -134
- package/src/components/Recipient/RecipientList.jsx +0 -18
- package/src/components/ShareAutosuggest.jsx +1 -0
- package/src/components/ShareAutosuggest.spec.jsx +10 -5
- package/src/components/ShareDialogCozyToCozy.spec.jsx +50 -4
- package/src/components/ShareDiscardChangesModal.jsx +40 -0
- package/src/components/ShareModal/ShareModal.jsx +5 -5
- package/src/components/ShareRecipientsInput.jsx +11 -6
- package/src/components/ShareRecipientsInput.spec.jsx +59 -0
- package/src/state.js +5 -1
- package/dist/components/SharedDrive/SharedDriveRecipient.js +0 -61
- package/dist/components/SharedDrive/SharedDriveRecipientPermissions.js +0 -109
- package/dist/components/SharedDrive/SharedDriveRecipientStatus.js +0 -22
- package/dist/components/SharedFolder/DumbBatchSharedFolderModal.js +0 -145
- package/src/components/SharedDrive/SharedDriveRecipient.jsx +0 -62
- package/src/components/SharedDrive/SharedDriveRecipientPermissions.jsx +0 -78
- package/src/components/SharedDrive/SharedDriveRecipientStatus.jsx +0 -23
- package/src/components/SharedFolder/DumbBatchSharedFolderModal.jsx +0 -161
|
@@ -1,159 +1,251 @@
|
|
|
1
1
|
import PropTypes from 'prop-types'
|
|
2
|
-
import React, { useEffect, useState } from 'react'
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
|
3
3
|
|
|
4
4
|
import { useClient } from 'cozy-client'
|
|
5
|
+
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
6
|
+
import { FixedDialog } from 'cozy-ui/transpiled/react/CozyDialogs'
|
|
7
|
+
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
5
8
|
import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
|
|
9
|
+
import ConfirmDialogProvider, {
|
|
10
|
+
useConfirmDialog
|
|
11
|
+
} from 'cozy-ui/transpiled/react/providers/ConfirmDialog'
|
|
6
12
|
import { useI18n } from 'twake-i18n'
|
|
7
13
|
|
|
8
14
|
import { getOrCreateFromArray } from '../../helpers/contacts'
|
|
9
15
|
import withLocales from '../../hoc/withLocales'
|
|
10
16
|
import { usePendingRecipients } from '../../hooks/usePendingRecipients'
|
|
11
17
|
import { useSharingContext } from '../../hooks/useSharingContext'
|
|
12
|
-
import
|
|
18
|
+
import AntivirusAlert from '../AntivirusAlert'
|
|
19
|
+
import { default as DumbShareByEmail } from '../ShareByEmail'
|
|
20
|
+
import ShareByLink from '../ShareByLink'
|
|
21
|
+
import WhoHasAccess from '../WhoHasAccess'
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
|
|
23
|
+
const FederatedFolderModalContent = ({
|
|
24
|
+
onClose,
|
|
25
|
+
document: existingDocument,
|
|
26
|
+
autoOpenShareRestriction,
|
|
27
|
+
showGenerateLinkButton
|
|
28
|
+
}) => {
|
|
29
|
+
const client = useClient()
|
|
30
|
+
const { t } = useI18n()
|
|
31
|
+
const {
|
|
32
|
+
share,
|
|
33
|
+
getSharingLink,
|
|
34
|
+
getFederatedShareLink,
|
|
35
|
+
getDocumentPermissions,
|
|
36
|
+
getOwner,
|
|
37
|
+
getSharingById,
|
|
38
|
+
getRecipients,
|
|
39
|
+
revoke
|
|
40
|
+
} = useSharingContext()
|
|
41
|
+
const { showAlert } = useAlert()
|
|
42
|
+
const { showConfirmDialog, closeConfirmDialog } = useConfirmDialog()
|
|
43
|
+
|
|
44
|
+
const [sharingLink, setSharingLink] = useState(null)
|
|
45
|
+
const {
|
|
46
|
+
pendingRecipients,
|
|
47
|
+
setPendingRecipients,
|
|
48
|
+
selectedOption,
|
|
49
|
+
setSelectedOption
|
|
50
|
+
} = usePendingRecipients()
|
|
51
|
+
|
|
52
|
+
// share from CozyProvider is wired to callbacks and realtime that
|
|
53
|
+
// makes existingDocument and existingRecipients reactive to changes.
|
|
54
|
+
// But we want it to be reactive only when we revoke a member. When we add member
|
|
55
|
+
// we close the popup and we do not want to see briefly the new contacts added
|
|
56
|
+
// in members before the modal closes. That's why when clicking on "Share"
|
|
57
|
+
// we do not use the reactive existingDocument and existingRecipients.
|
|
58
|
+
const [isSending, setIsSending] = useState(false)
|
|
59
|
+
const [frozenDoc, setFrozenDoc] = useState(null)
|
|
60
|
+
const [frozenRecipients, setFrozenRecipients] = useState(null)
|
|
61
|
+
|
|
62
|
+
const handleCloseRequest = useCallback(() => {
|
|
63
|
+
if (pendingRecipients.length === 0) {
|
|
64
|
+
onClose()
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
showConfirmDialog({
|
|
69
|
+
title: t('ShareDiscardChangesModal.title'),
|
|
70
|
+
actions: (
|
|
71
|
+
<>
|
|
72
|
+
<Button
|
|
73
|
+
variant="secondary"
|
|
74
|
+
label={t('ShareDiscardChangesModal.cancel')}
|
|
75
|
+
className="u-fz-small"
|
|
76
|
+
onClick={closeConfirmDialog}
|
|
77
|
+
/>
|
|
78
|
+
<Button
|
|
79
|
+
variant="primary"
|
|
80
|
+
label={t('ShareDiscardChangesModal.discard')}
|
|
81
|
+
className="u-fz-small"
|
|
82
|
+
onClick={() => {
|
|
83
|
+
closeConfirmDialog()
|
|
84
|
+
onClose()
|
|
85
|
+
}}
|
|
86
|
+
/>
|
|
87
|
+
</>
|
|
88
|
+
)
|
|
89
|
+
})
|
|
90
|
+
}, [
|
|
91
|
+
closeConfirmDialog,
|
|
16
92
|
onClose,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const client = useClient()
|
|
22
|
-
const { t } = useI18n()
|
|
23
|
-
const {
|
|
24
|
-
share,
|
|
25
|
-
getSharingLink,
|
|
26
|
-
getFederatedShareLink,
|
|
27
|
-
getDocumentPermissions,
|
|
28
|
-
getOwner,
|
|
29
|
-
getSharingById,
|
|
30
|
-
getRecipients,
|
|
31
|
-
revoke
|
|
32
|
-
} = useSharingContext()
|
|
33
|
-
const { showAlert } = useAlert()
|
|
34
|
-
|
|
35
|
-
const [sharingLink, setSharingLink] = useState(null)
|
|
36
|
-
const {
|
|
37
|
-
pendingRecipients,
|
|
38
|
-
setPendingRecipients,
|
|
39
|
-
selectedOption,
|
|
40
|
-
setSelectedOption
|
|
41
|
-
} = usePendingRecipients()
|
|
42
|
-
|
|
43
|
-
// share from CozyProvider is wired to callbacks and realtime that
|
|
44
|
-
// makes existingDocument and existingRecipients reactive to changes.
|
|
45
|
-
// But we want it to be reactive only when we revoke a member. When we add member
|
|
46
|
-
// we close the popup and we do not want to see briefly the new contacts added
|
|
47
|
-
// in members before the modal closes. That's why when clicking on "Share"
|
|
48
|
-
// we do not use the reactive existingDocument and existingRecipients.
|
|
49
|
-
const [isSending, setIsSending] = useState(false)
|
|
50
|
-
const [frozenDoc, setFrozenDoc] = useState(null)
|
|
51
|
-
const [frozenRecipients, setFrozenRecipients] = useState(null)
|
|
52
|
-
|
|
53
|
-
const documentPermissions = existingDocument
|
|
54
|
-
? getDocumentPermissions(existingDocument._id)
|
|
55
|
-
: []
|
|
56
|
-
|
|
57
|
-
useEffect(() => {
|
|
58
|
-
const fetchSharingLink = async () => {
|
|
59
|
-
if (!existingDocument) return
|
|
60
|
-
|
|
61
|
-
if (existingDocument.driveId) {
|
|
62
|
-
const link = await getFederatedShareLink(existingDocument)
|
|
63
|
-
setSharingLink(link)
|
|
64
|
-
} else {
|
|
65
|
-
setSharingLink(getSharingLink(existingDocument._id))
|
|
66
|
-
}
|
|
67
|
-
}
|
|
93
|
+
pendingRecipients.length,
|
|
94
|
+
showConfirmDialog,
|
|
95
|
+
t
|
|
96
|
+
])
|
|
68
97
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
existingDocument,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const folderName = existingDocument?.name || ''
|
|
80
|
-
|
|
81
|
-
const onSend = async () => {
|
|
82
|
-
if (pendingRecipients.length === 0) {
|
|
83
|
-
onClose()
|
|
84
|
-
return
|
|
85
|
-
}
|
|
98
|
+
const documentPermissions = useMemo(
|
|
99
|
+
() =>
|
|
100
|
+
existingDocument ? getDocumentPermissions(existingDocument._id) : [],
|
|
101
|
+
[existingDocument, getDocumentPermissions]
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
const fetchSharingLink = async () => {
|
|
106
|
+
if (!existingDocument) return
|
|
86
107
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const contacts = await getOrCreateFromArray(
|
|
93
|
-
client,
|
|
94
|
-
pendingRecipients,
|
|
95
|
-
contact => client.create('io.cozy.contacts', contact)
|
|
96
|
-
)
|
|
97
|
-
const readWriteRecipients =
|
|
98
|
-
selectedOption === 'readOnly' ? [] : contacts
|
|
99
|
-
const readOnlyRecipients = selectedOption === 'readOnly' ? contacts : []
|
|
100
|
-
|
|
101
|
-
await share({
|
|
102
|
-
description: folderName,
|
|
103
|
-
document: existingDocument,
|
|
104
|
-
recipients: readWriteRecipients,
|
|
105
|
-
readOnlyRecipients,
|
|
106
|
-
sharedDrive: true,
|
|
107
|
-
openSharing: false
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
showAlert({
|
|
111
|
-
message: t('FederatedFolder.successNotification'),
|
|
112
|
-
severity: 'success',
|
|
113
|
-
variant: 'filled'
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
onClose()
|
|
117
|
-
} catch (_err) {
|
|
118
|
-
showAlert({
|
|
119
|
-
message: t('FederatedFolder.errorNotification'),
|
|
120
|
-
severity: 'error',
|
|
121
|
-
variant: 'filled'
|
|
122
|
-
})
|
|
123
|
-
} finally {
|
|
124
|
-
setIsSending(false)
|
|
108
|
+
if (existingDocument.driveId) {
|
|
109
|
+
const link = await getFederatedShareLink(existingDocument)
|
|
110
|
+
setSharingLink(link)
|
|
111
|
+
} else {
|
|
112
|
+
setSharingLink(getSharingLink(existingDocument._id))
|
|
125
113
|
}
|
|
126
114
|
}
|
|
127
115
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
116
|
+
fetchSharingLink()
|
|
117
|
+
}, [
|
|
118
|
+
existingDocument,
|
|
119
|
+
documentPermissions,
|
|
120
|
+
getFederatedShareLink,
|
|
121
|
+
getSharingLink,
|
|
122
|
+
getOwner,
|
|
123
|
+
getSharingById
|
|
124
|
+
])
|
|
125
|
+
|
|
126
|
+
const folderName = existingDocument?.name || ''
|
|
127
|
+
|
|
128
|
+
const onSend = async () => {
|
|
129
|
+
if (isSending || pendingRecipients.length === 0) {
|
|
130
|
+
onClose()
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
setIsSending(true)
|
|
135
|
+
setFrozenDoc(existingDocument)
|
|
136
|
+
setFrozenRecipients(existingRecipients)
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
const contacts = await getOrCreateFromArray(
|
|
140
|
+
client,
|
|
141
|
+
pendingRecipients,
|
|
142
|
+
contact => client.create('io.cozy.contacts', contact)
|
|
143
|
+
)
|
|
144
|
+
const readWriteRecipients = selectedOption === 'readOnly' ? [] : contacts
|
|
145
|
+
const readOnlyRecipients = selectedOption === 'readOnly' ? contacts : []
|
|
146
|
+
|
|
147
|
+
await share({
|
|
148
|
+
description: folderName,
|
|
149
|
+
document: existingDocument,
|
|
150
|
+
recipients: readWriteRecipients,
|
|
151
|
+
readOnlyRecipients,
|
|
152
|
+
sharedDrive: true,
|
|
153
|
+
openSharing: false
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
showAlert({
|
|
157
|
+
message: t('FederatedFolder.successNotification'),
|
|
158
|
+
severity: 'success',
|
|
159
|
+
variant: 'filled'
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
onClose()
|
|
163
|
+
} catch (_err) {
|
|
164
|
+
showAlert({
|
|
165
|
+
message: t('FederatedFolder.errorNotification'),
|
|
166
|
+
severity: 'error',
|
|
167
|
+
variant: 'filled'
|
|
168
|
+
})
|
|
169
|
+
} finally {
|
|
170
|
+
setIsSending(false)
|
|
171
|
+
}
|
|
155
172
|
}
|
|
156
|
-
|
|
173
|
+
|
|
174
|
+
const existingRecipients = existingDocument
|
|
175
|
+
? getRecipients(existingDocument._id)
|
|
176
|
+
: []
|
|
177
|
+
|
|
178
|
+
const modalTitle = t('FederatedFolder.shareTitle', { name: folderName })
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<FixedDialog
|
|
182
|
+
open
|
|
183
|
+
disableGutters
|
|
184
|
+
onClose={handleCloseRequest}
|
|
185
|
+
title={modalTitle}
|
|
186
|
+
classes={{ paper: 'u-ov-visible' }}
|
|
187
|
+
componentsProps={{
|
|
188
|
+
dialogContent: { className: 'u-ov-visible' }
|
|
189
|
+
}}
|
|
190
|
+
content={
|
|
191
|
+
<div>
|
|
192
|
+
<div className="u-ph-2">
|
|
193
|
+
<AntivirusAlert
|
|
194
|
+
document={isSending ? frozenDoc : existingDocument}
|
|
195
|
+
/>
|
|
196
|
+
<Typography variant="h6" className="u-mt-1-half u-mb-half">
|
|
197
|
+
{t('Share.contacts.addUsers')}
|
|
198
|
+
</Typography>
|
|
199
|
+
<DumbShareByEmail
|
|
200
|
+
currentRecipients={
|
|
201
|
+
isSending ? frozenRecipients : existingRecipients
|
|
202
|
+
}
|
|
203
|
+
document={isSending ? frozenDoc : existingDocument}
|
|
204
|
+
documentType="Files"
|
|
205
|
+
pendingRecipients={pendingRecipients}
|
|
206
|
+
onPendingRecipientsChange={setPendingRecipients}
|
|
207
|
+
selectedOption={selectedOption}
|
|
208
|
+
onSelectedOptionChange={setSelectedOption}
|
|
209
|
+
/>
|
|
210
|
+
</div>
|
|
211
|
+
<WhoHasAccess
|
|
212
|
+
isOwner
|
|
213
|
+
isSharedDrive
|
|
214
|
+
recipients={isSending ? frozenRecipients : existingRecipients}
|
|
215
|
+
document={isSending ? frozenDoc : existingDocument}
|
|
216
|
+
documentType="Files"
|
|
217
|
+
className="u-w-100"
|
|
218
|
+
onRevoke={revoke}
|
|
219
|
+
link={sharingLink}
|
|
220
|
+
/>
|
|
221
|
+
</div>
|
|
222
|
+
}
|
|
223
|
+
actions={
|
|
224
|
+
<>
|
|
225
|
+
<ShareByLink
|
|
226
|
+
link={sharingLink}
|
|
227
|
+
document={isSending ? frozenDoc : existingDocument}
|
|
228
|
+
documentType="Files"
|
|
229
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
230
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
231
|
+
/>
|
|
232
|
+
<Button
|
|
233
|
+
variant="primary"
|
|
234
|
+
label={t('FederatedFolder.share')}
|
|
235
|
+
disabled={isSending}
|
|
236
|
+
onClick={onSend}
|
|
237
|
+
/>
|
|
238
|
+
</>
|
|
239
|
+
}
|
|
240
|
+
/>
|
|
241
|
+
)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export const FederatedFolderModal = withLocales(props => (
|
|
245
|
+
<ConfirmDialogProvider>
|
|
246
|
+
<FederatedFolderModalContent {...props} />
|
|
247
|
+
</ConfirmDialogProvider>
|
|
248
|
+
))
|
|
157
249
|
|
|
158
250
|
FederatedFolderModal.propTypes = {
|
|
159
251
|
onClose: PropTypes.func.isRequired,
|
|
@@ -41,41 +41,6 @@ jest.mock('../../hooks/usePendingRecipients', () => ({
|
|
|
41
41
|
usePendingRecipients: jest.fn()
|
|
42
42
|
}))
|
|
43
43
|
|
|
44
|
-
jest.mock('../SharedFolder/DumbBatchSharedFolderModal', () => ({
|
|
45
|
-
DumbBatchSharedFolderModal: ({
|
|
46
|
-
title,
|
|
47
|
-
recipients,
|
|
48
|
-
onRevoke,
|
|
49
|
-
onSend,
|
|
50
|
-
onClose,
|
|
51
|
-
sharingLink,
|
|
52
|
-
pendingRecipients,
|
|
53
|
-
selectedOption
|
|
54
|
-
}) => (
|
|
55
|
-
<div data-testid="dumb-modal">
|
|
56
|
-
<span data-testid="title">{title}</span>
|
|
57
|
-
<span data-testid="sharing-link">{sharingLink}</span>
|
|
58
|
-
<span data-testid="recipients-count">{recipients.length}</span>
|
|
59
|
-
<span data-testid="pending-recipients-count">
|
|
60
|
-
{pendingRecipients.length}
|
|
61
|
-
</span>
|
|
62
|
-
<span data-testid="selected-option">{selectedOption}</span>
|
|
63
|
-
<button data-testid="btn-send" onClick={onSend}>
|
|
64
|
-
Send
|
|
65
|
-
</button>
|
|
66
|
-
<button
|
|
67
|
-
data-testid="btn-revoke"
|
|
68
|
-
onClick={() => onRevoke({ _id: 'folder-123' }, 'abc', 1)}
|
|
69
|
-
>
|
|
70
|
-
Revoke
|
|
71
|
-
</button>
|
|
72
|
-
<button data-testid="btn-close" onClick={onClose}>
|
|
73
|
-
Close
|
|
74
|
-
</button>
|
|
75
|
-
</div>
|
|
76
|
-
)
|
|
77
|
-
}))
|
|
78
|
-
|
|
79
44
|
const mockDocument = {
|
|
80
45
|
_id: 'folder-123',
|
|
81
46
|
name: 'My Test Folder',
|
|
@@ -145,46 +110,22 @@ describe('FederatedFolderModal', () => {
|
|
|
145
110
|
|
|
146
111
|
describe('initialization', () => {
|
|
147
112
|
it('should pass document name as title', async () => {
|
|
148
|
-
const {
|
|
113
|
+
const { findByText } = setup()
|
|
149
114
|
|
|
150
|
-
await
|
|
151
|
-
expect(getByTestId('title').textContent).toBe('Share "My Test Folder"')
|
|
152
|
-
})
|
|
115
|
+
await findByText('Share "My Test Folder"')
|
|
153
116
|
})
|
|
154
117
|
|
|
155
118
|
it('should pass default title when document has no name', async () => {
|
|
156
119
|
const documentWithoutName = { _id: 'folder-456', path: '/test' }
|
|
157
|
-
const {
|
|
158
|
-
|
|
159
|
-
await waitFor(() => {
|
|
160
|
-
expect(getByTestId('title').textContent).toBe('Share ""')
|
|
161
|
-
})
|
|
162
|
-
})
|
|
120
|
+
const { findByText } = setup({ document: documentWithoutName })
|
|
163
121
|
|
|
164
|
-
|
|
165
|
-
const { getByTestId } = setup()
|
|
166
|
-
|
|
167
|
-
await waitFor(() => {
|
|
168
|
-
expect(getByTestId('sharing-link').textContent).toBe(
|
|
169
|
-
'https://example.com/share/abc123'
|
|
170
|
-
)
|
|
171
|
-
})
|
|
122
|
+
await findByText('Share ""')
|
|
172
123
|
})
|
|
173
124
|
|
|
174
|
-
it('should
|
|
175
|
-
const {
|
|
125
|
+
it('should show Copy link', async () => {
|
|
126
|
+
const { findByText } = setup()
|
|
176
127
|
|
|
177
|
-
await
|
|
178
|
-
expect(getByTestId('sharing-link').textContent).toBe('')
|
|
179
|
-
})
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
it('should pass selectedOption from usePendingRecipients', async () => {
|
|
183
|
-
const { getByTestId } = setup()
|
|
184
|
-
|
|
185
|
-
await waitFor(() => {
|
|
186
|
-
expect(getByTestId('selected-option').textContent).toBe('readWrite')
|
|
187
|
-
})
|
|
128
|
+
await findByText('Copy link')
|
|
188
129
|
})
|
|
189
130
|
})
|
|
190
131
|
|
|
@@ -193,13 +134,11 @@ describe('FederatedFolderModal', () => {
|
|
|
193
134
|
|
|
194
135
|
it('should call onClose and skip share when there are no pending recipients', async () => {
|
|
195
136
|
// pendingRecipients defaults to [] via beforeEach
|
|
196
|
-
const {
|
|
137
|
+
const { findByText } = setup()
|
|
197
138
|
|
|
198
|
-
await
|
|
199
|
-
expect(getByTestId('btn-send')).toBeTruthy()
|
|
200
|
-
})
|
|
139
|
+
const sendButton = await findByText('Done')
|
|
201
140
|
|
|
202
|
-
fireEvent.click(
|
|
141
|
+
fireEvent.click(sendButton)
|
|
203
142
|
|
|
204
143
|
await waitFor(() => {
|
|
205
144
|
expect(mockOnClose).toHaveBeenCalled()
|
|
@@ -216,13 +155,11 @@ describe('FederatedFolderModal', () => {
|
|
|
216
155
|
})
|
|
217
156
|
getOrCreateFromArray.mockResolvedValue([pendingRecipient])
|
|
218
157
|
mockShare.mockResolvedValueOnce({})
|
|
219
|
-
const {
|
|
158
|
+
const { findByText } = setup()
|
|
220
159
|
|
|
221
|
-
await
|
|
222
|
-
expect(getByTestId('btn-send')).toBeTruthy()
|
|
223
|
-
})
|
|
160
|
+
const sendButton = await findByText('Done')
|
|
224
161
|
|
|
225
|
-
fireEvent.click(
|
|
162
|
+
fireEvent.click(sendButton)
|
|
226
163
|
|
|
227
164
|
await waitFor(() => {
|
|
228
165
|
expect(mockShare).toHaveBeenCalledWith({
|
|
@@ -245,13 +182,11 @@ describe('FederatedFolderModal', () => {
|
|
|
245
182
|
})
|
|
246
183
|
getOrCreateFromArray.mockResolvedValue([pendingRecipient])
|
|
247
184
|
mockShare.mockResolvedValueOnce({})
|
|
248
|
-
const {
|
|
185
|
+
const { findByText } = setup()
|
|
249
186
|
|
|
250
|
-
await
|
|
251
|
-
expect(getByTestId('btn-send')).toBeTruthy()
|
|
252
|
-
})
|
|
187
|
+
const sendButton = await findByText('Done')
|
|
253
188
|
|
|
254
|
-
fireEvent.click(
|
|
189
|
+
fireEvent.click(sendButton)
|
|
255
190
|
|
|
256
191
|
await waitFor(() => {
|
|
257
192
|
expect(mockShowAlert).toHaveBeenCalledWith({
|
|
@@ -272,13 +207,11 @@ describe('FederatedFolderModal', () => {
|
|
|
272
207
|
})
|
|
273
208
|
getOrCreateFromArray.mockResolvedValue([pendingRecipient])
|
|
274
209
|
mockShare.mockRejectedValueOnce(new Error('Share failed'))
|
|
275
|
-
const {
|
|
210
|
+
const { findByText } = setup()
|
|
276
211
|
|
|
277
|
-
await
|
|
278
|
-
expect(getByTestId('btn-send')).toBeTruthy()
|
|
279
|
-
})
|
|
212
|
+
const sendButton = await findByText('Done')
|
|
280
213
|
|
|
281
|
-
fireEvent.click(
|
|
214
|
+
fireEvent.click(sendButton)
|
|
282
215
|
|
|
283
216
|
await waitFor(() => {
|
|
284
217
|
expect(mockShowAlert).toHaveBeenCalledWith({
|
|
@@ -291,66 +224,58 @@ describe('FederatedFolderModal', () => {
|
|
|
291
224
|
})
|
|
292
225
|
})
|
|
293
226
|
|
|
294
|
-
describe('
|
|
295
|
-
it('should call
|
|
296
|
-
|
|
297
|
-
const { getByTestId } = setup()
|
|
227
|
+
describe('onClose callback', () => {
|
|
228
|
+
it('should call onClose when close button is clicked', async () => {
|
|
229
|
+
const { findByRole } = setup()
|
|
298
230
|
|
|
299
|
-
await
|
|
300
|
-
expect(getByTestId('dumb-modal')).toBeTruthy()
|
|
301
|
-
})
|
|
231
|
+
const closeButton = await findByRole('button', { name: /close/i })
|
|
302
232
|
|
|
303
|
-
fireEvent.click(
|
|
233
|
+
fireEvent.click(closeButton)
|
|
304
234
|
|
|
305
|
-
|
|
306
|
-
expect(mockRevoke).toHaveBeenCalledWith({ _id: 'folder-123' }, 'abc', 1)
|
|
307
|
-
})
|
|
235
|
+
expect(mockOnClose).toHaveBeenCalled()
|
|
308
236
|
})
|
|
309
|
-
})
|
|
310
|
-
|
|
311
|
-
describe('onClose callback', () => {
|
|
312
|
-
it('should call onClose when close button is clicked', async () => {
|
|
313
|
-
const { getByTestId } = setup()
|
|
314
237
|
|
|
315
|
-
|
|
316
|
-
|
|
238
|
+
it('should ask confirmation when close button is clicked with pending recipients', async () => {
|
|
239
|
+
usePendingRecipients.mockReturnValue({
|
|
240
|
+
pendingRecipients: [{ name: 'Alice', email: 'alice@example.com' }],
|
|
241
|
+
setPendingRecipients: jest.fn(),
|
|
242
|
+
selectedOption: 'readWrite',
|
|
243
|
+
setSelectedOption: jest.fn()
|
|
317
244
|
})
|
|
318
245
|
|
|
319
|
-
|
|
246
|
+
const { getByRole, findByRole, getByText } = setup()
|
|
320
247
|
|
|
321
|
-
|
|
322
|
-
})
|
|
323
|
-
})
|
|
248
|
+
const closeButton = await findByRole('button', { name: /close/i })
|
|
324
249
|
|
|
325
|
-
|
|
326
|
-
const existingRecipients = [
|
|
327
|
-
{
|
|
328
|
-
index: 'sharing-abc-member-0',
|
|
329
|
-
name: 'Charlie',
|
|
330
|
-
email: 'charlie@example.com',
|
|
331
|
-
status: 'owner',
|
|
332
|
-
type: 'two-way',
|
|
333
|
-
sharingId: 'abc',
|
|
334
|
-
memberIndex: 0
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
index: 'sharing-abc-member-1',
|
|
338
|
-
name: 'Diana',
|
|
339
|
-
email: 'diana@example.com',
|
|
340
|
-
status: 'ready',
|
|
341
|
-
type: 'one-way',
|
|
342
|
-
sharingId: 'abc',
|
|
343
|
-
memberIndex: 1
|
|
344
|
-
}
|
|
345
|
-
]
|
|
250
|
+
fireEvent.click(closeButton)
|
|
346
251
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
const { getByTestId } = setup()
|
|
252
|
+
expect(getByText("Discard the changes you haven't saved?")).toBeTruthy()
|
|
253
|
+
expect(mockOnClose).not.toHaveBeenCalled()
|
|
350
254
|
|
|
351
|
-
|
|
352
|
-
|
|
255
|
+
fireEvent.click(getByRole('button', { name: 'Cancel' }))
|
|
256
|
+
|
|
257
|
+
expect(mockOnClose).not.toHaveBeenCalled()
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
it('should close after discard confirmation', async () => {
|
|
261
|
+
usePendingRecipients.mockReturnValue({
|
|
262
|
+
pendingRecipients: [{ name: 'Alice', email: 'alice@example.com' }],
|
|
263
|
+
setPendingRecipients: jest.fn(),
|
|
264
|
+
selectedOption: 'readWrite',
|
|
265
|
+
setSelectedOption: jest.fn()
|
|
353
266
|
})
|
|
267
|
+
|
|
268
|
+
const { getByRole, findByRole, getByText } = setup()
|
|
269
|
+
|
|
270
|
+
const closeButton = await findByRole('button', { name: /close/i })
|
|
271
|
+
|
|
272
|
+
fireEvent.click(closeButton)
|
|
273
|
+
|
|
274
|
+
expect(getByText("Discard the changes you haven't saved?")).toBeTruthy()
|
|
275
|
+
|
|
276
|
+
fireEvent.click(getByRole('button', { name: 'Discard' }))
|
|
277
|
+
|
|
278
|
+
expect(mockOnClose).toHaveBeenCalledTimes(1)
|
|
354
279
|
})
|
|
355
280
|
})
|
|
356
281
|
})
|