cozy-sharing 33.2.0 → 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 +6 -0
- package/dist/components/FederatedFolder/FederatedFolderModal.js +31 -87
- package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +151 -101
- 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 +6 -35
- package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +36 -1
- 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,12 @@
|
|
|
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
|
+
|
|
6
12
|
# [33.2.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@33.1.2...cozy-sharing@33.2.0) (2026-06-09)
|
|
7
13
|
|
|
8
14
|
### Features
|
|
@@ -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,
|
|
@@ -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,15 +430,15 @@ describe('FederatedFolderModal', function () {
|
|
|
380
430
|
|
|
381
431
|
case 10:
|
|
382
432
|
case "end":
|
|
383
|
-
return
|
|
433
|
+
return _context10.stop();
|
|
384
434
|
}
|
|
385
|
-
},
|
|
435
|
+
}, _callee10);
|
|
386
436
|
})));
|
|
387
|
-
it('should show progress icon on Done button while share is in progress', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
388
|
-
var resolveShare,
|
|
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;
|
|
389
439
|
|
|
390
|
-
return _regeneratorRuntime.wrap(function
|
|
391
|
-
while (1) switch (
|
|
440
|
+
return _regeneratorRuntime.wrap(function _callee12$(_context12) {
|
|
441
|
+
while (1) switch (_context12.prev = _context12.next) {
|
|
392
442
|
case 0:
|
|
393
443
|
usePendingRecipients.mockReturnValue({
|
|
394
444
|
pendingRecipients: [pendingRecipient],
|
|
@@ -400,14 +450,14 @@ describe('FederatedFolderModal', function () {
|
|
|
400
450
|
mockShare.mockReturnValueOnce(new Promise(function (resolve) {
|
|
401
451
|
resolveShare = resolve;
|
|
402
452
|
}));
|
|
403
|
-
|
|
404
|
-
|
|
453
|
+
_setup11 = setup(), findByText = _setup11.findByText, getByRole = _setup11.getByRole, queryByRole = _setup11.queryByRole;
|
|
454
|
+
_context12.next = 6;
|
|
405
455
|
return findByText('Done');
|
|
406
456
|
|
|
407
457
|
case 6:
|
|
408
|
-
sendButton =
|
|
458
|
+
sendButton = _context12.sent;
|
|
409
459
|
fireEvent.click(sendButton);
|
|
410
|
-
|
|
460
|
+
_context12.next = 10;
|
|
411
461
|
return waitFor(function () {
|
|
412
462
|
expect(getByRole('button', {
|
|
413
463
|
name: 'Done'
|
|
@@ -416,56 +466,56 @@ describe('FederatedFolderModal', function () {
|
|
|
416
466
|
});
|
|
417
467
|
|
|
418
468
|
case 10:
|
|
419
|
-
|
|
420
|
-
return act( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
421
|
-
return _regeneratorRuntime.wrap(function
|
|
422
|
-
while (1) switch (
|
|
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) {
|
|
423
473
|
case 0:
|
|
424
474
|
resolveShare({});
|
|
425
475
|
|
|
426
476
|
case 1:
|
|
427
477
|
case "end":
|
|
428
|
-
return
|
|
478
|
+
return _context11.stop();
|
|
429
479
|
}
|
|
430
|
-
},
|
|
480
|
+
}, _callee11);
|
|
431
481
|
})));
|
|
432
482
|
|
|
433
483
|
case 12:
|
|
434
484
|
case "end":
|
|
435
|
-
return
|
|
485
|
+
return _context12.stop();
|
|
436
486
|
}
|
|
437
|
-
},
|
|
487
|
+
}, _callee12);
|
|
438
488
|
})));
|
|
439
489
|
});
|
|
440
490
|
describe('onClose callback', function () {
|
|
441
|
-
it('should call onClose when close button is clicked', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
442
|
-
var
|
|
491
|
+
it('should call onClose when close button is clicked', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee13() {
|
|
492
|
+
var _setup12, findByRole, closeButton;
|
|
443
493
|
|
|
444
|
-
return _regeneratorRuntime.wrap(function
|
|
445
|
-
while (1) switch (
|
|
494
|
+
return _regeneratorRuntime.wrap(function _callee13$(_context13) {
|
|
495
|
+
while (1) switch (_context13.prev = _context13.next) {
|
|
446
496
|
case 0:
|
|
447
|
-
|
|
448
|
-
|
|
497
|
+
_setup12 = setup(), findByRole = _setup12.findByRole;
|
|
498
|
+
_context13.next = 3;
|
|
449
499
|
return findByRole('button', {
|
|
450
500
|
name: /close/i
|
|
451
501
|
});
|
|
452
502
|
|
|
453
503
|
case 3:
|
|
454
|
-
closeButton =
|
|
504
|
+
closeButton = _context13.sent;
|
|
455
505
|
fireEvent.click(closeButton);
|
|
456
506
|
expect(mockOnClose).toHaveBeenCalled();
|
|
457
507
|
|
|
458
508
|
case 6:
|
|
459
509
|
case "end":
|
|
460
|
-
return
|
|
510
|
+
return _context13.stop();
|
|
461
511
|
}
|
|
462
|
-
},
|
|
512
|
+
}, _callee13);
|
|
463
513
|
})));
|
|
464
|
-
it('should ask confirmation when close button is clicked with pending recipients', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
465
|
-
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;
|
|
466
516
|
|
|
467
|
-
return _regeneratorRuntime.wrap(function
|
|
468
|
-
while (1) switch (
|
|
517
|
+
return _regeneratorRuntime.wrap(function _callee14$(_context14) {
|
|
518
|
+
while (1) switch (_context14.prev = _context14.next) {
|
|
469
519
|
case 0:
|
|
470
520
|
usePendingRecipients.mockReturnValue({
|
|
471
521
|
pendingRecipients: [{
|
|
@@ -476,14 +526,14 @@ describe('FederatedFolderModal', function () {
|
|
|
476
526
|
selectedOption: 'readWrite',
|
|
477
527
|
setSelectedOption: jest.fn()
|
|
478
528
|
});
|
|
479
|
-
|
|
480
|
-
|
|
529
|
+
_setup13 = setup(), getByRole = _setup13.getByRole, findByRole = _setup13.findByRole, getByText = _setup13.getByText;
|
|
530
|
+
_context14.next = 4;
|
|
481
531
|
return findByRole('button', {
|
|
482
532
|
name: /close/i
|
|
483
533
|
});
|
|
484
534
|
|
|
485
535
|
case 4:
|
|
486
|
-
closeButton =
|
|
536
|
+
closeButton = _context14.sent;
|
|
487
537
|
fireEvent.click(closeButton);
|
|
488
538
|
expect(getByText("Discard the changes you haven't saved?")).toBeTruthy();
|
|
489
539
|
expect(mockOnClose).not.toHaveBeenCalled();
|
|
@@ -494,15 +544,15 @@ describe('FederatedFolderModal', function () {
|
|
|
494
544
|
|
|
495
545
|
case 10:
|
|
496
546
|
case "end":
|
|
497
|
-
return
|
|
547
|
+
return _context14.stop();
|
|
498
548
|
}
|
|
499
|
-
},
|
|
549
|
+
}, _callee14);
|
|
500
550
|
})));
|
|
501
|
-
it('should close after discard confirmation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
502
|
-
var
|
|
551
|
+
it('should close after discard confirmation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee15() {
|
|
552
|
+
var _setup14, getByRole, findByRole, getByText, closeButton;
|
|
503
553
|
|
|
504
|
-
return _regeneratorRuntime.wrap(function
|
|
505
|
-
while (1) switch (
|
|
554
|
+
return _regeneratorRuntime.wrap(function _callee15$(_context15) {
|
|
555
|
+
while (1) switch (_context15.prev = _context15.next) {
|
|
506
556
|
case 0:
|
|
507
557
|
usePendingRecipients.mockReturnValue({
|
|
508
558
|
pendingRecipients: [{
|
|
@@ -513,14 +563,14 @@ describe('FederatedFolderModal', function () {
|
|
|
513
563
|
selectedOption: 'readWrite',
|
|
514
564
|
setSelectedOption: jest.fn()
|
|
515
565
|
});
|
|
516
|
-
|
|
517
|
-
|
|
566
|
+
_setup14 = setup(), getByRole = _setup14.getByRole, findByRole = _setup14.findByRole, getByText = _setup14.getByText;
|
|
567
|
+
_context15.next = 4;
|
|
518
568
|
return findByRole('button', {
|
|
519
569
|
name: /close/i
|
|
520
570
|
});
|
|
521
571
|
|
|
522
572
|
case 4:
|
|
523
|
-
closeButton =
|
|
573
|
+
closeButton = _context15.sent;
|
|
524
574
|
fireEvent.click(closeButton);
|
|
525
575
|
expect(getByText("Discard the changes you haven't saved?")).toBeTruthy();
|
|
526
576
|
fireEvent.click(getByRole('button', {
|
|
@@ -530,9 +580,9 @@ describe('FederatedFolderModal', function () {
|
|
|
530
580
|
|
|
531
581
|
case 9:
|
|
532
582
|
case "end":
|
|
533
|
-
return
|
|
583
|
+
return _context15.stop();
|
|
534
584
|
}
|
|
535
|
-
},
|
|
585
|
+
}, _callee15);
|
|
536
586
|
})));
|
|
537
587
|
});
|
|
538
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.2.
|
|
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}
|
|
@@ -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' }
|
|
@@ -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
|
+
})
|