cozy-sharing 33.0.2 → 33.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/components/FederatedFolder/FederatedFolderModal.js +31 -3
- package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +132 -68
- package/package.json +2 -2
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +58 -21
- package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +36 -1
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.1.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@33.0.2...cozy-sharing@33.1.0) (2026-06-04)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- Remove email sharing in recipient side ([f6a3f19](https://github.com/cozy/cozy-libs/commit/f6a3f19bd32f9c1d1d22284a59349a60e2ca147e))
|
|
11
|
+
|
|
6
12
|
## [33.0.2](https://github.com/cozy/cozy-libs/compare/cozy-sharing@33.0.1...cozy-sharing@33.0.2) (2026-06-02)
|
|
7
13
|
|
|
8
14
|
### Bug Fixes
|
|
@@ -14,6 +14,24 @@ import { getOrCreateFromArray } from '../../helpers/contacts';
|
|
|
14
14
|
import withLocales from '../../hoc/withLocales';
|
|
15
15
|
import { usePendingRecipients } from '../../hooks/usePendingRecipients';
|
|
16
16
|
import { useSharingContext } from '../../hooks/useSharingContext';
|
|
17
|
+
var styles = {
|
|
18
|
+
"share-modal-content": "share__share-modal-content___1iqEq",
|
|
19
|
+
"coz-form": "share__coz-form___1ICST",
|
|
20
|
+
"coz-form-group": "share__coz-form-group___VsQp7",
|
|
21
|
+
"coz-form-desc": "share__coz-form-desc___2mYN4",
|
|
22
|
+
"coz-form-label": "share__coz-form-label___bogBw",
|
|
23
|
+
"coz-form-label--error": "share__coz-form-label--error___3YPkf",
|
|
24
|
+
"coz-form-errors": "share__coz-form-errors___2xYRz",
|
|
25
|
+
"coz-form-controls": "share__coz-form-controls___H8kGc",
|
|
26
|
+
"coz-form-controls--full": "share__coz-form-controls--full___1oQXF",
|
|
27
|
+
"coz-form-controls--dispatch": "share__coz-form-controls--dispatch___1zIxt",
|
|
28
|
+
"error": "share__error___pwqPO",
|
|
29
|
+
"share-byemail-onlybylink": "share__share-byemail-onlybylink___29W-t",
|
|
30
|
+
"aligned-dropdown-button": "share__aligned-dropdown-button___3crgG",
|
|
31
|
+
"share-details-created": "share__share-details-created___z3nvO",
|
|
32
|
+
"share-details-perm": "share__share-details-perm___3HjxK",
|
|
33
|
+
"share-details-perm-desc": "share__share-details-perm-desc___3HyHu"
|
|
34
|
+
};
|
|
17
35
|
import AntivirusAlert from '../AntivirusAlert';
|
|
18
36
|
import { default as DumbShareByEmail } from '../ShareByEmail';
|
|
19
37
|
import ShareByLink from '../ShareByLink';
|
|
@@ -37,6 +55,8 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
37
55
|
getOwner = _useSharingContext.getOwner,
|
|
38
56
|
getSharingById = _useSharingContext.getSharingById,
|
|
39
57
|
getRecipients = _useSharingContext.getRecipients,
|
|
58
|
+
hasSharedChild = _useSharingContext.hasSharedChild,
|
|
59
|
+
hasSharedParent = _useSharingContext.hasSharedParent,
|
|
40
60
|
revoke = _useSharingContext.revoke;
|
|
41
61
|
|
|
42
62
|
var _useAlert = useAlert(),
|
|
@@ -152,6 +172,10 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
152
172
|
fetchSharingLink();
|
|
153
173
|
}, [existingDocument, documentPermissions, getFederatedShareLink, getSharingLink, getOwner, getSharingById]);
|
|
154
174
|
var folderName = (existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.name) || '';
|
|
175
|
+
var documentPath = existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.path;
|
|
176
|
+
var hasParentRestriction = Boolean((existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.driveId) || documentPath && hasSharedParent(documentPath));
|
|
177
|
+
var hasChildRestriction = Boolean(documentPath && hasSharedChild(documentPath));
|
|
178
|
+
var canShareByEmail = !hasParentRestriction && !hasChildRestriction;
|
|
155
179
|
|
|
156
180
|
var onSend = /*#__PURE__*/function () {
|
|
157
181
|
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
@@ -248,7 +272,11 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
248
272
|
className: "u-ph-2"
|
|
249
273
|
}, /*#__PURE__*/React.createElement(AntivirusAlert, {
|
|
250
274
|
document: isSending ? frozenDoc : existingDocument
|
|
251
|
-
}), /*#__PURE__*/React.createElement(
|
|
275
|
+
}), !canShareByEmail && /*#__PURE__*/React.createElement("div", {
|
|
276
|
+
className: styles['share-byemail-onlybylink']
|
|
277
|
+
}, t('Files.share.shareByEmail.onlyByLink', {
|
|
278
|
+
type: t("Files.share.shareByEmail.type.".concat((existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.type) === 'file' ? 'file' : 'folder'))
|
|
279
|
+
}), ' ', /*#__PURE__*/React.createElement("strong", null, t("Files.share.shareByEmail.".concat(hasParentRestriction ? 'hasSharedParent' : 'hasSharedChild')))), canShareByEmail && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Typography, {
|
|
252
280
|
variant: "h6",
|
|
253
281
|
className: "u-mt-1-half u-mb-half"
|
|
254
282
|
}, t('Share.contacts.addUsers')), /*#__PURE__*/React.createElement(DumbShareByEmail, {
|
|
@@ -260,7 +288,7 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
260
288
|
selectedOption: selectedOption,
|
|
261
289
|
onSelectedOptionChange: setSelectedOption,
|
|
262
290
|
enableCreateContact: true
|
|
263
|
-
})), /*#__PURE__*/React.createElement(WhoHasAccess, {
|
|
291
|
+
}))), /*#__PURE__*/React.createElement(WhoHasAccess, {
|
|
264
292
|
isOwner: true,
|
|
265
293
|
isSharedDrive: true,
|
|
266
294
|
recipients: isSending ? frozenRecipients : existingRecipients,
|
|
@@ -276,7 +304,7 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
276
304
|
documentType: "Files",
|
|
277
305
|
showGenerateLinkButton: showGenerateLinkButton,
|
|
278
306
|
autoOpenShareRestriction: autoOpenShareRestriction
|
|
279
|
-
}), /*#__PURE__*/React.createElement(Button, {
|
|
307
|
+
}), canShareByEmail && /*#__PURE__*/React.createElement(Button, {
|
|
280
308
|
variant: "primary",
|
|
281
309
|
label: t('FederatedFolder.share'),
|
|
282
310
|
disabled: isSending,
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
1
2
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
3
|
import _extends from "@babel/runtime/helpers/extends";
|
|
4
|
+
|
|
5
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
6
|
+
|
|
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
|
+
|
|
3
9
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
10
|
import { fireEvent, render, waitFor } from '@testing-library/react';
|
|
5
11
|
import React from 'react';
|
|
@@ -11,7 +17,10 @@ import AppLike from '../SharingBanner/test/AppLike';
|
|
|
11
17
|
var mockShare = jest.fn();
|
|
12
18
|
var mockRevoke = jest.fn();
|
|
13
19
|
var mockGetSharingLink = jest.fn();
|
|
20
|
+
var mockGetFederatedShareLink = jest.fn();
|
|
14
21
|
var mockGetRecipients = jest.fn().mockReturnValue([]);
|
|
22
|
+
var mockHasSharedChild = jest.fn();
|
|
23
|
+
var mockHasSharedParent = jest.fn();
|
|
15
24
|
var mockShowAlert = jest.fn();
|
|
16
25
|
var mockOnClose = jest.fn();
|
|
17
26
|
jest.mock('../../hooks/useSharingContext', function () {
|
|
@@ -21,8 +30,11 @@ jest.mock('../../hooks/useSharingContext', function () {
|
|
|
21
30
|
share: mockShare,
|
|
22
31
|
revoke: mockRevoke,
|
|
23
32
|
getSharingLink: mockGetSharingLink,
|
|
33
|
+
getFederatedShareLink: mockGetFederatedShareLink,
|
|
24
34
|
getDocumentPermissions: jest.fn().mockReturnValue([]),
|
|
25
|
-
getRecipients: mockGetRecipients
|
|
35
|
+
getRecipients: mockGetRecipients,
|
|
36
|
+
hasSharedChild: mockHasSharedChild,
|
|
37
|
+
hasSharedParent: mockHasSharedParent
|
|
26
38
|
};
|
|
27
39
|
}
|
|
28
40
|
};
|
|
@@ -97,7 +109,10 @@ describe('FederatedFolderModal', function () {
|
|
|
97
109
|
beforeEach(function () {
|
|
98
110
|
jest.clearAllMocks();
|
|
99
111
|
mockGetSharingLink.mockReturnValue('https://example.com/share/abc123');
|
|
112
|
+
mockGetFederatedShareLink.mockResolvedValue('https://example.com/share/federated-abc123');
|
|
100
113
|
mockGetRecipients.mockReturnValue([]);
|
|
114
|
+
mockHasSharedChild.mockReturnValue(false);
|
|
115
|
+
mockHasSharedParent.mockReturnValue(false);
|
|
101
116
|
client = createTestClient();
|
|
102
117
|
sharingContextValue = createSharingContextValue();
|
|
103
118
|
usePendingRecipients.mockReturnValue({
|
|
@@ -175,27 +190,76 @@ describe('FederatedFolderModal', function () {
|
|
|
175
190
|
}
|
|
176
191
|
}, _callee3);
|
|
177
192
|
})));
|
|
193
|
+
it('should hide share by email when document is in federated shared folder received by current user', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
|
|
194
|
+
var _setup4, findByText, queryByText;
|
|
195
|
+
|
|
196
|
+
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
197
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
198
|
+
case 0:
|
|
199
|
+
_setup4 = setup({
|
|
200
|
+
document: _objectSpread(_objectSpread({}, mockDocument), {}, {
|
|
201
|
+
driveId: 'federated-folder-id'
|
|
202
|
+
})
|
|
203
|
+
}), findByText = _setup4.findByText, queryByText = _setup4.queryByText;
|
|
204
|
+
_context4.next = 3;
|
|
205
|
+
return findByText('Copy link');
|
|
206
|
+
|
|
207
|
+
case 3:
|
|
208
|
+
expect(queryByText('Add users')).toBe(null);
|
|
209
|
+
expect(queryByText('Done')).toBe(null);
|
|
210
|
+
|
|
211
|
+
case 5:
|
|
212
|
+
case "end":
|
|
213
|
+
return _context4.stop();
|
|
214
|
+
}
|
|
215
|
+
}, _callee4);
|
|
216
|
+
})));
|
|
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 _callee5() {
|
|
218
|
+
var _setup5, findByText;
|
|
219
|
+
|
|
220
|
+
return _regeneratorRuntime.wrap(function _callee5$(_context5) {
|
|
221
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
222
|
+
case 0:
|
|
223
|
+
_setup5 = setup({
|
|
224
|
+
document: _objectSpread(_objectSpread({}, mockDocument), {}, {
|
|
225
|
+
driveId: 'federated-folder-id',
|
|
226
|
+
type: 'directory'
|
|
227
|
+
})
|
|
228
|
+
}), findByText = _setup5.findByText;
|
|
229
|
+
_context5.next = 3;
|
|
230
|
+
return findByText('This folder can only be shared by link, because');
|
|
231
|
+
|
|
232
|
+
case 3:
|
|
233
|
+
_context5.next = 5;
|
|
234
|
+
return findByText('it has a shared parent');
|
|
235
|
+
|
|
236
|
+
case 5:
|
|
237
|
+
case "end":
|
|
238
|
+
return _context5.stop();
|
|
239
|
+
}
|
|
240
|
+
}, _callee5);
|
|
241
|
+
})));
|
|
178
242
|
});
|
|
179
243
|
describe('onSend callback', function () {
|
|
180
244
|
var pendingRecipient = {
|
|
181
245
|
name: 'Alice',
|
|
182
246
|
email: 'alice@example.com'
|
|
183
247
|
};
|
|
184
|
-
it('should call onClose and skip share when there are no pending recipients', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
185
|
-
var
|
|
248
|
+
it('should call onClose and skip share when there are no pending recipients', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
|
|
249
|
+
var _setup6, findByText, sendButton;
|
|
186
250
|
|
|
187
|
-
return _regeneratorRuntime.wrap(function
|
|
188
|
-
while (1) switch (
|
|
251
|
+
return _regeneratorRuntime.wrap(function _callee6$(_context6) {
|
|
252
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
189
253
|
case 0:
|
|
190
254
|
// pendingRecipients defaults to [] via beforeEach
|
|
191
|
-
|
|
192
|
-
|
|
255
|
+
_setup6 = setup(), findByText = _setup6.findByText;
|
|
256
|
+
_context6.next = 3;
|
|
193
257
|
return findByText('Done');
|
|
194
258
|
|
|
195
259
|
case 3:
|
|
196
|
-
sendButton =
|
|
260
|
+
sendButton = _context6.sent;
|
|
197
261
|
fireEvent.click(sendButton);
|
|
198
|
-
|
|
262
|
+
_context6.next = 7;
|
|
199
263
|
return waitFor(function () {
|
|
200
264
|
expect(mockOnClose).toHaveBeenCalled();
|
|
201
265
|
expect(mockShare).not.toHaveBeenCalled();
|
|
@@ -203,15 +267,15 @@ describe('FederatedFolderModal', function () {
|
|
|
203
267
|
|
|
204
268
|
case 7:
|
|
205
269
|
case "end":
|
|
206
|
-
return
|
|
270
|
+
return _context6.stop();
|
|
207
271
|
}
|
|
208
|
-
},
|
|
272
|
+
}, _callee6);
|
|
209
273
|
})));
|
|
210
|
-
it('should call share with correct parameters', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
211
|
-
var
|
|
274
|
+
it('should call share with correct parameters', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7() {
|
|
275
|
+
var _setup7, findByText, sendButton;
|
|
212
276
|
|
|
213
|
-
return _regeneratorRuntime.wrap(function
|
|
214
|
-
while (1) switch (
|
|
277
|
+
return _regeneratorRuntime.wrap(function _callee7$(_context7) {
|
|
278
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
215
279
|
case 0:
|
|
216
280
|
usePendingRecipients.mockReturnValue({
|
|
217
281
|
pendingRecipients: [pendingRecipient],
|
|
@@ -221,14 +285,14 @@ describe('FederatedFolderModal', function () {
|
|
|
221
285
|
});
|
|
222
286
|
getOrCreateFromArray.mockResolvedValue([pendingRecipient]);
|
|
223
287
|
mockShare.mockResolvedValueOnce({});
|
|
224
|
-
|
|
225
|
-
|
|
288
|
+
_setup7 = setup(), findByText = _setup7.findByText;
|
|
289
|
+
_context7.next = 6;
|
|
226
290
|
return findByText('Done');
|
|
227
291
|
|
|
228
292
|
case 6:
|
|
229
|
-
sendButton =
|
|
293
|
+
sendButton = _context7.sent;
|
|
230
294
|
fireEvent.click(sendButton);
|
|
231
|
-
|
|
295
|
+
_context7.next = 10;
|
|
232
296
|
return waitFor(function () {
|
|
233
297
|
expect(mockShare).toHaveBeenCalledWith({
|
|
234
298
|
description: 'My Test Folder',
|
|
@@ -242,15 +306,15 @@ describe('FederatedFolderModal', function () {
|
|
|
242
306
|
|
|
243
307
|
case 10:
|
|
244
308
|
case "end":
|
|
245
|
-
return
|
|
309
|
+
return _context7.stop();
|
|
246
310
|
}
|
|
247
|
-
},
|
|
311
|
+
}, _callee7);
|
|
248
312
|
})));
|
|
249
|
-
it('should show success alert and close modal on successful share', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
250
|
-
var
|
|
313
|
+
it('should show success alert and close modal on successful share', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
|
|
314
|
+
var _setup8, findByText, sendButton;
|
|
251
315
|
|
|
252
|
-
return _regeneratorRuntime.wrap(function
|
|
253
|
-
while (1) switch (
|
|
316
|
+
return _regeneratorRuntime.wrap(function _callee8$(_context8) {
|
|
317
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
254
318
|
case 0:
|
|
255
319
|
usePendingRecipients.mockReturnValue({
|
|
256
320
|
pendingRecipients: [pendingRecipient],
|
|
@@ -260,14 +324,14 @@ describe('FederatedFolderModal', function () {
|
|
|
260
324
|
});
|
|
261
325
|
getOrCreateFromArray.mockResolvedValue([pendingRecipient]);
|
|
262
326
|
mockShare.mockResolvedValueOnce({});
|
|
263
|
-
|
|
264
|
-
|
|
327
|
+
_setup8 = setup(), findByText = _setup8.findByText;
|
|
328
|
+
_context8.next = 6;
|
|
265
329
|
return findByText('Done');
|
|
266
330
|
|
|
267
331
|
case 6:
|
|
268
|
-
sendButton =
|
|
332
|
+
sendButton = _context8.sent;
|
|
269
333
|
fireEvent.click(sendButton);
|
|
270
|
-
|
|
334
|
+
_context8.next = 10;
|
|
271
335
|
return waitFor(function () {
|
|
272
336
|
expect(mockShowAlert).toHaveBeenCalledWith({
|
|
273
337
|
message: 'Folder has been shared',
|
|
@@ -279,15 +343,15 @@ describe('FederatedFolderModal', function () {
|
|
|
279
343
|
|
|
280
344
|
case 10:
|
|
281
345
|
case "end":
|
|
282
|
-
return
|
|
346
|
+
return _context8.stop();
|
|
283
347
|
}
|
|
284
|
-
},
|
|
348
|
+
}, _callee8);
|
|
285
349
|
})));
|
|
286
|
-
it('should show error alert when share fails', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
287
|
-
var
|
|
350
|
+
it('should show error alert when share fails', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
|
|
351
|
+
var _setup9, findByText, sendButton;
|
|
288
352
|
|
|
289
|
-
return _regeneratorRuntime.wrap(function
|
|
290
|
-
while (1) switch (
|
|
353
|
+
return _regeneratorRuntime.wrap(function _callee9$(_context9) {
|
|
354
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
291
355
|
case 0:
|
|
292
356
|
usePendingRecipients.mockReturnValue({
|
|
293
357
|
pendingRecipients: [pendingRecipient],
|
|
@@ -297,14 +361,14 @@ describe('FederatedFolderModal', function () {
|
|
|
297
361
|
});
|
|
298
362
|
getOrCreateFromArray.mockResolvedValue([pendingRecipient]);
|
|
299
363
|
mockShare.mockRejectedValueOnce(new Error('Share failed'));
|
|
300
|
-
|
|
301
|
-
|
|
364
|
+
_setup9 = setup(), findByText = _setup9.findByText;
|
|
365
|
+
_context9.next = 6;
|
|
302
366
|
return findByText('Done');
|
|
303
367
|
|
|
304
368
|
case 6:
|
|
305
|
-
sendButton =
|
|
369
|
+
sendButton = _context9.sent;
|
|
306
370
|
fireEvent.click(sendButton);
|
|
307
|
-
|
|
371
|
+
_context9.next = 10;
|
|
308
372
|
return waitFor(function () {
|
|
309
373
|
expect(mockShowAlert).toHaveBeenCalledWith({
|
|
310
374
|
message: 'Error while sharing folder',
|
|
@@ -316,40 +380,40 @@ describe('FederatedFolderModal', function () {
|
|
|
316
380
|
|
|
317
381
|
case 10:
|
|
318
382
|
case "end":
|
|
319
|
-
return
|
|
383
|
+
return _context9.stop();
|
|
320
384
|
}
|
|
321
|
-
},
|
|
385
|
+
}, _callee9);
|
|
322
386
|
})));
|
|
323
387
|
});
|
|
324
388
|
describe('onClose callback', function () {
|
|
325
|
-
it('should call onClose when close button is clicked', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
326
|
-
var
|
|
389
|
+
it('should call onClose when close button is clicked', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
|
|
390
|
+
var _setup10, findByRole, closeButton;
|
|
327
391
|
|
|
328
|
-
return _regeneratorRuntime.wrap(function
|
|
329
|
-
while (1) switch (
|
|
392
|
+
return _regeneratorRuntime.wrap(function _callee10$(_context10) {
|
|
393
|
+
while (1) switch (_context10.prev = _context10.next) {
|
|
330
394
|
case 0:
|
|
331
|
-
|
|
332
|
-
|
|
395
|
+
_setup10 = setup(), findByRole = _setup10.findByRole;
|
|
396
|
+
_context10.next = 3;
|
|
333
397
|
return findByRole('button', {
|
|
334
398
|
name: /close/i
|
|
335
399
|
});
|
|
336
400
|
|
|
337
401
|
case 3:
|
|
338
|
-
closeButton =
|
|
402
|
+
closeButton = _context10.sent;
|
|
339
403
|
fireEvent.click(closeButton);
|
|
340
404
|
expect(mockOnClose).toHaveBeenCalled();
|
|
341
405
|
|
|
342
406
|
case 6:
|
|
343
407
|
case "end":
|
|
344
|
-
return
|
|
408
|
+
return _context10.stop();
|
|
345
409
|
}
|
|
346
|
-
},
|
|
410
|
+
}, _callee10);
|
|
347
411
|
})));
|
|
348
|
-
it('should ask confirmation when close button is clicked with pending recipients', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
349
|
-
var
|
|
412
|
+
it('should ask confirmation when close button is clicked with pending recipients', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11() {
|
|
413
|
+
var _setup11, getByRole, findByRole, getByText, closeButton;
|
|
350
414
|
|
|
351
|
-
return _regeneratorRuntime.wrap(function
|
|
352
|
-
while (1) switch (
|
|
415
|
+
return _regeneratorRuntime.wrap(function _callee11$(_context11) {
|
|
416
|
+
while (1) switch (_context11.prev = _context11.next) {
|
|
353
417
|
case 0:
|
|
354
418
|
usePendingRecipients.mockReturnValue({
|
|
355
419
|
pendingRecipients: [{
|
|
@@ -360,14 +424,14 @@ describe('FederatedFolderModal', function () {
|
|
|
360
424
|
selectedOption: 'readWrite',
|
|
361
425
|
setSelectedOption: jest.fn()
|
|
362
426
|
});
|
|
363
|
-
|
|
364
|
-
|
|
427
|
+
_setup11 = setup(), getByRole = _setup11.getByRole, findByRole = _setup11.findByRole, getByText = _setup11.getByText;
|
|
428
|
+
_context11.next = 4;
|
|
365
429
|
return findByRole('button', {
|
|
366
430
|
name: /close/i
|
|
367
431
|
});
|
|
368
432
|
|
|
369
433
|
case 4:
|
|
370
|
-
closeButton =
|
|
434
|
+
closeButton = _context11.sent;
|
|
371
435
|
fireEvent.click(closeButton);
|
|
372
436
|
expect(getByText("Discard the changes you haven't saved?")).toBeTruthy();
|
|
373
437
|
expect(mockOnClose).not.toHaveBeenCalled();
|
|
@@ -378,15 +442,15 @@ describe('FederatedFolderModal', function () {
|
|
|
378
442
|
|
|
379
443
|
case 10:
|
|
380
444
|
case "end":
|
|
381
|
-
return
|
|
445
|
+
return _context11.stop();
|
|
382
446
|
}
|
|
383
|
-
},
|
|
447
|
+
}, _callee11);
|
|
384
448
|
})));
|
|
385
|
-
it('should close after discard confirmation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
386
|
-
var
|
|
449
|
+
it('should close after discard confirmation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee12() {
|
|
450
|
+
var _setup12, getByRole, findByRole, getByText, closeButton;
|
|
387
451
|
|
|
388
|
-
return _regeneratorRuntime.wrap(function
|
|
389
|
-
while (1) switch (
|
|
452
|
+
return _regeneratorRuntime.wrap(function _callee12$(_context12) {
|
|
453
|
+
while (1) switch (_context12.prev = _context12.next) {
|
|
390
454
|
case 0:
|
|
391
455
|
usePendingRecipients.mockReturnValue({
|
|
392
456
|
pendingRecipients: [{
|
|
@@ -397,14 +461,14 @@ describe('FederatedFolderModal', function () {
|
|
|
397
461
|
selectedOption: 'readWrite',
|
|
398
462
|
setSelectedOption: jest.fn()
|
|
399
463
|
});
|
|
400
|
-
|
|
401
|
-
|
|
464
|
+
_setup12 = setup(), getByRole = _setup12.getByRole, findByRole = _setup12.findByRole, getByText = _setup12.getByText;
|
|
465
|
+
_context12.next = 4;
|
|
402
466
|
return findByRole('button', {
|
|
403
467
|
name: /close/i
|
|
404
468
|
});
|
|
405
469
|
|
|
406
470
|
case 4:
|
|
407
|
-
closeButton =
|
|
471
|
+
closeButton = _context12.sent;
|
|
408
472
|
fireEvent.click(closeButton);
|
|
409
473
|
expect(getByText("Discard the changes you haven't saved?")).toBeTruthy();
|
|
410
474
|
fireEvent.click(getByRole('button', {
|
|
@@ -414,9 +478,9 @@ describe('FederatedFolderModal', function () {
|
|
|
414
478
|
|
|
415
479
|
case 9:
|
|
416
480
|
case "end":
|
|
417
|
-
return
|
|
481
|
+
return _context12.stop();
|
|
418
482
|
}
|
|
419
|
-
},
|
|
483
|
+
}, _callee12);
|
|
420
484
|
})));
|
|
421
485
|
});
|
|
422
486
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-sharing",
|
|
3
|
-
"version": "33.0
|
|
3
|
+
"version": "33.1.0",
|
|
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": "9121c28a002700514566901dbab15401308bddbb"
|
|
87
87
|
}
|
|
@@ -15,6 +15,7 @@ import { getOrCreateFromArray } from '../../helpers/contacts'
|
|
|
15
15
|
import withLocales from '../../hoc/withLocales'
|
|
16
16
|
import { usePendingRecipients } from '../../hooks/usePendingRecipients'
|
|
17
17
|
import { useSharingContext } from '../../hooks/useSharingContext'
|
|
18
|
+
import styles from '../../styles/share.styl'
|
|
18
19
|
import AntivirusAlert from '../AntivirusAlert'
|
|
19
20
|
import { default as DumbShareByEmail } from '../ShareByEmail'
|
|
20
21
|
import ShareByLink from '../ShareByLink'
|
|
@@ -36,6 +37,8 @@ const FederatedFolderModalContent = ({
|
|
|
36
37
|
getOwner,
|
|
37
38
|
getSharingById,
|
|
38
39
|
getRecipients,
|
|
40
|
+
hasSharedChild,
|
|
41
|
+
hasSharedParent,
|
|
39
42
|
revoke
|
|
40
43
|
} = useSharingContext()
|
|
41
44
|
const { showAlert } = useAlert()
|
|
@@ -124,6 +127,14 @@ const FederatedFolderModalContent = ({
|
|
|
124
127
|
])
|
|
125
128
|
|
|
126
129
|
const folderName = existingDocument?.name || ''
|
|
130
|
+
const documentPath = existingDocument?.path
|
|
131
|
+
const hasParentRestriction = Boolean(
|
|
132
|
+
existingDocument?.driveId || (documentPath && hasSharedParent(documentPath))
|
|
133
|
+
)
|
|
134
|
+
const hasChildRestriction = Boolean(
|
|
135
|
+
documentPath && hasSharedChild(documentPath)
|
|
136
|
+
)
|
|
137
|
+
const canShareByEmail = !hasParentRestriction && !hasChildRestriction
|
|
127
138
|
|
|
128
139
|
const onSend = async () => {
|
|
129
140
|
if (isSending || pendingRecipients.length === 0) {
|
|
@@ -193,21 +204,45 @@ const FederatedFolderModalContent = ({
|
|
|
193
204
|
<AntivirusAlert
|
|
194
205
|
document={isSending ? frozenDoc : existingDocument}
|
|
195
206
|
/>
|
|
196
|
-
|
|
197
|
-
{
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
{!canShareByEmail && (
|
|
208
|
+
<div className={styles['share-byemail-onlybylink']}>
|
|
209
|
+
{t('Files.share.shareByEmail.onlyByLink', {
|
|
210
|
+
type: t(
|
|
211
|
+
`Files.share.shareByEmail.type.${
|
|
212
|
+
existingDocument?.type === 'file' ? 'file' : 'folder'
|
|
213
|
+
}`
|
|
214
|
+
)
|
|
215
|
+
})}{' '}
|
|
216
|
+
<strong>
|
|
217
|
+
{t(
|
|
218
|
+
`Files.share.shareByEmail.${
|
|
219
|
+
hasParentRestriction
|
|
220
|
+
? 'hasSharedParent'
|
|
221
|
+
: 'hasSharedChild'
|
|
222
|
+
}`
|
|
223
|
+
)}
|
|
224
|
+
</strong>
|
|
225
|
+
</div>
|
|
226
|
+
)}
|
|
227
|
+
{canShareByEmail && (
|
|
228
|
+
<>
|
|
229
|
+
<Typography variant="h6" className="u-mt-1-half u-mb-half">
|
|
230
|
+
{t('Share.contacts.addUsers')}
|
|
231
|
+
</Typography>
|
|
232
|
+
<DumbShareByEmail
|
|
233
|
+
currentRecipients={
|
|
234
|
+
isSending ? frozenRecipients : existingRecipients
|
|
235
|
+
}
|
|
236
|
+
document={isSending ? frozenDoc : existingDocument}
|
|
237
|
+
documentType="Files"
|
|
238
|
+
pendingRecipients={pendingRecipients}
|
|
239
|
+
onPendingRecipientsChange={setPendingRecipients}
|
|
240
|
+
selectedOption={selectedOption}
|
|
241
|
+
onSelectedOptionChange={setSelectedOption}
|
|
242
|
+
enableCreateContact
|
|
243
|
+
/>
|
|
244
|
+
</>
|
|
245
|
+
)}
|
|
211
246
|
</div>
|
|
212
247
|
<WhoHasAccess
|
|
213
248
|
isOwner
|
|
@@ -230,12 +265,14 @@ const FederatedFolderModalContent = ({
|
|
|
230
265
|
showGenerateLinkButton={showGenerateLinkButton}
|
|
231
266
|
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
232
267
|
/>
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
268
|
+
{canShareByEmail && (
|
|
269
|
+
<Button
|
|
270
|
+
variant="primary"
|
|
271
|
+
label={t('FederatedFolder.share')}
|
|
272
|
+
disabled={isSending}
|
|
273
|
+
onClick={onSend}
|
|
274
|
+
/>
|
|
275
|
+
)}
|
|
239
276
|
</>
|
|
240
277
|
}
|
|
241
278
|
/>
|
|
@@ -11,7 +11,10 @@ import AppLike from '../SharingBanner/test/AppLike'
|
|
|
11
11
|
const mockShare = jest.fn()
|
|
12
12
|
const mockRevoke = jest.fn()
|
|
13
13
|
const mockGetSharingLink = jest.fn()
|
|
14
|
+
const mockGetFederatedShareLink = jest.fn()
|
|
14
15
|
const mockGetRecipients = jest.fn().mockReturnValue([])
|
|
16
|
+
const mockHasSharedChild = jest.fn()
|
|
17
|
+
const mockHasSharedParent = jest.fn()
|
|
15
18
|
const mockShowAlert = jest.fn()
|
|
16
19
|
const mockOnClose = jest.fn()
|
|
17
20
|
|
|
@@ -20,8 +23,11 @@ jest.mock('../../hooks/useSharingContext', () => ({
|
|
|
20
23
|
share: mockShare,
|
|
21
24
|
revoke: mockRevoke,
|
|
22
25
|
getSharingLink: mockGetSharingLink,
|
|
26
|
+
getFederatedShareLink: mockGetFederatedShareLink,
|
|
23
27
|
getDocumentPermissions: jest.fn().mockReturnValue([]),
|
|
24
|
-
getRecipients: mockGetRecipients
|
|
28
|
+
getRecipients: mockGetRecipients,
|
|
29
|
+
hasSharedChild: mockHasSharedChild,
|
|
30
|
+
hasSharedParent: mockHasSharedParent
|
|
25
31
|
})
|
|
26
32
|
}))
|
|
27
33
|
|
|
@@ -84,7 +90,12 @@ describe('FederatedFolderModal', () => {
|
|
|
84
90
|
beforeEach(() => {
|
|
85
91
|
jest.clearAllMocks()
|
|
86
92
|
mockGetSharingLink.mockReturnValue('https://example.com/share/abc123')
|
|
93
|
+
mockGetFederatedShareLink.mockResolvedValue(
|
|
94
|
+
'https://example.com/share/federated-abc123'
|
|
95
|
+
)
|
|
87
96
|
mockGetRecipients.mockReturnValue([])
|
|
97
|
+
mockHasSharedChild.mockReturnValue(false)
|
|
98
|
+
mockHasSharedParent.mockReturnValue(false)
|
|
88
99
|
client = createTestClient()
|
|
89
100
|
sharingContextValue = createSharingContextValue()
|
|
90
101
|
usePendingRecipients.mockReturnValue({
|
|
@@ -127,6 +138,30 @@ describe('FederatedFolderModal', () => {
|
|
|
127
138
|
|
|
128
139
|
await findByText('Copy link')
|
|
129
140
|
})
|
|
141
|
+
|
|
142
|
+
it('should hide share by email when document is in federated shared folder received by current user', async () => {
|
|
143
|
+
const { findByText, queryByText } = setup({
|
|
144
|
+
document: { ...mockDocument, driveId: 'federated-folder-id' }
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
await findByText('Copy link')
|
|
148
|
+
|
|
149
|
+
expect(queryByText('Add users')).toBe(null)
|
|
150
|
+
expect(queryByText('Done')).toBe(null)
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
it('should show only by link message when document is in federated shared folder received by current user', async () => {
|
|
154
|
+
const { findByText } = setup({
|
|
155
|
+
document: {
|
|
156
|
+
...mockDocument,
|
|
157
|
+
driveId: 'federated-folder-id',
|
|
158
|
+
type: 'directory'
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
await findByText('This folder can only be shared by link, because')
|
|
163
|
+
await findByText('it has a shared parent')
|
|
164
|
+
})
|
|
130
165
|
})
|
|
131
166
|
|
|
132
167
|
describe('onSend callback', () => {
|