cozy-sharing 28.9.1 → 28.10.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 CHANGED
@@ -3,6 +3,16 @@
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
+ # [28.10.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@28.9.2...cozy-sharing@28.10.0) (2026-03-17)
7
+
8
+ ### Features
9
+
10
+ - Allow to revoke shared drive file sharing link ([7cff1da](https://github.com/cozy/cozy-libs/commit/7cff1da36a8b048a25efd302a5e3e0efb114e327))
11
+
12
+ ## [28.9.2](https://github.com/cozy/cozy-libs/compare/cozy-sharing@28.9.1...cozy-sharing@28.9.2) (2026-03-16)
13
+
14
+ **Note:** Version bump only for package cozy-sharing
15
+
6
16
  ## [28.9.1](https://github.com/cozy/cozy-libs/compare/cozy-sharing@28.9.0...cozy-sharing@28.9.1) (2026-03-16)
7
17
 
8
18
  **Note:** Version bump only for package cozy-sharing
@@ -788,32 +788,73 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
788
788
  };
789
789
  }());
790
790
 
791
- _defineProperty(_this2, "revokeSharingLink", /*#__PURE__*/function () {
792
- var _ref18 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee16(document) {
793
- var perms;
791
+ _defineProperty(_this2, "revokeSharedDriveSharingLink", /*#__PURE__*/function () {
792
+ var _ref18 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee16(document, perms) {
793
+ var client, drivePermissionCollection;
794
794
  return _regeneratorRuntime.wrap(function _callee16$(_context16) {
795
795
  while (1) switch (_context16.prev = _context16.next) {
796
+ case 0:
797
+ client = _this2.props.client;
798
+ drivePermissionCollection = client.collection('io.cozy.permissions', {
799
+ driveId: document.driveId
800
+ });
801
+ _context16.next = 4;
802
+ return Promise.all(perms.map(function (p) {
803
+ return drivePermissionCollection.destroy(p);
804
+ }));
805
+
806
+ case 4:
807
+ case "end":
808
+ return _context16.stop();
809
+ }
810
+ }, _callee16);
811
+ }));
812
+
813
+ return function (_x30, _x31) {
814
+ return _ref18.apply(this, arguments);
815
+ };
816
+ }());
817
+
818
+ _defineProperty(_this2, "revokeSharingLink", /*#__PURE__*/function () {
819
+ var _ref19 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee17(document) {
820
+ var perms;
821
+ return _regeneratorRuntime.wrap(function _callee17$(_context17) {
822
+ while (1) switch (_context17.prev = _context17.next) {
796
823
  case 0:
797
824
  // Because some duplicate links have been created in the past, we must ensure
798
825
  // we revoke all of them
799
826
  perms = _getDocumentPermissions(_this2.state, document.id);
800
- _context16.next = 3;
827
+
828
+ if (!document.driveId) {
829
+ _context17.next = 6;
830
+ break;
831
+ }
832
+
833
+ _context17.next = 4;
834
+ return _this2.revokeSharedDriveSharingLink(document, perms);
835
+
836
+ case 4:
837
+ _context17.next = 8;
838
+ break;
839
+
840
+ case 6:
841
+ _context17.next = 8;
801
842
  return Promise.all(perms.map(function (p) {
802
843
  return _this2.permissionCol.destroy(p);
803
844
  }));
804
845
 
805
- case 3:
846
+ case 8:
806
847
  _this2.dispatch(revokeSharingLink(perms));
807
848
 
808
- case 4:
849
+ case 9:
809
850
  case "end":
810
- return _context16.stop();
851
+ return _context17.stop();
811
852
  }
812
- }, _callee16);
853
+ }, _callee17);
813
854
  }));
814
855
 
815
- return function (_x30) {
816
- return _ref18.apply(this, arguments);
856
+ return function (_x32) {
857
+ return _ref19.apply(this, arguments);
817
858
  };
818
859
  }());
819
860
 
@@ -937,14 +978,14 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
937
978
  }, {
938
979
  key: "fetchAllSharings",
939
980
  value: function () {
940
- var _fetchAllSharings = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee17() {
981
+ var _fetchAllSharings = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee18() {
941
982
  var _this$props, doctype, client, _yield$Promise$all, _yield$Promise$all2, sharings, permissions, apps, sharedDocIds, resp, folderPaths, filePaths;
942
983
 
943
- return _regeneratorRuntime.wrap(function _callee17$(_context17) {
944
- while (1) switch (_context17.prev = _context17.next) {
984
+ return _regeneratorRuntime.wrap(function _callee18$(_context18) {
985
+ while (1) switch (_context18.prev = _context18.next) {
945
986
  case 0:
946
987
  if (!this.isPublic) {
947
- _context17.next = 4;
988
+ _context18.next = 4;
948
989
  break;
949
990
  }
950
991
 
@@ -953,17 +994,17 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
953
994
  this.setState({
954
995
  allLoaded: true
955
996
  });
956
- return _context17.abrupt("return");
997
+ return _context18.abrupt("return");
957
998
 
958
999
  case 4:
959
1000
  _this$props = this.props, doctype = _this$props.doctype, client = _this$props.client;
960
- _context17.next = 7;
1001
+ _context18.next = 7;
961
1002
  return Promise.all([this.sharingCol.findByDoctype(doctype, {
962
1003
  withSharedDocs: false
963
1004
  }), this.permissionCol.findLinksByDoctype(doctype), client.fetchQueryAndGetFromState(fetchApps())]);
964
1005
 
965
1006
  case 7:
966
- _yield$Promise$all = _context17.sent;
1007
+ _yield$Promise$all = _context18.sent;
967
1008
  _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 3);
968
1009
  sharings = _yield$Promise$all2[0];
969
1010
  permissions = _yield$Promise$all2[1];
@@ -977,35 +1018,35 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
977
1018
  this.setState({
978
1019
  hasLoadedAtLeastOnePage: true
979
1020
  });
980
- _context17.next = 16;
1021
+ _context18.next = 16;
981
1022
  return fetchNextPermissions(permissions, this.dispatch, this.permissionCol);
982
1023
 
983
1024
  case 16:
984
1025
  if (!(doctype === 'io.cozy.files')) {
985
- _context17.next = 26;
1026
+ _context18.next = 26;
986
1027
  break;
987
1028
  }
988
1029
 
989
1030
  sharedDocIds = getSharedDocIdsBySharings(sharings);
990
- _context17.next = 20;
1031
+ _context18.next = 20;
991
1032
  return client.collection(doctype).all({
992
1033
  keys: sharedDocIds
993
1034
  });
994
1035
 
995
1036
  case 20:
996
- resp = _context17.sent;
1037
+ resp = _context18.sent;
997
1038
  folderPaths = resp.data.filter(function (f) {
998
1039
  return f.type === 'directory' && !f.trashed;
999
1040
  }).map(function (f) {
1000
1041
  return f.path;
1001
1042
  });
1002
- _context17.next = 24;
1043
+ _context18.next = 24;
1003
1044
  return fetchFilesPaths(client, doctype, resp.data.filter(function (f) {
1004
1045
  return f.type !== 'directory' && !f.trashed;
1005
1046
  }));
1006
1047
 
1007
1048
  case 24:
1008
- filePaths = _context17.sent;
1049
+ filePaths = _context18.sent;
1009
1050
  this.dispatch(receivePaths([].concat(_toConsumableArray(folderPaths), _toConsumableArray(filePaths))));
1010
1051
 
1011
1052
  case 26:
@@ -1015,9 +1056,9 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
1015
1056
 
1016
1057
  case 27:
1017
1058
  case "end":
1018
- return _context17.stop();
1059
+ return _context18.stop();
1019
1060
  }
1020
- }, _callee17, this);
1061
+ }, _callee18, this);
1021
1062
  }));
1022
1063
 
1023
1064
  function fetchAllSharings() {
@@ -257,6 +257,102 @@ describe('shareByLink', function () {
257
257
  }, _callee4);
258
258
  })));
259
259
  });
260
+ describe('revokeSharingLink', function () {
261
+ var PERM = {
262
+ type: 'io.cozy.permissions',
263
+ id: 'perm_1',
264
+ attributes: {
265
+ type: 'share',
266
+ permissions: {
267
+ rule0: {
268
+ type: 'io.cozy.files',
269
+ verbs: ['GET'],
270
+ values: ['file_id']
271
+ }
272
+ }
273
+ }
274
+ };
275
+ var provider;
276
+ var mockDestroy;
277
+ beforeEach(function () {
278
+ mockDestroy = jest.fn().mockResolvedValue({});
279
+ var mockClient = createMockClient({});
280
+
281
+ mockClient.getStackClient = function () {
282
+ return {
283
+ uri: 'http://cozy.local'
284
+ };
285
+ };
286
+
287
+ mockClient.collection = jest.fn().mockReturnValue({
288
+ destroy: mockDestroy
289
+ });
290
+ provider = new SharingProvider({
291
+ client: mockClient
292
+ });
293
+ provider.state = reducer(undefined, addSharingLink(PERM));
294
+ provider.dispatch = jest.fn(function (action) {
295
+ provider.state = reducer(provider.state, action);
296
+ });
297
+ });
298
+ it('uses permissionCol.destroy for a regular file', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
299
+ var regularFile;
300
+ return _regeneratorRuntime.wrap(function _callee5$(_context5) {
301
+ while (1) switch (_context5.prev = _context5.next) {
302
+ case 0:
303
+ regularFile = {
304
+ _id: 'file_id',
305
+ id: 'file_id'
306
+ };
307
+ provider.permissionCol = {
308
+ destroy: mockDestroy
309
+ };
310
+ _context5.next = 4;
311
+ return provider.revokeSharingLink(regularFile);
312
+
313
+ case 4:
314
+ expect(mockDestroy).toHaveBeenCalledTimes(1);
315
+ expect(mockDestroy).toHaveBeenCalledWith(PERM);
316
+ expect(provider.dispatch).toHaveBeenCalledTimes(1);
317
+
318
+ case 7:
319
+ case "end":
320
+ return _context5.stop();
321
+ }
322
+ }, _callee5);
323
+ })));
324
+ it('uses drivePermissionCollection.destroy for a shared drive file', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
325
+ var driveFile, mockDriveCollection;
326
+ return _regeneratorRuntime.wrap(function _callee6$(_context6) {
327
+ while (1) switch (_context6.prev = _context6.next) {
328
+ case 0:
329
+ driveFile = {
330
+ _id: 'file_id',
331
+ id: 'file_id',
332
+ driveId: 'drive_123'
333
+ };
334
+ mockDriveCollection = {
335
+ destroy: mockDestroy
336
+ };
337
+ provider.props.client.collection = jest.fn().mockReturnValue(mockDriveCollection);
338
+ _context6.next = 5;
339
+ return provider.revokeSharingLink(driveFile);
340
+
341
+ case 5:
342
+ expect(provider.props.client.collection).toHaveBeenCalledWith('io.cozy.permissions', {
343
+ driveId: 'drive_123'
344
+ });
345
+ expect(mockDestroy).toHaveBeenCalledTimes(1);
346
+ expect(mockDestroy).toHaveBeenCalledWith(PERM);
347
+ expect(provider.dispatch).toHaveBeenCalledTimes(1);
348
+
349
+ case 9:
350
+ case "end":
351
+ return _context6.stop();
352
+ }
353
+ }, _callee6);
354
+ })));
355
+ });
260
356
  describe('updateDocumentPermissions', function () {
261
357
  var PERM_DRIVE_FILE = {
262
358
  type: 'io.cozy.permissions',
@@ -275,10 +371,10 @@ describe('updateDocumentPermissions', function () {
275
371
  }
276
372
  }
277
373
  };
278
- it('sends only one PATCH request for a shared drive file', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
374
+ it('sends only one PATCH request for a shared drive file', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7() {
279
375
  var driveFile, mockAdd, mockClient, provider;
280
- return _regeneratorRuntime.wrap(function _callee5$(_context5) {
281
- while (1) switch (_context5.prev = _context5.next) {
376
+ return _regeneratorRuntime.wrap(function _callee7$(_context7) {
377
+ while (1) switch (_context7.prev = _context7.next) {
282
378
  case 0:
283
379
  driveFile = {
284
380
  _id: 'file_in_drive',
@@ -298,7 +394,7 @@ describe('updateDocumentPermissions', function () {
298
394
 
299
395
  provider.state = reducer(undefined, addSharingLink(PERM_DRIVE_FILE));
300
396
  provider.dispatch = jest.fn();
301
- _context5.next = 9;
397
+ _context7.next = 9;
302
398
  return provider.updateDocumentPermissions(driveFile, {
303
399
  verbs: ['GET'],
304
400
  expiresAt: '',
@@ -310,9 +406,9 @@ describe('updateDocumentPermissions', function () {
310
406
 
311
407
  case 10:
312
408
  case "end":
313
- return _context5.stop();
409
+ return _context7.stop();
314
410
  }
315
- }, _callee5);
411
+ }, _callee7);
316
412
  })));
317
413
  });
318
414
  describe('updateSharingMemberType', function () {
@@ -362,53 +458,53 @@ describe('updateSharingMemberType', function () {
362
458
  };
363
459
  jest.spyOn(instance, 'addRecipients').mockResolvedValue({});
364
460
  });
365
- it('should throw when sharing is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
366
- return _regeneratorRuntime.wrap(function _callee6$(_context6) {
367
- while (1) switch (_context6.prev = _context6.next) {
461
+ it('should throw when sharing is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
462
+ return _regeneratorRuntime.wrap(function _callee8$(_context8) {
463
+ while (1) switch (_context8.prev = _context8.next) {
368
464
  case 0:
369
- _context6.next = 2;
465
+ _context8.next = 2;
370
466
  return expect(instance.updateSharingMemberType('unknown-id', 1, 'one-way')).rejects.toThrow('Sharing not found');
371
467
 
372
468
  case 2:
373
469
  case "end":
374
- return _context6.stop();
470
+ return _context8.stop();
375
471
  }
376
- }, _callee6);
472
+ }, _callee8);
377
473
  })));
378
- it('should throw when member is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7() {
379
- return _regeneratorRuntime.wrap(function _callee7$(_context7) {
380
- while (1) switch (_context7.prev = _context7.next) {
474
+ it('should throw when member is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
475
+ return _regeneratorRuntime.wrap(function _callee9$(_context9) {
476
+ while (1) switch (_context9.prev = _context9.next) {
381
477
  case 0:
382
- _context7.next = 2;
478
+ _context9.next = 2;
383
479
  return expect(instance.updateSharingMemberType('sharing-123', 99, 'one-way')).rejects.toThrow('Member not found');
384
480
 
385
481
  case 2:
386
482
  case "end":
387
- return _context7.stop();
483
+ return _context9.stop();
388
484
  }
389
- }, _callee7);
485
+ }, _callee9);
390
486
  })));
391
- it('should throw when contact is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
392
- return _regeneratorRuntime.wrap(function _callee8$(_context8) {
393
- while (1) switch (_context8.prev = _context8.next) {
487
+ it('should throw when contact is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
488
+ return _regeneratorRuntime.wrap(function _callee10$(_context10) {
489
+ while (1) switch (_context10.prev = _context10.next) {
394
490
  case 0:
395
491
  mockContactsCollection.find.mockResolvedValue({
396
492
  data: []
397
493
  });
398
- _context8.next = 3;
494
+ _context10.next = 3;
399
495
  return expect(instance.updateSharingMemberType('sharing-123', 1, 'one-way')).rejects.toThrow('Contact not found');
400
496
 
401
497
  case 3:
402
498
  case "end":
403
- return _context8.stop();
499
+ return _context10.stop();
404
500
  }
405
- }, _callee8);
501
+ }, _callee10);
406
502
  })));
407
- it('should revoke and re-add with readOnly when switching to one-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
408
- return _regeneratorRuntime.wrap(function _callee9$(_context9) {
409
- while (1) switch (_context9.prev = _context9.next) {
503
+ it('should revoke and re-add with readOnly when switching to one-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11() {
504
+ return _regeneratorRuntime.wrap(function _callee11$(_context11) {
505
+ while (1) switch (_context11.prev = _context11.next) {
410
506
  case 0:
411
- _context9.next = 2;
507
+ _context11.next = 2;
412
508
  return instance.updateSharingMemberType('sharing-123', 1, 'one-way');
413
509
 
414
510
  case 2:
@@ -421,15 +517,15 @@ describe('updateSharingMemberType', function () {
421
517
 
422
518
  case 4:
423
519
  case "end":
424
- return _context9.stop();
520
+ return _context11.stop();
425
521
  }
426
- }, _callee9);
522
+ }, _callee11);
427
523
  })));
428
- it('should revoke and re-add as read-write when switching to two-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
429
- return _regeneratorRuntime.wrap(function _callee10$(_context10) {
430
- while (1) switch (_context10.prev = _context10.next) {
524
+ it('should revoke and re-add as read-write when switching to two-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee12() {
525
+ return _regeneratorRuntime.wrap(function _callee12$(_context12) {
526
+ while (1) switch (_context12.prev = _context12.next) {
431
527
  case 0:
432
- _context10.next = 2;
528
+ _context12.next = 2;
433
529
  return instance.updateSharingMemberType('sharing-123', 1, 'two-way');
434
530
 
435
531
  case 2:
@@ -442,23 +538,23 @@ describe('updateSharingMemberType', function () {
442
538
 
443
539
  case 4:
444
540
  case "end":
445
- return _context10.stop();
541
+ return _context12.stop();
446
542
  }
447
- }, _callee10);
543
+ }, _callee12);
448
544
  })));
449
- it('should rethrow error if addRecipients fails after revocation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11() {
450
- return _regeneratorRuntime.wrap(function _callee11$(_context11) {
451
- while (1) switch (_context11.prev = _context11.next) {
545
+ it('should rethrow error if addRecipients fails after revocation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee13() {
546
+ return _regeneratorRuntime.wrap(function _callee13$(_context13) {
547
+ while (1) switch (_context13.prev = _context13.next) {
452
548
  case 0:
453
549
  instance.addRecipients.mockRejectedValue(new Error('Network error'));
454
- _context11.next = 3;
550
+ _context13.next = 3;
455
551
  return expect(instance.updateSharingMemberType('sharing-123', 1, 'one-way')).rejects.toThrow('Network error');
456
552
 
457
553
  case 3:
458
554
  case "end":
459
- return _context11.stop();
555
+ return _context13.stop();
460
556
  }
461
- }, _callee11);
557
+ }, _callee13);
462
558
  })));
463
559
  }); // TODO Convert with react-testing-library
464
560
  // describe('hasWriteAccess', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-sharing",
3
- "version": "28.9.1",
3
+ "version": "28.10.0",
4
4
  "description": "Provides sharing login for React applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -59,14 +59,14 @@
59
59
  "cozy-intent": "^2.30.4",
60
60
  "cozy-minilog": "^3.10.1",
61
61
  "cozy-ui": "^135.0.0",
62
- "cozy-ui-plus": "^5.2.2",
62
+ "cozy-ui-plus": "^5.2.3",
63
63
  "jest": "27.5.1",
64
64
  "jest-environment-jsdom": "27.5.1",
65
65
  "react": "16.12.0",
66
66
  "react-dom": "16.13.0",
67
67
  "react-router": "^5.0.1",
68
68
  "storybook": "7.6.0",
69
- "twake-i18n": "^0.3.3"
69
+ "twake-i18n": "^0.3.4"
70
70
  },
71
71
  "peerDependencies": {
72
72
  "cozy-client": ">=60.22.0",
@@ -83,5 +83,5 @@
83
83
  "sideEffects": [
84
84
  "*.css"
85
85
  ],
86
- "gitHead": "81041f18f0134c0ead8f325adc27e6182965c875"
86
+ "gitHead": "e7dd5e7bebc8462801a3851ae9658b6dd50a2ffd"
87
87
  }
@@ -496,11 +496,23 @@ export class SharingProvider extends Component {
496
496
  return responses
497
497
  }
498
498
 
499
+ revokeSharedDriveSharingLink = async (document, perms) => {
500
+ const { client } = this.props
501
+ const drivePermissionCollection = client.collection('io.cozy.permissions', {
502
+ driveId: document.driveId
503
+ })
504
+ await Promise.all(perms.map(p => drivePermissionCollection.destroy(p)))
505
+ }
506
+
499
507
  revokeSharingLink = async document => {
500
508
  // Because some duplicate links have been created in the past, we must ensure
501
509
  // we revoke all of them
502
510
  const perms = getDocumentPermissions(this.state, document.id)
503
- await Promise.all(perms.map(p => this.permissionCol.destroy(p)))
511
+ if (document.driveId) {
512
+ await this.revokeSharedDriveSharingLink(document, perms)
513
+ } else {
514
+ await Promise.all(perms.map(p => this.permissionCol.destroy(p)))
515
+ }
504
516
  this.dispatch(revokeSharingLink(perms))
505
517
  }
506
518
 
@@ -192,6 +192,63 @@ describe('shareByLink', () => {
192
192
  })
193
193
  })
194
194
 
195
+ describe('revokeSharingLink', () => {
196
+ const PERM = {
197
+ type: 'io.cozy.permissions',
198
+ id: 'perm_1',
199
+ attributes: {
200
+ type: 'share',
201
+ permissions: {
202
+ rule0: { type: 'io.cozy.files', verbs: ['GET'], values: ['file_id'] }
203
+ }
204
+ }
205
+ }
206
+
207
+ let provider
208
+ let mockDestroy
209
+
210
+ beforeEach(() => {
211
+ mockDestroy = jest.fn().mockResolvedValue({})
212
+ const mockClient = createMockClient({})
213
+ mockClient.getStackClient = () => ({ uri: 'http://cozy.local' })
214
+ mockClient.collection = jest.fn().mockReturnValue({ destroy: mockDestroy })
215
+ provider = new SharingProvider({ client: mockClient })
216
+ provider.state = reducer(undefined, addSharingLink(PERM))
217
+ provider.dispatch = jest.fn(action => {
218
+ provider.state = reducer(provider.state, action)
219
+ })
220
+ })
221
+
222
+ it('uses permissionCol.destroy for a regular file', async () => {
223
+ const regularFile = { _id: 'file_id', id: 'file_id' }
224
+ provider.permissionCol = { destroy: mockDestroy }
225
+
226
+ await provider.revokeSharingLink(regularFile)
227
+
228
+ expect(mockDestroy).toHaveBeenCalledTimes(1)
229
+ expect(mockDestroy).toHaveBeenCalledWith(PERM)
230
+ expect(provider.dispatch).toHaveBeenCalledTimes(1)
231
+ })
232
+
233
+ it('uses drivePermissionCollection.destroy for a shared drive file', async () => {
234
+ const driveFile = { _id: 'file_id', id: 'file_id', driveId: 'drive_123' }
235
+ const mockDriveCollection = { destroy: mockDestroy }
236
+ provider.props.client.collection = jest
237
+ .fn()
238
+ .mockReturnValue(mockDriveCollection)
239
+
240
+ await provider.revokeSharingLink(driveFile)
241
+
242
+ expect(provider.props.client.collection).toHaveBeenCalledWith(
243
+ 'io.cozy.permissions',
244
+ { driveId: 'drive_123' }
245
+ )
246
+ expect(mockDestroy).toHaveBeenCalledTimes(1)
247
+ expect(mockDestroy).toHaveBeenCalledWith(PERM)
248
+ expect(provider.dispatch).toHaveBeenCalledTimes(1)
249
+ })
250
+ })
251
+
195
252
  describe('updateDocumentPermissions', () => {
196
253
  const PERM_DRIVE_FILE = {
197
254
  type: 'io.cozy.permissions',