cozy-sharing 33.1.2 → 33.2.1
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 +12 -0
- package/dist/components/FederatedFolder/FederatedFolderModal.js +32 -88
- package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +188 -86
- package/dist/components/ShareDialogCozyToCozy.js +6 -0
- package/dist/components/ShareDialogCozyToCozy.spec.js +3 -0
- package/dist/components/ShareDialogOnlyByLink.js +7 -3
- package/dist/components/ShareDialogOnlyByLink.spec.js +75 -0
- package/package.json +2 -2
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +7 -36
- package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +67 -2
- package/src/components/ShareDialogCozyToCozy.jsx +4 -0
- package/src/components/ShareDialogCozyToCozy.spec.jsx +1 -0
- package/src/components/ShareDialogOnlyByLink.jsx +5 -3
- package/src/components/ShareDialogOnlyByLink.spec.jsx +65 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [33.2.1](https://github.com/cozy/cozy-libs/compare/cozy-sharing@33.2.0...cozy-sharing@33.2.1) (2026-06-09)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **cozy-sharing:** Refresh link state in share modal ([dfb6dd3](https://github.com/cozy/cozy-libs/commit/dfb6dd39e81b13a7da37ab8f5b4480fb645df01e))
|
|
11
|
+
|
|
12
|
+
# [33.2.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@33.1.2...cozy-sharing@33.2.0) (2026-06-09)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- **cozy-sharing:** Show progress icon on done button during share ([885a715](https://github.com/cozy/cozy-libs/commit/885a71568a96354e3d962296a205efb05881a5d1))
|
|
17
|
+
|
|
6
18
|
## [33.1.2](https://github.com/cozy/cozy-libs/compare/cozy-sharing@33.1.1...cozy-sharing@33.1.2) (2026-06-08)
|
|
7
19
|
|
|
8
20
|
### Bug Fixes
|
|
@@ -2,7 +2,7 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
|
2
2
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
3
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
|
-
import React, { useCallback,
|
|
5
|
+
import React, { useCallback, useState } from 'react';
|
|
6
6
|
import { useClient } from 'cozy-client';
|
|
7
7
|
import Button from 'cozy-ui/transpiled/react/Buttons';
|
|
8
8
|
import { FixedDialog } from 'cozy-ui/transpiled/react/CozyDialogs';
|
|
@@ -51,9 +51,6 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
51
51
|
share = _useSharingContext.share,
|
|
52
52
|
getSharingLink = _useSharingContext.getSharingLink,
|
|
53
53
|
getFederatedShareLink = _useSharingContext.getFederatedShareLink,
|
|
54
|
-
getDocumentPermissions = _useSharingContext.getDocumentPermissions,
|
|
55
|
-
getOwner = _useSharingContext.getOwner,
|
|
56
|
-
getSharingById = _useSharingContext.getSharingById,
|
|
57
54
|
getRecipients = _useSharingContext.getRecipients,
|
|
58
55
|
hasSharedChild = _useSharingContext.hasSharedChild,
|
|
59
56
|
hasSharedParent = _useSharingContext.hasSharedParent,
|
|
@@ -66,11 +63,6 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
66
63
|
showConfirmDialog = _useConfirmDialog.showConfirmDialog,
|
|
67
64
|
closeConfirmDialog = _useConfirmDialog.closeConfirmDialog;
|
|
68
65
|
|
|
69
|
-
var _useState = useState(null),
|
|
70
|
-
_useState2 = _slicedToArray(_useState, 2),
|
|
71
|
-
sharingLink = _useState2[0],
|
|
72
|
-
setSharingLink = _useState2[1];
|
|
73
|
-
|
|
74
66
|
var _usePendingRecipients = usePendingRecipients(),
|
|
75
67
|
pendingRecipients = _usePendingRecipients.pendingRecipients,
|
|
76
68
|
setPendingRecipients = _usePendingRecipients.setPendingRecipients,
|
|
@@ -83,20 +75,20 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
83
75
|
// we do not use the reactive existingDocument and existingRecipients.
|
|
84
76
|
|
|
85
77
|
|
|
86
|
-
var
|
|
78
|
+
var _useState = useState(false),
|
|
79
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
80
|
+
isSending = _useState2[0],
|
|
81
|
+
setIsSending = _useState2[1];
|
|
82
|
+
|
|
83
|
+
var _useState3 = useState(null),
|
|
87
84
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
frozenDoc = _useState4[0],
|
|
86
|
+
setFrozenDoc = _useState4[1];
|
|
90
87
|
|
|
91
88
|
var _useState5 = useState(null),
|
|
92
89
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
var _useState7 = useState(null),
|
|
97
|
-
_useState8 = _slicedToArray(_useState7, 2),
|
|
98
|
-
frozenRecipients = _useState8[0],
|
|
99
|
-
setFrozenRecipients = _useState8[1];
|
|
90
|
+
frozenRecipients = _useState6[0],
|
|
91
|
+
setFrozenRecipients = _useState6[1];
|
|
100
92
|
|
|
101
93
|
var handleCloseRequest = useCallback(function () {
|
|
102
94
|
if (pendingRecipients.length === 0) {
|
|
@@ -122,55 +114,6 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
122
114
|
}))
|
|
123
115
|
});
|
|
124
116
|
}, [closeConfirmDialog, onClose, pendingRecipients.length, showConfirmDialog, t]);
|
|
125
|
-
var documentPermissions = useMemo(function () {
|
|
126
|
-
return existingDocument ? getDocumentPermissions(existingDocument._id) : [];
|
|
127
|
-
}, [existingDocument, getDocumentPermissions]);
|
|
128
|
-
useEffect(function () {
|
|
129
|
-
var fetchSharingLink = /*#__PURE__*/function () {
|
|
130
|
-
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
131
|
-
var link;
|
|
132
|
-
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
133
|
-
while (1) switch (_context.prev = _context.next) {
|
|
134
|
-
case 0:
|
|
135
|
-
if (existingDocument) {
|
|
136
|
-
_context.next = 2;
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return _context.abrupt("return");
|
|
141
|
-
|
|
142
|
-
case 2:
|
|
143
|
-
if (!existingDocument.driveId) {
|
|
144
|
-
_context.next = 9;
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
_context.next = 5;
|
|
149
|
-
return getFederatedShareLink(existingDocument);
|
|
150
|
-
|
|
151
|
-
case 5:
|
|
152
|
-
link = _context.sent;
|
|
153
|
-
setSharingLink(link);
|
|
154
|
-
_context.next = 10;
|
|
155
|
-
break;
|
|
156
|
-
|
|
157
|
-
case 9:
|
|
158
|
-
setSharingLink(getSharingLink(existingDocument._id));
|
|
159
|
-
|
|
160
|
-
case 10:
|
|
161
|
-
case "end":
|
|
162
|
-
return _context.stop();
|
|
163
|
-
}
|
|
164
|
-
}, _callee);
|
|
165
|
-
}));
|
|
166
|
-
|
|
167
|
-
return function fetchSharingLink() {
|
|
168
|
-
return _ref2.apply(this, arguments);
|
|
169
|
-
};
|
|
170
|
-
}();
|
|
171
|
-
|
|
172
|
-
fetchSharingLink();
|
|
173
|
-
}, [existingDocument, documentPermissions, getFederatedShareLink, getSharingLink, getOwner, getSharingById]);
|
|
174
117
|
var folderName = (existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.name) || '';
|
|
175
118
|
var documentPath = existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.path;
|
|
176
119
|
var hasParentRestriction = Boolean((existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.driveId) || documentPath && hasSharedParent(documentPath));
|
|
@@ -178,34 +121,34 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
178
121
|
var canShareByEmail = !hasParentRestriction && !hasChildRestriction;
|
|
179
122
|
|
|
180
123
|
var onSend = /*#__PURE__*/function () {
|
|
181
|
-
var
|
|
124
|
+
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
182
125
|
var contacts, readWriteRecipients, readOnlyRecipients;
|
|
183
|
-
return _regeneratorRuntime.wrap(function
|
|
184
|
-
while (1) switch (
|
|
126
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
127
|
+
while (1) switch (_context.prev = _context.next) {
|
|
185
128
|
case 0:
|
|
186
129
|
if (!(isSending || pendingRecipients.length === 0)) {
|
|
187
|
-
|
|
130
|
+
_context.next = 3;
|
|
188
131
|
break;
|
|
189
132
|
}
|
|
190
133
|
|
|
191
134
|
onClose();
|
|
192
|
-
return
|
|
135
|
+
return _context.abrupt("return");
|
|
193
136
|
|
|
194
137
|
case 3:
|
|
195
138
|
setIsSending(true);
|
|
196
139
|
setFrozenDoc(existingDocument);
|
|
197
140
|
setFrozenRecipients(existingRecipients);
|
|
198
|
-
|
|
199
|
-
|
|
141
|
+
_context.prev = 6;
|
|
142
|
+
_context.next = 9;
|
|
200
143
|
return getOrCreateFromArray(client, pendingRecipients, function (contact) {
|
|
201
144
|
return client.create('io.cozy.contacts', contact);
|
|
202
145
|
});
|
|
203
146
|
|
|
204
147
|
case 9:
|
|
205
|
-
contacts =
|
|
148
|
+
contacts = _context.sent;
|
|
206
149
|
readWriteRecipients = selectedOption === 'readOnly' ? [] : contacts;
|
|
207
150
|
readOnlyRecipients = selectedOption === 'readOnly' ? contacts : [];
|
|
208
|
-
|
|
151
|
+
_context.next = 14;
|
|
209
152
|
return share({
|
|
210
153
|
description: folderName,
|
|
211
154
|
document: existingDocument,
|
|
@@ -222,12 +165,12 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
222
165
|
variant: 'filled'
|
|
223
166
|
});
|
|
224
167
|
onClose();
|
|
225
|
-
|
|
168
|
+
_context.next = 21;
|
|
226
169
|
break;
|
|
227
170
|
|
|
228
171
|
case 18:
|
|
229
|
-
|
|
230
|
-
|
|
172
|
+
_context.prev = 18;
|
|
173
|
+
_context.t0 = _context["catch"](6);
|
|
231
174
|
showAlert({
|
|
232
175
|
message: t('FederatedFolder.errorNotification'),
|
|
233
176
|
severity: 'error',
|
|
@@ -235,23 +178,24 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
235
178
|
});
|
|
236
179
|
|
|
237
180
|
case 21:
|
|
238
|
-
|
|
181
|
+
_context.prev = 21;
|
|
239
182
|
setIsSending(false);
|
|
240
|
-
return
|
|
183
|
+
return _context.finish(21);
|
|
241
184
|
|
|
242
185
|
case 24:
|
|
243
186
|
case "end":
|
|
244
|
-
return
|
|
187
|
+
return _context.stop();
|
|
245
188
|
}
|
|
246
|
-
},
|
|
189
|
+
}, _callee, null, [[6, 18, 21, 24]]);
|
|
247
190
|
}));
|
|
248
191
|
|
|
249
192
|
return function onSend() {
|
|
250
|
-
return
|
|
193
|
+
return _ref2.apply(this, arguments);
|
|
251
194
|
};
|
|
252
195
|
}();
|
|
253
196
|
|
|
254
197
|
var existingRecipients = existingDocument ? getRecipients(existingDocument._id) : [];
|
|
198
|
+
var displayedLink = existingDocument !== null && existingDocument !== void 0 && existingDocument.driveId ? getFederatedShareLink(existingDocument) : getSharingLink(existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument._id);
|
|
255
199
|
var modalTitle = t('FederatedFolder.shareTitle', {
|
|
256
200
|
name: folderName
|
|
257
201
|
});
|
|
@@ -296,10 +240,10 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
296
240
|
documentType: "Files",
|
|
297
241
|
className: "u-w-100",
|
|
298
242
|
onRevoke: revoke,
|
|
299
|
-
link:
|
|
243
|
+
link: displayedLink
|
|
300
244
|
})),
|
|
301
245
|
actions: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ShareByLink, {
|
|
302
|
-
link:
|
|
246
|
+
link: displayedLink,
|
|
303
247
|
document: isSending ? frozenDoc : existingDocument,
|
|
304
248
|
documentType: "Files",
|
|
305
249
|
showGenerateLinkButton: showGenerateLinkButton,
|
|
@@ -307,7 +251,7 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
307
251
|
}), canShareByEmail && /*#__PURE__*/React.createElement(Button, {
|
|
308
252
|
variant: "primary",
|
|
309
253
|
label: t('FederatedFolder.share'),
|
|
310
|
-
|
|
254
|
+
busy: isSending,
|
|
311
255
|
onClick: onSend
|
|
312
256
|
}))
|
|
313
257
|
});
|
|
@@ -7,7 +7,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
|
|
|
7
7
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
8
8
|
|
|
9
9
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
10
|
-
import { fireEvent, render, waitFor } from '@testing-library/react';
|
|
10
|
+
import { act, fireEvent, render, waitFor } from '@testing-library/react';
|
|
11
11
|
import React from 'react';
|
|
12
12
|
import { createMockClient } from 'cozy-client';
|
|
13
13
|
import { FederatedFolderModal } from './FederatedFolderModal';
|
|
@@ -15,6 +15,7 @@ import { getOrCreateFromArray } from '../../helpers/contacts';
|
|
|
15
15
|
import { usePendingRecipients } from '../../hooks/usePendingRecipients';
|
|
16
16
|
import AppLike from '../SharingBanner/test/AppLike';
|
|
17
17
|
var mockShare = jest.fn();
|
|
18
|
+
var mockShareByLink = jest.fn();
|
|
18
19
|
var mockRevoke = jest.fn();
|
|
19
20
|
var mockGetSharingLink = jest.fn();
|
|
20
21
|
var mockGetFederatedShareLink = jest.fn();
|
|
@@ -28,10 +29,13 @@ jest.mock('../../hooks/useSharingContext', function () {
|
|
|
28
29
|
useSharingContext: function useSharingContext() {
|
|
29
30
|
return {
|
|
30
31
|
share: mockShare,
|
|
32
|
+
shareByLink: mockShareByLink,
|
|
31
33
|
revoke: mockRevoke,
|
|
32
34
|
getSharingLink: mockGetSharingLink,
|
|
33
35
|
getFederatedShareLink: mockGetFederatedShareLink,
|
|
34
36
|
getDocumentPermissions: jest.fn().mockReturnValue([]),
|
|
37
|
+
getOwner: jest.fn(),
|
|
38
|
+
getSharingById: jest.fn(),
|
|
35
39
|
getRecipients: mockGetRecipients,
|
|
36
40
|
hasSharedChild: mockHasSharedChild,
|
|
37
41
|
hasSharedParent: mockHasSharedParent
|
|
@@ -63,6 +67,11 @@ jest.mock('../../hooks/usePendingRecipients', function () {
|
|
|
63
67
|
usePendingRecipients: jest.fn()
|
|
64
68
|
};
|
|
65
69
|
});
|
|
70
|
+
jest.mock('../ShareByLink', function () {
|
|
71
|
+
return function () {
|
|
72
|
+
return /*#__PURE__*/React.createElement("button", null, "Copy link");
|
|
73
|
+
};
|
|
74
|
+
});
|
|
66
75
|
var mockDocument = {
|
|
67
76
|
_id: 'folder-123',
|
|
68
77
|
name: 'My Test Folder',
|
|
@@ -109,10 +118,25 @@ describe('FederatedFolderModal', function () {
|
|
|
109
118
|
beforeEach(function () {
|
|
110
119
|
jest.clearAllMocks();
|
|
111
120
|
mockGetSharingLink.mockReturnValue('https://example.com/share/abc123');
|
|
112
|
-
mockGetFederatedShareLink.
|
|
121
|
+
mockGetFederatedShareLink.mockReturnValue('https://example.com/share/federated-abc123');
|
|
113
122
|
mockGetRecipients.mockReturnValue([]);
|
|
114
123
|
mockHasSharedChild.mockReturnValue(false);
|
|
115
124
|
mockHasSharedParent.mockReturnValue(false);
|
|
125
|
+
mockShareByLink.mockResolvedValue({
|
|
126
|
+
data: {
|
|
127
|
+
_id: 'permission-id',
|
|
128
|
+
attributes: {
|
|
129
|
+
shortcodes: {
|
|
130
|
+
code: 'abc123'
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
Object.assign(navigator, {
|
|
136
|
+
clipboard: {
|
|
137
|
+
writeText: jest.fn()
|
|
138
|
+
}
|
|
139
|
+
});
|
|
116
140
|
client = createTestClient();
|
|
117
141
|
sharingContextValue = createSharingContextValue();
|
|
118
142
|
usePendingRecipients.mockReturnValue({
|
|
@@ -190,18 +214,44 @@ describe('FederatedFolderModal', function () {
|
|
|
190
214
|
}
|
|
191
215
|
}, _callee3);
|
|
192
216
|
})));
|
|
193
|
-
it('should
|
|
194
|
-
var _setup4, findByText, queryByText;
|
|
217
|
+
it('should show link access as soon as a link is generated', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
|
|
218
|
+
var _setup4, findByText, queryByText, rerender;
|
|
195
219
|
|
|
196
220
|
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
197
221
|
while (1) switch (_context4.prev = _context4.next) {
|
|
198
222
|
case 0:
|
|
199
|
-
|
|
223
|
+
mockGetSharingLink.mockReturnValue(null);
|
|
224
|
+
_setup4 = setup(), findByText = _setup4.findByText, queryByText = _setup4.queryByText, rerender = _setup4.rerender;
|
|
225
|
+
expect(queryByText('Anyone with the link')).toBe(null);
|
|
226
|
+
mockGetSharingLink.mockReturnValue('https://example.com/share/abc123');
|
|
227
|
+
rerender( /*#__PURE__*/React.createElement(AppLike, {
|
|
228
|
+
client: client,
|
|
229
|
+
sharingContextValue: sharingContextValue
|
|
230
|
+
}, /*#__PURE__*/React.createElement(FederatedFolderModal, {
|
|
231
|
+
document: mockDocument,
|
|
232
|
+
onClose: mockOnClose
|
|
233
|
+
})));
|
|
234
|
+
_context4.next = 7;
|
|
235
|
+
return findByText('Anyone with the link');
|
|
236
|
+
|
|
237
|
+
case 7:
|
|
238
|
+
case "end":
|
|
239
|
+
return _context4.stop();
|
|
240
|
+
}
|
|
241
|
+
}, _callee4);
|
|
242
|
+
})));
|
|
243
|
+
it('should hide share by email when document is in federated shared folder received by current user', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
|
|
244
|
+
var _setup5, findByText, queryByText;
|
|
245
|
+
|
|
246
|
+
return _regeneratorRuntime.wrap(function _callee5$(_context5) {
|
|
247
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
248
|
+
case 0:
|
|
249
|
+
_setup5 = setup({
|
|
200
250
|
document: _objectSpread(_objectSpread({}, mockDocument), {}, {
|
|
201
251
|
driveId: 'federated-folder-id'
|
|
202
252
|
})
|
|
203
|
-
}), findByText =
|
|
204
|
-
|
|
253
|
+
}), findByText = _setup5.findByText, queryByText = _setup5.queryByText;
|
|
254
|
+
_context5.next = 3;
|
|
205
255
|
return findByText('Copy link');
|
|
206
256
|
|
|
207
257
|
case 3:
|
|
@@ -210,34 +260,34 @@ describe('FederatedFolderModal', function () {
|
|
|
210
260
|
|
|
211
261
|
case 5:
|
|
212
262
|
case "end":
|
|
213
|
-
return
|
|
263
|
+
return _context5.stop();
|
|
214
264
|
}
|
|
215
|
-
},
|
|
265
|
+
}, _callee5);
|
|
216
266
|
})));
|
|
217
|
-
it('should show only by link message when document is in federated shared folder received by current user', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
218
|
-
var
|
|
267
|
+
it('should show only by link message when document is in federated shared folder received by current user', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
|
|
268
|
+
var _setup6, findByText;
|
|
219
269
|
|
|
220
|
-
return _regeneratorRuntime.wrap(function
|
|
221
|
-
while (1) switch (
|
|
270
|
+
return _regeneratorRuntime.wrap(function _callee6$(_context6) {
|
|
271
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
222
272
|
case 0:
|
|
223
|
-
|
|
273
|
+
_setup6 = setup({
|
|
224
274
|
document: _objectSpread(_objectSpread({}, mockDocument), {}, {
|
|
225
275
|
driveId: 'federated-folder-id',
|
|
226
276
|
type: 'directory'
|
|
227
277
|
})
|
|
228
|
-
}), findByText =
|
|
229
|
-
|
|
278
|
+
}), findByText = _setup6.findByText;
|
|
279
|
+
_context6.next = 3;
|
|
230
280
|
return findByText('This folder can only be shared by link, because');
|
|
231
281
|
|
|
232
282
|
case 3:
|
|
233
|
-
|
|
283
|
+
_context6.next = 5;
|
|
234
284
|
return findByText('it has a shared parent');
|
|
235
285
|
|
|
236
286
|
case 5:
|
|
237
287
|
case "end":
|
|
238
|
-
return
|
|
288
|
+
return _context6.stop();
|
|
239
289
|
}
|
|
240
|
-
},
|
|
290
|
+
}, _callee6);
|
|
241
291
|
})));
|
|
242
292
|
});
|
|
243
293
|
describe('onSend callback', function () {
|
|
@@ -245,21 +295,21 @@ describe('FederatedFolderModal', function () {
|
|
|
245
295
|
name: 'Alice',
|
|
246
296
|
email: 'alice@example.com'
|
|
247
297
|
};
|
|
248
|
-
it('should call onClose and skip share when there are no pending recipients', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
249
|
-
var
|
|
298
|
+
it('should call onClose and skip share when there are no pending recipients', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7() {
|
|
299
|
+
var _setup7, findByText, sendButton;
|
|
250
300
|
|
|
251
|
-
return _regeneratorRuntime.wrap(function
|
|
252
|
-
while (1) switch (
|
|
301
|
+
return _regeneratorRuntime.wrap(function _callee7$(_context7) {
|
|
302
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
253
303
|
case 0:
|
|
254
304
|
// pendingRecipients defaults to [] via beforeEach
|
|
255
|
-
|
|
256
|
-
|
|
305
|
+
_setup7 = setup(), findByText = _setup7.findByText;
|
|
306
|
+
_context7.next = 3;
|
|
257
307
|
return findByText('Done');
|
|
258
308
|
|
|
259
309
|
case 3:
|
|
260
|
-
sendButton =
|
|
310
|
+
sendButton = _context7.sent;
|
|
261
311
|
fireEvent.click(sendButton);
|
|
262
|
-
|
|
312
|
+
_context7.next = 7;
|
|
263
313
|
return waitFor(function () {
|
|
264
314
|
expect(mockOnClose).toHaveBeenCalled();
|
|
265
315
|
expect(mockShare).not.toHaveBeenCalled();
|
|
@@ -267,15 +317,15 @@ describe('FederatedFolderModal', function () {
|
|
|
267
317
|
|
|
268
318
|
case 7:
|
|
269
319
|
case "end":
|
|
270
|
-
return
|
|
320
|
+
return _context7.stop();
|
|
271
321
|
}
|
|
272
|
-
},
|
|
322
|
+
}, _callee7);
|
|
273
323
|
})));
|
|
274
|
-
it('should call share with correct parameters', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
275
|
-
var
|
|
324
|
+
it('should call share with correct parameters', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
|
|
325
|
+
var _setup8, findByText, sendButton;
|
|
276
326
|
|
|
277
|
-
return _regeneratorRuntime.wrap(function
|
|
278
|
-
while (1) switch (
|
|
327
|
+
return _regeneratorRuntime.wrap(function _callee8$(_context8) {
|
|
328
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
279
329
|
case 0:
|
|
280
330
|
usePendingRecipients.mockReturnValue({
|
|
281
331
|
pendingRecipients: [pendingRecipient],
|
|
@@ -285,14 +335,14 @@ describe('FederatedFolderModal', function () {
|
|
|
285
335
|
});
|
|
286
336
|
getOrCreateFromArray.mockResolvedValue([pendingRecipient]);
|
|
287
337
|
mockShare.mockResolvedValueOnce({});
|
|
288
|
-
|
|
289
|
-
|
|
338
|
+
_setup8 = setup(), findByText = _setup8.findByText;
|
|
339
|
+
_context8.next = 6;
|
|
290
340
|
return findByText('Done');
|
|
291
341
|
|
|
292
342
|
case 6:
|
|
293
|
-
sendButton =
|
|
343
|
+
sendButton = _context8.sent;
|
|
294
344
|
fireEvent.click(sendButton);
|
|
295
|
-
|
|
345
|
+
_context8.next = 10;
|
|
296
346
|
return waitFor(function () {
|
|
297
347
|
expect(mockShare).toHaveBeenCalledWith({
|
|
298
348
|
description: 'My Test Folder',
|
|
@@ -306,15 +356,15 @@ describe('FederatedFolderModal', function () {
|
|
|
306
356
|
|
|
307
357
|
case 10:
|
|
308
358
|
case "end":
|
|
309
|
-
return
|
|
359
|
+
return _context8.stop();
|
|
310
360
|
}
|
|
311
|
-
},
|
|
361
|
+
}, _callee8);
|
|
312
362
|
})));
|
|
313
|
-
it('should show success alert and close modal on successful share', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
314
|
-
var
|
|
363
|
+
it('should show success alert and close modal on successful share', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
|
|
364
|
+
var _setup9, findByText, sendButton;
|
|
315
365
|
|
|
316
|
-
return _regeneratorRuntime.wrap(function
|
|
317
|
-
while (1) switch (
|
|
366
|
+
return _regeneratorRuntime.wrap(function _callee9$(_context9) {
|
|
367
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
318
368
|
case 0:
|
|
319
369
|
usePendingRecipients.mockReturnValue({
|
|
320
370
|
pendingRecipients: [pendingRecipient],
|
|
@@ -324,14 +374,14 @@ describe('FederatedFolderModal', function () {
|
|
|
324
374
|
});
|
|
325
375
|
getOrCreateFromArray.mockResolvedValue([pendingRecipient]);
|
|
326
376
|
mockShare.mockResolvedValueOnce({});
|
|
327
|
-
|
|
328
|
-
|
|
377
|
+
_setup9 = setup(), findByText = _setup9.findByText;
|
|
378
|
+
_context9.next = 6;
|
|
329
379
|
return findByText('Done');
|
|
330
380
|
|
|
331
381
|
case 6:
|
|
332
|
-
sendButton =
|
|
382
|
+
sendButton = _context9.sent;
|
|
333
383
|
fireEvent.click(sendButton);
|
|
334
|
-
|
|
384
|
+
_context9.next = 10;
|
|
335
385
|
return waitFor(function () {
|
|
336
386
|
expect(mockShowAlert).toHaveBeenCalledWith({
|
|
337
387
|
message: 'Folder has been shared',
|
|
@@ -343,15 +393,15 @@ describe('FederatedFolderModal', function () {
|
|
|
343
393
|
|
|
344
394
|
case 10:
|
|
345
395
|
case "end":
|
|
346
|
-
return
|
|
396
|
+
return _context9.stop();
|
|
347
397
|
}
|
|
348
|
-
},
|
|
398
|
+
}, _callee9);
|
|
349
399
|
})));
|
|
350
|
-
it('should show error alert when share fails', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
351
|
-
var
|
|
400
|
+
it('should show error alert when share fails', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
|
|
401
|
+
var _setup10, findByText, sendButton;
|
|
352
402
|
|
|
353
|
-
return _regeneratorRuntime.wrap(function
|
|
354
|
-
while (1) switch (
|
|
403
|
+
return _regeneratorRuntime.wrap(function _callee10$(_context10) {
|
|
404
|
+
while (1) switch (_context10.prev = _context10.next) {
|
|
355
405
|
case 0:
|
|
356
406
|
usePendingRecipients.mockReturnValue({
|
|
357
407
|
pendingRecipients: [pendingRecipient],
|
|
@@ -361,14 +411,14 @@ describe('FederatedFolderModal', function () {
|
|
|
361
411
|
});
|
|
362
412
|
getOrCreateFromArray.mockResolvedValue([pendingRecipient]);
|
|
363
413
|
mockShare.mockRejectedValueOnce(new Error('Share failed'));
|
|
364
|
-
|
|
365
|
-
|
|
414
|
+
_setup10 = setup(), findByText = _setup10.findByText;
|
|
415
|
+
_context10.next = 6;
|
|
366
416
|
return findByText('Done');
|
|
367
417
|
|
|
368
418
|
case 6:
|
|
369
|
-
sendButton =
|
|
419
|
+
sendButton = _context10.sent;
|
|
370
420
|
fireEvent.click(sendButton);
|
|
371
|
-
|
|
421
|
+
_context10.next = 10;
|
|
372
422
|
return waitFor(function () {
|
|
373
423
|
expect(mockShowAlert).toHaveBeenCalledWith({
|
|
374
424
|
message: 'Error while sharing folder',
|
|
@@ -380,40 +430,92 @@ describe('FederatedFolderModal', function () {
|
|
|
380
430
|
|
|
381
431
|
case 10:
|
|
382
432
|
case "end":
|
|
383
|
-
return
|
|
433
|
+
return _context10.stop();
|
|
384
434
|
}
|
|
385
|
-
},
|
|
435
|
+
}, _callee10);
|
|
436
|
+
})));
|
|
437
|
+
it('should show progress icon on Done button while share is in progress', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee12() {
|
|
438
|
+
var resolveShare, _setup11, findByText, getByRole, queryByRole, sendButton;
|
|
439
|
+
|
|
440
|
+
return _regeneratorRuntime.wrap(function _callee12$(_context12) {
|
|
441
|
+
while (1) switch (_context12.prev = _context12.next) {
|
|
442
|
+
case 0:
|
|
443
|
+
usePendingRecipients.mockReturnValue({
|
|
444
|
+
pendingRecipients: [pendingRecipient],
|
|
445
|
+
setPendingRecipients: jest.fn(),
|
|
446
|
+
selectedOption: 'readWrite',
|
|
447
|
+
setSelectedOption: jest.fn()
|
|
448
|
+
});
|
|
449
|
+
getOrCreateFromArray.mockResolvedValue([pendingRecipient]);
|
|
450
|
+
mockShare.mockReturnValueOnce(new Promise(function (resolve) {
|
|
451
|
+
resolveShare = resolve;
|
|
452
|
+
}));
|
|
453
|
+
_setup11 = setup(), findByText = _setup11.findByText, getByRole = _setup11.getByRole, queryByRole = _setup11.queryByRole;
|
|
454
|
+
_context12.next = 6;
|
|
455
|
+
return findByText('Done');
|
|
456
|
+
|
|
457
|
+
case 6:
|
|
458
|
+
sendButton = _context12.sent;
|
|
459
|
+
fireEvent.click(sendButton);
|
|
460
|
+
_context12.next = 10;
|
|
461
|
+
return waitFor(function () {
|
|
462
|
+
expect(getByRole('button', {
|
|
463
|
+
name: 'Done'
|
|
464
|
+
})).toBeDisabled();
|
|
465
|
+
expect(queryByRole('progressbar')).not.toBeNull();
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
case 10:
|
|
469
|
+
_context12.next = 12;
|
|
470
|
+
return act( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11() {
|
|
471
|
+
return _regeneratorRuntime.wrap(function _callee11$(_context11) {
|
|
472
|
+
while (1) switch (_context11.prev = _context11.next) {
|
|
473
|
+
case 0:
|
|
474
|
+
resolveShare({});
|
|
475
|
+
|
|
476
|
+
case 1:
|
|
477
|
+
case "end":
|
|
478
|
+
return _context11.stop();
|
|
479
|
+
}
|
|
480
|
+
}, _callee11);
|
|
481
|
+
})));
|
|
482
|
+
|
|
483
|
+
case 12:
|
|
484
|
+
case "end":
|
|
485
|
+
return _context12.stop();
|
|
486
|
+
}
|
|
487
|
+
}, _callee12);
|
|
386
488
|
})));
|
|
387
489
|
});
|
|
388
490
|
describe('onClose callback', function () {
|
|
389
|
-
it('should call onClose when close button is clicked', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
390
|
-
var
|
|
491
|
+
it('should call onClose when close button is clicked', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee13() {
|
|
492
|
+
var _setup12, findByRole, closeButton;
|
|
391
493
|
|
|
392
|
-
return _regeneratorRuntime.wrap(function
|
|
393
|
-
while (1) switch (
|
|
494
|
+
return _regeneratorRuntime.wrap(function _callee13$(_context13) {
|
|
495
|
+
while (1) switch (_context13.prev = _context13.next) {
|
|
394
496
|
case 0:
|
|
395
|
-
|
|
396
|
-
|
|
497
|
+
_setup12 = setup(), findByRole = _setup12.findByRole;
|
|
498
|
+
_context13.next = 3;
|
|
397
499
|
return findByRole('button', {
|
|
398
500
|
name: /close/i
|
|
399
501
|
});
|
|
400
502
|
|
|
401
503
|
case 3:
|
|
402
|
-
closeButton =
|
|
504
|
+
closeButton = _context13.sent;
|
|
403
505
|
fireEvent.click(closeButton);
|
|
404
506
|
expect(mockOnClose).toHaveBeenCalled();
|
|
405
507
|
|
|
406
508
|
case 6:
|
|
407
509
|
case "end":
|
|
408
|
-
return
|
|
510
|
+
return _context13.stop();
|
|
409
511
|
}
|
|
410
|
-
},
|
|
512
|
+
}, _callee13);
|
|
411
513
|
})));
|
|
412
|
-
it('should ask confirmation when close button is clicked with pending recipients', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
413
|
-
var
|
|
514
|
+
it('should ask confirmation when close button is clicked with pending recipients', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee14() {
|
|
515
|
+
var _setup13, getByRole, findByRole, getByText, closeButton;
|
|
414
516
|
|
|
415
|
-
return _regeneratorRuntime.wrap(function
|
|
416
|
-
while (1) switch (
|
|
517
|
+
return _regeneratorRuntime.wrap(function _callee14$(_context14) {
|
|
518
|
+
while (1) switch (_context14.prev = _context14.next) {
|
|
417
519
|
case 0:
|
|
418
520
|
usePendingRecipients.mockReturnValue({
|
|
419
521
|
pendingRecipients: [{
|
|
@@ -424,14 +526,14 @@ describe('FederatedFolderModal', function () {
|
|
|
424
526
|
selectedOption: 'readWrite',
|
|
425
527
|
setSelectedOption: jest.fn()
|
|
426
528
|
});
|
|
427
|
-
|
|
428
|
-
|
|
529
|
+
_setup13 = setup(), getByRole = _setup13.getByRole, findByRole = _setup13.findByRole, getByText = _setup13.getByText;
|
|
530
|
+
_context14.next = 4;
|
|
429
531
|
return findByRole('button', {
|
|
430
532
|
name: /close/i
|
|
431
533
|
});
|
|
432
534
|
|
|
433
535
|
case 4:
|
|
434
|
-
closeButton =
|
|
536
|
+
closeButton = _context14.sent;
|
|
435
537
|
fireEvent.click(closeButton);
|
|
436
538
|
expect(getByText("Discard the changes you haven't saved?")).toBeTruthy();
|
|
437
539
|
expect(mockOnClose).not.toHaveBeenCalled();
|
|
@@ -442,15 +544,15 @@ describe('FederatedFolderModal', function () {
|
|
|
442
544
|
|
|
443
545
|
case 10:
|
|
444
546
|
case "end":
|
|
445
|
-
return
|
|
547
|
+
return _context14.stop();
|
|
446
548
|
}
|
|
447
|
-
},
|
|
549
|
+
}, _callee14);
|
|
448
550
|
})));
|
|
449
|
-
it('should close after discard confirmation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
450
|
-
var
|
|
551
|
+
it('should close after discard confirmation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee15() {
|
|
552
|
+
var _setup14, getByRole, findByRole, getByText, closeButton;
|
|
451
553
|
|
|
452
|
-
return _regeneratorRuntime.wrap(function
|
|
453
|
-
while (1) switch (
|
|
554
|
+
return _regeneratorRuntime.wrap(function _callee15$(_context15) {
|
|
555
|
+
while (1) switch (_context15.prev = _context15.next) {
|
|
454
556
|
case 0:
|
|
455
557
|
usePendingRecipients.mockReturnValue({
|
|
456
558
|
pendingRecipients: [{
|
|
@@ -461,14 +563,14 @@ describe('FederatedFolderModal', function () {
|
|
|
461
563
|
selectedOption: 'readWrite',
|
|
462
564
|
setSelectedOption: jest.fn()
|
|
463
565
|
});
|
|
464
|
-
|
|
465
|
-
|
|
566
|
+
_setup14 = setup(), getByRole = _setup14.getByRole, findByRole = _setup14.findByRole, getByText = _setup14.getByText;
|
|
567
|
+
_context15.next = 4;
|
|
466
568
|
return findByRole('button', {
|
|
467
569
|
name: /close/i
|
|
468
570
|
});
|
|
469
571
|
|
|
470
572
|
case 4:
|
|
471
|
-
closeButton =
|
|
573
|
+
closeButton = _context15.sent;
|
|
472
574
|
fireEvent.click(closeButton);
|
|
473
575
|
expect(getByText("Discard the changes you haven't saved?")).toBeTruthy();
|
|
474
576
|
fireEvent.click(getByRole('button', {
|
|
@@ -478,9 +580,9 @@ describe('FederatedFolderModal', function () {
|
|
|
478
580
|
|
|
479
581
|
case 9:
|
|
480
582
|
case "end":
|
|
481
|
-
return
|
|
583
|
+
return _context15.stop();
|
|
482
584
|
}
|
|
483
|
-
},
|
|
585
|
+
}, _callee15);
|
|
484
586
|
})));
|
|
485
587
|
});
|
|
486
588
|
});
|
|
@@ -24,6 +24,7 @@ import { getOrCreateFromArray } from '../helpers/contacts';
|
|
|
24
24
|
import { hasReachRecipientsLimit } from '../helpers/recipients';
|
|
25
25
|
import { getErrorMessage, getSuccessMessage } from '../helpers/share';
|
|
26
26
|
import { usePendingRecipients } from '../hooks/usePendingRecipients';
|
|
27
|
+
import { useSharingContext } from '../hooks/useSharingContext';
|
|
27
28
|
var styles = {
|
|
28
29
|
"share-modal-content": "share__share-modal-content___1iqEq",
|
|
29
30
|
"coz-form": "share__coz-form___1ICST",
|
|
@@ -144,6 +145,9 @@ var ShareDialogCozyToCozy = function ShareDialogCozyToCozy(_ref3) {
|
|
|
144
145
|
var _useAlert = useAlert(),
|
|
145
146
|
showAlert = _useAlert.showAlert;
|
|
146
147
|
|
|
148
|
+
var _useSharingContext = useSharingContext(),
|
|
149
|
+
getSharingLink = _useSharingContext.getSharingLink;
|
|
150
|
+
|
|
147
151
|
var _usePendingRecipients = usePendingRecipients(),
|
|
148
152
|
pendingRecipients = _usePendingRecipients.pendingRecipients,
|
|
149
153
|
setPendingRecipients = _usePendingRecipients.setPendingRecipients,
|
|
@@ -160,6 +164,7 @@ var ShareDialogCozyToCozy = function ShareDialogCozyToCozy(_ref3) {
|
|
|
160
164
|
showRecipientsLimit = _useState4[0],
|
|
161
165
|
setShowRecipientsLimit = _useState4[1];
|
|
162
166
|
|
|
167
|
+
var displayedLink = getSharingLink(document._id || document.id);
|
|
163
168
|
var handleShare = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
164
169
|
var contacts, readWriteRecipients, readOnlyRecipients;
|
|
165
170
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
@@ -254,6 +259,7 @@ var ShareDialogCozyToCozy = function ShareDialogCozyToCozy(_ref3) {
|
|
|
254
259
|
return Actions;
|
|
255
260
|
}, [handleShare, submitting, t, documentType, showShareByLink, showGenerateLinkButton, autoOpenShareRestriction]);
|
|
256
261
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ShareDialogTwoStepsConfirmationContainer, _extends({}, props, {
|
|
262
|
+
link: displayedLink,
|
|
257
263
|
documentType: documentType,
|
|
258
264
|
document: document,
|
|
259
265
|
recipients: recipients,
|
|
@@ -7,6 +7,7 @@ import { useI18n } from 'twake-i18n';
|
|
|
7
7
|
import AntivirusAlert from './AntivirusAlert';
|
|
8
8
|
import { default as DumbShareByLink } from './ShareByLink';
|
|
9
9
|
import WhoHasAccess from './WhoHasAccess';
|
|
10
|
+
import { useSharingContext } from '../hooks/useSharingContext';
|
|
10
11
|
|
|
11
12
|
var ShareDialogOnlyByLink = function ShareDialogOnlyByLink(_ref) {
|
|
12
13
|
var isOwner = _ref.isOwner,
|
|
@@ -15,7 +16,6 @@ var ShareDialogOnlyByLink = function ShareDialogOnlyByLink(_ref) {
|
|
|
15
16
|
recipients = _ref.recipients,
|
|
16
17
|
document = _ref.document,
|
|
17
18
|
documentType = _ref.documentType,
|
|
18
|
-
link = _ref.link,
|
|
19
19
|
onClose = _ref.onClose,
|
|
20
20
|
permissions = _ref.permissions,
|
|
21
21
|
showGenerateLinkButton = _ref.showGenerateLinkButton,
|
|
@@ -27,6 +27,10 @@ var ShareDialogOnlyByLink = function ShareDialogOnlyByLink(_ref) {
|
|
|
27
27
|
var _useBreakpoints = useBreakpoints(),
|
|
28
28
|
isMobile = _useBreakpoints.isMobile;
|
|
29
29
|
|
|
30
|
+
var _useSharingContext = useSharingContext(),
|
|
31
|
+
getSharingLink = _useSharingContext.getSharingLink;
|
|
32
|
+
|
|
33
|
+
var displayedLink = getSharingLink(document._id || document.id);
|
|
30
34
|
return /*#__PURE__*/React.createElement(Dialog, {
|
|
31
35
|
disableGutters: true,
|
|
32
36
|
disableEnforceFocus: true,
|
|
@@ -47,12 +51,12 @@ var ShareDialogOnlyByLink = function ShareDialogOnlyByLink(_ref) {
|
|
|
47
51
|
onRevoke: onRevoke,
|
|
48
52
|
onRevokeSelf: onRevokeSelf,
|
|
49
53
|
recipients: recipients,
|
|
50
|
-
link:
|
|
54
|
+
link: displayedLink,
|
|
51
55
|
permissions: permissions
|
|
52
56
|
}), /*#__PURE__*/React.createElement("div", {
|
|
53
57
|
className: cx('u-mt-half', isMobile ? 'u-ph-1 u-mb-1' : 'u-ph-2 u-mb-1-half')
|
|
54
58
|
}, /*#__PURE__*/React.createElement(DumbShareByLink, {
|
|
55
|
-
link:
|
|
59
|
+
link: displayedLink,
|
|
56
60
|
document: document,
|
|
57
61
|
documentType: documentType,
|
|
58
62
|
showGenerateLinkButton: showGenerateLinkButton,
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import ShareDialogOnlyByLink from './ShareDialogOnlyByLink';
|
|
4
|
+
import AppLike from '../../test/AppLike';
|
|
5
|
+
var mockSharingLink = null;
|
|
6
|
+
jest.mock('./ShareByLink', function () {
|
|
7
|
+
return function () {
|
|
8
|
+
return /*#__PURE__*/React.createElement("button", null, "Copy link");
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
jest.mock('../hooks/useSharingContext', function () {
|
|
12
|
+
return {
|
|
13
|
+
useSharingContext: function useSharingContext() {
|
|
14
|
+
return {
|
|
15
|
+
documentType: 'Files',
|
|
16
|
+
getDocumentPermissions: function getDocumentPermissions() {
|
|
17
|
+
return [];
|
|
18
|
+
},
|
|
19
|
+
getSharingLink: function getSharingLink() {
|
|
20
|
+
return mockSharingLink;
|
|
21
|
+
},
|
|
22
|
+
revokeSharingLink: jest.fn(),
|
|
23
|
+
updateDocumentPermissions: jest.fn()
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
describe('ShareDialogOnlyByLink', function () {
|
|
29
|
+
beforeEach(function () {
|
|
30
|
+
mockSharingLink = null;
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
var renderModal = function renderModal() {
|
|
34
|
+
return /*#__PURE__*/React.createElement(AppLike, null, /*#__PURE__*/React.createElement(ShareDialogOnlyByLink, {
|
|
35
|
+
document: {
|
|
36
|
+
_id: 'file-id',
|
|
37
|
+
attributes: {
|
|
38
|
+
name: 'file.txt'
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
documentType: "Files",
|
|
42
|
+
isOwner: true,
|
|
43
|
+
onClose: jest.fn(),
|
|
44
|
+
onRevoke: jest.fn(),
|
|
45
|
+
onRevokeSelf: jest.fn(),
|
|
46
|
+
permissions: [],
|
|
47
|
+
recipients: []
|
|
48
|
+
}));
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
var setup = function setup() {
|
|
52
|
+
return render(renderModal());
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
it('shows link access as soon as a link is generated', function () {
|
|
56
|
+
var _setup = setup(),
|
|
57
|
+
rerender = _setup.rerender;
|
|
58
|
+
|
|
59
|
+
expect(screen.queryByText('Anyone with the link')).toBe(null);
|
|
60
|
+
mockSharingLink = 'https://example.com/public';
|
|
61
|
+
rerender(renderModal());
|
|
62
|
+
expect(screen.queryByText('Anyone with the link')).toBeInTheDocument();
|
|
63
|
+
});
|
|
64
|
+
it('hides link access as soon as a link is revoked', function () {
|
|
65
|
+
mockSharingLink = 'https://example.com/public';
|
|
66
|
+
|
|
67
|
+
var _setup2 = setup(),
|
|
68
|
+
rerender = _setup2.rerender;
|
|
69
|
+
|
|
70
|
+
expect(screen.queryByText('Anyone with the link')).toBeInTheDocument();
|
|
71
|
+
mockSharingLink = null;
|
|
72
|
+
rerender(renderModal());
|
|
73
|
+
expect(screen.queryByText('Anyone with the link')).toBe(null);
|
|
74
|
+
});
|
|
75
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-sharing",
|
|
3
|
-
"version": "33.1
|
|
3
|
+
"version": "33.2.1",
|
|
4
4
|
"description": "Provides sharing login for React applications.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "Cozy",
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"sideEffects": [
|
|
84
84
|
"*.css"
|
|
85
85
|
],
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "107c14be0fb0677515062187e3fdadeab4e00350"
|
|
87
87
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import PropTypes from 'prop-types'
|
|
2
|
-
import React, { useCallback,
|
|
2
|
+
import React, { useCallback, useState } from 'react'
|
|
3
3
|
|
|
4
4
|
import { useClient } from 'cozy-client'
|
|
5
5
|
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
@@ -33,9 +33,6 @@ const FederatedFolderModalContent = ({
|
|
|
33
33
|
share,
|
|
34
34
|
getSharingLink,
|
|
35
35
|
getFederatedShareLink,
|
|
36
|
-
getDocumentPermissions,
|
|
37
|
-
getOwner,
|
|
38
|
-
getSharingById,
|
|
39
36
|
getRecipients,
|
|
40
37
|
hasSharedChild,
|
|
41
38
|
hasSharedParent,
|
|
@@ -44,7 +41,6 @@ const FederatedFolderModalContent = ({
|
|
|
44
41
|
const { showAlert } = useAlert()
|
|
45
42
|
const { showConfirmDialog, closeConfirmDialog } = useConfirmDialog()
|
|
46
43
|
|
|
47
|
-
const [sharingLink, setSharingLink] = useState(null)
|
|
48
44
|
const {
|
|
49
45
|
pendingRecipients,
|
|
50
46
|
setPendingRecipients,
|
|
@@ -98,34 +94,6 @@ const FederatedFolderModalContent = ({
|
|
|
98
94
|
t
|
|
99
95
|
])
|
|
100
96
|
|
|
101
|
-
const documentPermissions = useMemo(
|
|
102
|
-
() =>
|
|
103
|
-
existingDocument ? getDocumentPermissions(existingDocument._id) : [],
|
|
104
|
-
[existingDocument, getDocumentPermissions]
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
useEffect(() => {
|
|
108
|
-
const fetchSharingLink = async () => {
|
|
109
|
-
if (!existingDocument) return
|
|
110
|
-
|
|
111
|
-
if (existingDocument.driveId) {
|
|
112
|
-
const link = await getFederatedShareLink(existingDocument)
|
|
113
|
-
setSharingLink(link)
|
|
114
|
-
} else {
|
|
115
|
-
setSharingLink(getSharingLink(existingDocument._id))
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
fetchSharingLink()
|
|
120
|
-
}, [
|
|
121
|
-
existingDocument,
|
|
122
|
-
documentPermissions,
|
|
123
|
-
getFederatedShareLink,
|
|
124
|
-
getSharingLink,
|
|
125
|
-
getOwner,
|
|
126
|
-
getSharingById
|
|
127
|
-
])
|
|
128
|
-
|
|
129
97
|
const folderName = existingDocument?.name || ''
|
|
130
98
|
const documentPath = existingDocument?.path
|
|
131
99
|
const hasParentRestriction = Boolean(
|
|
@@ -185,6 +153,9 @@ const FederatedFolderModalContent = ({
|
|
|
185
153
|
const existingRecipients = existingDocument
|
|
186
154
|
? getRecipients(existingDocument._id)
|
|
187
155
|
: []
|
|
156
|
+
const displayedLink = existingDocument?.driveId
|
|
157
|
+
? getFederatedShareLink(existingDocument)
|
|
158
|
+
: getSharingLink(existingDocument?._id)
|
|
188
159
|
|
|
189
160
|
const modalTitle = t('FederatedFolder.shareTitle', { name: folderName })
|
|
190
161
|
|
|
@@ -252,14 +223,14 @@ const FederatedFolderModalContent = ({
|
|
|
252
223
|
documentType="Files"
|
|
253
224
|
className="u-w-100"
|
|
254
225
|
onRevoke={revoke}
|
|
255
|
-
link={
|
|
226
|
+
link={displayedLink}
|
|
256
227
|
/>
|
|
257
228
|
</div>
|
|
258
229
|
}
|
|
259
230
|
actions={
|
|
260
231
|
<>
|
|
261
232
|
<ShareByLink
|
|
262
|
-
link={
|
|
233
|
+
link={displayedLink}
|
|
263
234
|
document={isSending ? frozenDoc : existingDocument}
|
|
264
235
|
documentType="Files"
|
|
265
236
|
showGenerateLinkButton={showGenerateLinkButton}
|
|
@@ -269,7 +240,7 @@ const FederatedFolderModalContent = ({
|
|
|
269
240
|
<Button
|
|
270
241
|
variant="primary"
|
|
271
242
|
label={t('FederatedFolder.share')}
|
|
272
|
-
|
|
243
|
+
busy={isSending}
|
|
273
244
|
onClick={onSend}
|
|
274
245
|
/>
|
|
275
246
|
)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fireEvent, render, waitFor } from '@testing-library/react'
|
|
1
|
+
import { act, fireEvent, render, waitFor } from '@testing-library/react'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
|
|
4
4
|
import { createMockClient } from 'cozy-client'
|
|
@@ -9,6 +9,7 @@ import { usePendingRecipients } from '../../hooks/usePendingRecipients'
|
|
|
9
9
|
import AppLike from '../SharingBanner/test/AppLike'
|
|
10
10
|
|
|
11
11
|
const mockShare = jest.fn()
|
|
12
|
+
const mockShareByLink = jest.fn()
|
|
12
13
|
const mockRevoke = jest.fn()
|
|
13
14
|
const mockGetSharingLink = jest.fn()
|
|
14
15
|
const mockGetFederatedShareLink = jest.fn()
|
|
@@ -21,10 +22,13 @@ const mockOnClose = jest.fn()
|
|
|
21
22
|
jest.mock('../../hooks/useSharingContext', () => ({
|
|
22
23
|
useSharingContext: () => ({
|
|
23
24
|
share: mockShare,
|
|
25
|
+
shareByLink: mockShareByLink,
|
|
24
26
|
revoke: mockRevoke,
|
|
25
27
|
getSharingLink: mockGetSharingLink,
|
|
26
28
|
getFederatedShareLink: mockGetFederatedShareLink,
|
|
27
29
|
getDocumentPermissions: jest.fn().mockReturnValue([]),
|
|
30
|
+
getOwner: jest.fn(),
|
|
31
|
+
getSharingById: jest.fn(),
|
|
28
32
|
getRecipients: mockGetRecipients,
|
|
29
33
|
hasSharedChild: mockHasSharedChild,
|
|
30
34
|
hasSharedParent: mockHasSharedParent
|
|
@@ -47,6 +51,8 @@ jest.mock('../../hooks/usePendingRecipients', () => ({
|
|
|
47
51
|
usePendingRecipients: jest.fn()
|
|
48
52
|
}))
|
|
49
53
|
|
|
54
|
+
jest.mock('../ShareByLink', () => () => <button>Copy link</button>)
|
|
55
|
+
|
|
50
56
|
const mockDocument = {
|
|
51
57
|
_id: 'folder-123',
|
|
52
58
|
name: 'My Test Folder',
|
|
@@ -90,12 +96,25 @@ describe('FederatedFolderModal', () => {
|
|
|
90
96
|
beforeEach(() => {
|
|
91
97
|
jest.clearAllMocks()
|
|
92
98
|
mockGetSharingLink.mockReturnValue('https://example.com/share/abc123')
|
|
93
|
-
mockGetFederatedShareLink.
|
|
99
|
+
mockGetFederatedShareLink.mockReturnValue(
|
|
94
100
|
'https://example.com/share/federated-abc123'
|
|
95
101
|
)
|
|
96
102
|
mockGetRecipients.mockReturnValue([])
|
|
97
103
|
mockHasSharedChild.mockReturnValue(false)
|
|
98
104
|
mockHasSharedParent.mockReturnValue(false)
|
|
105
|
+
mockShareByLink.mockResolvedValue({
|
|
106
|
+
data: {
|
|
107
|
+
_id: 'permission-id',
|
|
108
|
+
attributes: {
|
|
109
|
+
shortcodes: { code: 'abc123' }
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
Object.assign(navigator, {
|
|
114
|
+
clipboard: {
|
|
115
|
+
writeText: jest.fn()
|
|
116
|
+
}
|
|
117
|
+
})
|
|
99
118
|
client = createTestClient()
|
|
100
119
|
sharingContextValue = createSharingContextValue()
|
|
101
120
|
usePendingRecipients.mockReturnValue({
|
|
@@ -139,6 +158,22 @@ describe('FederatedFolderModal', () => {
|
|
|
139
158
|
await findByText('Copy link')
|
|
140
159
|
})
|
|
141
160
|
|
|
161
|
+
it('should show link access as soon as a link is generated', async () => {
|
|
162
|
+
mockGetSharingLink.mockReturnValue(null)
|
|
163
|
+
const { findByText, queryByText, rerender } = setup()
|
|
164
|
+
|
|
165
|
+
expect(queryByText('Anyone with the link')).toBe(null)
|
|
166
|
+
|
|
167
|
+
mockGetSharingLink.mockReturnValue('https://example.com/share/abc123')
|
|
168
|
+
rerender(
|
|
169
|
+
<AppLike client={client} sharingContextValue={sharingContextValue}>
|
|
170
|
+
<FederatedFolderModal document={mockDocument} onClose={mockOnClose} />
|
|
171
|
+
</AppLike>
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
await findByText('Anyone with the link')
|
|
175
|
+
})
|
|
176
|
+
|
|
142
177
|
it('should hide share by email when document is in federated shared folder received by current user', async () => {
|
|
143
178
|
const { findByText, queryByText } = setup({
|
|
144
179
|
document: { ...mockDocument, driveId: 'federated-folder-id' }
|
|
@@ -257,6 +292,36 @@ describe('FederatedFolderModal', () => {
|
|
|
257
292
|
expect(mockOnClose).not.toHaveBeenCalled()
|
|
258
293
|
})
|
|
259
294
|
})
|
|
295
|
+
|
|
296
|
+
it('should show progress icon on Done button while share is in progress', async () => {
|
|
297
|
+
usePendingRecipients.mockReturnValue({
|
|
298
|
+
pendingRecipients: [pendingRecipient],
|
|
299
|
+
setPendingRecipients: jest.fn(),
|
|
300
|
+
selectedOption: 'readWrite',
|
|
301
|
+
setSelectedOption: jest.fn()
|
|
302
|
+
})
|
|
303
|
+
getOrCreateFromArray.mockResolvedValue([pendingRecipient])
|
|
304
|
+
let resolveShare
|
|
305
|
+
mockShare.mockReturnValueOnce(
|
|
306
|
+
new Promise(resolve => {
|
|
307
|
+
resolveShare = resolve
|
|
308
|
+
})
|
|
309
|
+
)
|
|
310
|
+
const { findByText, getByRole, queryByRole } = setup()
|
|
311
|
+
|
|
312
|
+
const sendButton = await findByText('Done')
|
|
313
|
+
|
|
314
|
+
fireEvent.click(sendButton)
|
|
315
|
+
|
|
316
|
+
await waitFor(() => {
|
|
317
|
+
expect(getByRole('button', { name: 'Done' })).toBeDisabled()
|
|
318
|
+
expect(queryByRole('progressbar')).not.toBeNull()
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
await act(async () => {
|
|
322
|
+
resolveShare({})
|
|
323
|
+
})
|
|
324
|
+
})
|
|
260
325
|
})
|
|
261
326
|
|
|
262
327
|
describe('onClose callback', () => {
|
|
@@ -19,6 +19,7 @@ import { getOrCreateFromArray } from '../helpers/contacts'
|
|
|
19
19
|
import { hasReachRecipientsLimit } from '../helpers/recipients'
|
|
20
20
|
import { getErrorMessage, getSuccessMessage } from '../helpers/share'
|
|
21
21
|
import { usePendingRecipients } from '../hooks/usePendingRecipients'
|
|
22
|
+
import { useSharingContext } from '../hooks/useSharingContext'
|
|
22
23
|
import styles from '../styles/share.styl'
|
|
23
24
|
|
|
24
25
|
const SharingContent = ({
|
|
@@ -126,6 +127,7 @@ const ShareDialogCozyToCozy = ({
|
|
|
126
127
|
const { t } = useI18n()
|
|
127
128
|
const client = useClient()
|
|
128
129
|
const { showAlert } = useAlert()
|
|
130
|
+
const { getSharingLink } = useSharingContext()
|
|
129
131
|
|
|
130
132
|
const {
|
|
131
133
|
pendingRecipients,
|
|
@@ -136,6 +138,7 @@ const ShareDialogCozyToCozy = ({
|
|
|
136
138
|
|
|
137
139
|
const [submitting, setSubmitting] = useState(false)
|
|
138
140
|
const [showRecipientsLimit, setShowRecipientsLimit] = useState(false)
|
|
141
|
+
const displayedLink = getSharingLink(document._id || document.id)
|
|
139
142
|
|
|
140
143
|
const handleShare = useCallback(async () => {
|
|
141
144
|
if (pendingRecipients.length === 0) {
|
|
@@ -238,6 +241,7 @@ const ShareDialogCozyToCozy = ({
|
|
|
238
241
|
<>
|
|
239
242
|
<ShareDialogTwoStepsConfirmationContainer
|
|
240
243
|
{...props}
|
|
244
|
+
link={displayedLink}
|
|
241
245
|
documentType={documentType}
|
|
242
246
|
document={document}
|
|
243
247
|
recipients={recipients}
|
|
@@ -9,6 +9,7 @@ import { useI18n } from 'twake-i18n'
|
|
|
9
9
|
import AntivirusAlert from './AntivirusAlert'
|
|
10
10
|
import { default as DumbShareByLink } from './ShareByLink'
|
|
11
11
|
import WhoHasAccess from './WhoHasAccess'
|
|
12
|
+
import { useSharingContext } from '../hooks/useSharingContext'
|
|
12
13
|
|
|
13
14
|
const ShareDialogOnlyByLink = ({
|
|
14
15
|
isOwner,
|
|
@@ -17,7 +18,6 @@ const ShareDialogOnlyByLink = ({
|
|
|
17
18
|
recipients,
|
|
18
19
|
document,
|
|
19
20
|
documentType,
|
|
20
|
-
link,
|
|
21
21
|
onClose,
|
|
22
22
|
permissions,
|
|
23
23
|
showGenerateLinkButton,
|
|
@@ -25,6 +25,8 @@ const ShareDialogOnlyByLink = ({
|
|
|
25
25
|
}) => {
|
|
26
26
|
const { t } = useI18n()
|
|
27
27
|
const { isMobile } = useBreakpoints()
|
|
28
|
+
const { getSharingLink } = useSharingContext()
|
|
29
|
+
const displayedLink = getSharingLink(document._id || document.id)
|
|
28
30
|
|
|
29
31
|
return (
|
|
30
32
|
<Dialog
|
|
@@ -51,7 +53,7 @@ const ShareDialogOnlyByLink = ({
|
|
|
51
53
|
onRevoke={onRevoke}
|
|
52
54
|
onRevokeSelf={onRevokeSelf}
|
|
53
55
|
recipients={recipients}
|
|
54
|
-
link={
|
|
56
|
+
link={displayedLink}
|
|
55
57
|
permissions={permissions}
|
|
56
58
|
/>
|
|
57
59
|
<div
|
|
@@ -61,7 +63,7 @@ const ShareDialogOnlyByLink = ({
|
|
|
61
63
|
)}
|
|
62
64
|
>
|
|
63
65
|
<DumbShareByLink
|
|
64
|
-
link={
|
|
66
|
+
link={displayedLink}
|
|
65
67
|
document={document}
|
|
66
68
|
documentType={documentType}
|
|
67
69
|
showGenerateLinkButton={showGenerateLinkButton}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import ShareDialogOnlyByLink from './ShareDialogOnlyByLink'
|
|
5
|
+
import AppLike from '../../test/AppLike'
|
|
6
|
+
|
|
7
|
+
let mockSharingLink = null
|
|
8
|
+
|
|
9
|
+
jest.mock('./ShareByLink', () => () => <button>Copy link</button>)
|
|
10
|
+
|
|
11
|
+
jest.mock('../hooks/useSharingContext', () => ({
|
|
12
|
+
useSharingContext: () => ({
|
|
13
|
+
documentType: 'Files',
|
|
14
|
+
getDocumentPermissions: () => [],
|
|
15
|
+
getSharingLink: () => mockSharingLink,
|
|
16
|
+
revokeSharingLink: jest.fn(),
|
|
17
|
+
updateDocumentPermissions: jest.fn()
|
|
18
|
+
})
|
|
19
|
+
}))
|
|
20
|
+
|
|
21
|
+
describe('ShareDialogOnlyByLink', () => {
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
mockSharingLink = null
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const renderModal = () => (
|
|
27
|
+
<AppLike>
|
|
28
|
+
<ShareDialogOnlyByLink
|
|
29
|
+
document={{ _id: 'file-id', attributes: { name: 'file.txt' } }}
|
|
30
|
+
documentType="Files"
|
|
31
|
+
isOwner
|
|
32
|
+
onClose={jest.fn()}
|
|
33
|
+
onRevoke={jest.fn()}
|
|
34
|
+
onRevokeSelf={jest.fn()}
|
|
35
|
+
permissions={[]}
|
|
36
|
+
recipients={[]}
|
|
37
|
+
/>
|
|
38
|
+
</AppLike>
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
const setup = () => render(renderModal())
|
|
42
|
+
|
|
43
|
+
it('shows link access as soon as a link is generated', () => {
|
|
44
|
+
const { rerender } = setup()
|
|
45
|
+
|
|
46
|
+
expect(screen.queryByText('Anyone with the link')).toBe(null)
|
|
47
|
+
|
|
48
|
+
mockSharingLink = 'https://example.com/public'
|
|
49
|
+
rerender(renderModal())
|
|
50
|
+
|
|
51
|
+
expect(screen.queryByText('Anyone with the link')).toBeInTheDocument()
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('hides link access as soon as a link is revoked', () => {
|
|
55
|
+
mockSharingLink = 'https://example.com/public'
|
|
56
|
+
const { rerender } = setup()
|
|
57
|
+
|
|
58
|
+
expect(screen.queryByText('Anyone with the link')).toBeInTheDocument()
|
|
59
|
+
|
|
60
|
+
mockSharingLink = null
|
|
61
|
+
rerender(renderModal())
|
|
62
|
+
|
|
63
|
+
expect(screen.queryByText('Anyone with the link')).toBe(null)
|
|
64
|
+
})
|
|
65
|
+
})
|