cozy-sharing 38.1.0 → 38.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/SharingProvider.js +3 -2
- package/dist/SharingProvider.spec.js +148 -110
- package/dist/components/FederatedFolder/FederatedFolderModal.js +4 -3
- package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +185 -153
- package/dist/components/ShareModal/ShareModal.js +2 -2
- package/dist/components/ShareModal/ShareModal.spec.js +79 -0
- package/package.json +3 -3
- package/src/SharingProvider.jsx +4 -1
- package/src/SharingProvider.spec.jsx +26 -0
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +7 -3
- package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +22 -0
- package/src/components/ShareModal/ShareModal.jsx +4 -2
- package/src/components/ShareModal/ShareModal.spec.jsx +66 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,19 @@
|
|
|
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
|
+
## [38.1.2](https://github.com/cozy/cozy-libs/compare/cozy-sharing@38.1.1...cozy-sharing@38.1.2) (2026-09-23)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **sharing:** Reuse the ancestor drive sharing for nested documents ([698048c](https://github.com/cozy/cozy-libs/commit/698048c808fc5f244a57ced6498cb0a9f6562df0))
|
|
11
|
+
|
|
12
|
+
## [38.1.1](https://github.com/cozy/cozy-libs/compare/cozy-sharing@38.1.0...cozy-sharing@38.1.1) (2026-09-21)
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- **sharing:** Keep full share modal for nested-folder editors ([014c848](https://github.com/cozy/cozy-libs/commit/014c848bb46699cee47eb4baf8bb7a365edaf2f1))
|
|
17
|
+
- **sharing:** Show editable share modal for members with write access ([cba3a13](https://github.com/cozy/cozy-libs/commit/cba3a13185d1fe088136c3a758ec94f0d3472b69))
|
|
18
|
+
|
|
6
19
|
# [38.1.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@38.0.0...cozy-sharing@38.1.0) (2026-09-16)
|
|
7
20
|
|
|
8
21
|
### Features
|
package/dist/SharingProvider.js
CHANGED
|
@@ -136,8 +136,9 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
|
|
|
136
136
|
while (1) switch (_context2.prev = _context2.next) {
|
|
137
137
|
case 0:
|
|
138
138
|
document = _ref2.document, recipients = _ref2.recipients, readOnlyRecipients = _ref2.readOnlyRecipients, description = _ref2.description, openSharing = _ref2.openSharing, sharedDrive = _ref2.sharedDrive;
|
|
139
|
-
_this2$props2 = _this2.props, client = _this2$props2.client, doctype = _this2$props2.doctype;
|
|
140
|
-
|
|
139
|
+
_this2$props2 = _this2.props, client = _this2$props2.client, doctype = _this2$props2.doctype; // Documents nested in a shared drive have no sharing of their own
|
|
140
|
+
|
|
141
|
+
sharing = getDocumentSharing(_this2.state, document.id) || (document.driveId ? _getSharingById(_this2.state, document.driveId) : null);
|
|
141
142
|
|
|
142
143
|
if (!sharing) {
|
|
143
144
|
_context2.next = 12;
|
|
@@ -793,6 +793,44 @@ describe('shared drive recipient revocation', function () {
|
|
|
793
793
|
}
|
|
794
794
|
}, _callee14);
|
|
795
795
|
})));
|
|
796
|
+
it('adds recipients to the existing shared drive when sharing a document nested inside it', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee15() {
|
|
797
|
+
var nestedDocument;
|
|
798
|
+
return _regeneratorRuntime.wrap(function _callee15$(_context15) {
|
|
799
|
+
while (1) switch (_context15.prev = _context15.next) {
|
|
800
|
+
case 0:
|
|
801
|
+
sharingCol.addRecipients.mockResolvedValue({
|
|
802
|
+
data: SHARED_DRIVE
|
|
803
|
+
});
|
|
804
|
+
nestedDocument = {
|
|
805
|
+
_id: 'nested_folder_456',
|
|
806
|
+
id: 'nested_folder_456',
|
|
807
|
+
driveId: SHARED_DRIVE.id,
|
|
808
|
+
path: '/Shared folder/Sub folder'
|
|
809
|
+
};
|
|
810
|
+
_context15.next = 4;
|
|
811
|
+
return provider.share({
|
|
812
|
+
document: nestedDocument,
|
|
813
|
+
recipients: [recipient],
|
|
814
|
+
readOnlyRecipients: [],
|
|
815
|
+
description: 'Sub folder',
|
|
816
|
+
openSharing: false,
|
|
817
|
+
sharedDrive: true
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
case 4:
|
|
821
|
+
expect(sharingCol.create).not.toHaveBeenCalled();
|
|
822
|
+
expect(sharingCol.addRecipients).toHaveBeenCalledWith({
|
|
823
|
+
document: SHARED_DRIVE,
|
|
824
|
+
recipients: [recipient],
|
|
825
|
+
readOnlyRecipients: []
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
case 6:
|
|
829
|
+
case "end":
|
|
830
|
+
return _context15.stop();
|
|
831
|
+
}
|
|
832
|
+
}, _callee15);
|
|
833
|
+
})));
|
|
796
834
|
});
|
|
797
835
|
describe('fetchSharedDriveSharingLinks', function () {
|
|
798
836
|
var PERM_DRIVE_FILE = {
|
|
@@ -817,10 +855,10 @@ describe('fetchSharedDriveSharingLinks', function () {
|
|
|
817
855
|
id: 'file_in_drive',
|
|
818
856
|
driveId: 'drive_123'
|
|
819
857
|
};
|
|
820
|
-
it('fetches shared drive sharing links by file id', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
858
|
+
it('fetches shared drive sharing links by file id', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee16() {
|
|
821
859
|
var mockFindLinksByIds, mockClient, provider, result, permissions;
|
|
822
|
-
return _regeneratorRuntime.wrap(function
|
|
823
|
-
while (1) switch (
|
|
860
|
+
return _regeneratorRuntime.wrap(function _callee16$(_context16) {
|
|
861
|
+
while (1) switch (_context16.prev = _context16.next) {
|
|
824
862
|
case 0:
|
|
825
863
|
mockFindLinksByIds = jest.fn().mockResolvedValue({
|
|
826
864
|
data: [PERM_DRIVE_FILE]
|
|
@@ -830,11 +868,11 @@ describe('fetchSharedDriveSharingLinks', function () {
|
|
|
830
868
|
findLinksByIds: mockFindLinksByIds
|
|
831
869
|
});
|
|
832
870
|
provider = setupProvider(mockClient);
|
|
833
|
-
|
|
871
|
+
_context16.next = 6;
|
|
834
872
|
return provider.fetchSharedDriveSharingLinks(driveFile);
|
|
835
873
|
|
|
836
874
|
case 6:
|
|
837
|
-
result =
|
|
875
|
+
result = _context16.sent;
|
|
838
876
|
expect(mockClient.collection).toHaveBeenCalledWith('io.cozy.permissions', {
|
|
839
877
|
driveId: 'drive_123'
|
|
840
878
|
});
|
|
@@ -847,14 +885,14 @@ describe('fetchSharedDriveSharingLinks', function () {
|
|
|
847
885
|
|
|
848
886
|
case 14:
|
|
849
887
|
case "end":
|
|
850
|
-
return
|
|
888
|
+
return _context16.stop();
|
|
851
889
|
}
|
|
852
|
-
},
|
|
890
|
+
}, _callee16);
|
|
853
891
|
})));
|
|
854
|
-
it('returns an empty array and skips the API call for non-shared-drive documents', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
892
|
+
it('returns an empty array and skips the API call for non-shared-drive documents', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee17() {
|
|
855
893
|
var mockClient, findLinksByIds, provider, result;
|
|
856
|
-
return _regeneratorRuntime.wrap(function
|
|
857
|
-
while (1) switch (
|
|
894
|
+
return _regeneratorRuntime.wrap(function _callee17$(_context17) {
|
|
895
|
+
while (1) switch (_context17.prev = _context17.next) {
|
|
858
896
|
case 0:
|
|
859
897
|
mockClient = createMockClient({});
|
|
860
898
|
findLinksByIds = jest.fn();
|
|
@@ -863,27 +901,27 @@ describe('fetchSharedDriveSharingLinks', function () {
|
|
|
863
901
|
});
|
|
864
902
|
provider = setupProvider(mockClient);
|
|
865
903
|
provider.dispatch = jest.fn();
|
|
866
|
-
|
|
904
|
+
_context17.next = 7;
|
|
867
905
|
return provider.fetchSharedDriveSharingLinks({
|
|
868
906
|
_id: 'regular_file'
|
|
869
907
|
});
|
|
870
908
|
|
|
871
909
|
case 7:
|
|
872
|
-
result =
|
|
910
|
+
result = _context17.sent;
|
|
873
911
|
expect(result).toEqual([]);
|
|
874
912
|
expect(findLinksByIds).not.toHaveBeenCalled();
|
|
875
913
|
expect(provider.dispatch).not.toHaveBeenCalled();
|
|
876
914
|
|
|
877
915
|
case 11:
|
|
878
916
|
case "end":
|
|
879
|
-
return
|
|
917
|
+
return _context17.stop();
|
|
880
918
|
}
|
|
881
|
-
},
|
|
919
|
+
}, _callee17);
|
|
882
920
|
})));
|
|
883
|
-
it('uses document.id as a fallback when _id is missing', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
921
|
+
it('uses document.id as a fallback when _id is missing', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee18() {
|
|
884
922
|
var mockFindLinksByIds, mockClient, provider;
|
|
885
|
-
return _regeneratorRuntime.wrap(function
|
|
886
|
-
while (1) switch (
|
|
923
|
+
return _regeneratorRuntime.wrap(function _callee18$(_context18) {
|
|
924
|
+
while (1) switch (_context18.prev = _context18.next) {
|
|
887
925
|
case 0:
|
|
888
926
|
mockFindLinksByIds = jest.fn().mockResolvedValue({
|
|
889
927
|
data: [PERM_DRIVE_FILE]
|
|
@@ -893,7 +931,7 @@ describe('fetchSharedDriveSharingLinks', function () {
|
|
|
893
931
|
findLinksByIds: mockFindLinksByIds
|
|
894
932
|
});
|
|
895
933
|
provider = setupProvider(mockClient);
|
|
896
|
-
|
|
934
|
+
_context18.next = 6;
|
|
897
935
|
return provider.fetchSharedDriveSharingLinks({
|
|
898
936
|
id: 'file_in_drive',
|
|
899
937
|
driveId: 'drive_123'
|
|
@@ -904,14 +942,14 @@ describe('fetchSharedDriveSharingLinks', function () {
|
|
|
904
942
|
|
|
905
943
|
case 7:
|
|
906
944
|
case "end":
|
|
907
|
-
return
|
|
945
|
+
return _context18.stop();
|
|
908
946
|
}
|
|
909
|
-
},
|
|
947
|
+
}, _callee18);
|
|
910
948
|
})));
|
|
911
|
-
it('does not dispatch when the response has no data', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
949
|
+
it('does not dispatch when the response has no data', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee19() {
|
|
912
950
|
var mockFindLinksByIds, mockClient, provider, result;
|
|
913
|
-
return _regeneratorRuntime.wrap(function
|
|
914
|
-
while (1) switch (
|
|
951
|
+
return _regeneratorRuntime.wrap(function _callee19$(_context19) {
|
|
952
|
+
while (1) switch (_context19.prev = _context19.next) {
|
|
915
953
|
case 0:
|
|
916
954
|
mockFindLinksByIds = jest.fn().mockResolvedValue({
|
|
917
955
|
data: []
|
|
@@ -922,19 +960,19 @@ describe('fetchSharedDriveSharingLinks', function () {
|
|
|
922
960
|
});
|
|
923
961
|
provider = setupProvider(mockClient);
|
|
924
962
|
provider.dispatch = jest.fn();
|
|
925
|
-
|
|
963
|
+
_context19.next = 7;
|
|
926
964
|
return provider.fetchSharedDriveSharingLinks(driveFile);
|
|
927
965
|
|
|
928
966
|
case 7:
|
|
929
|
-
result =
|
|
967
|
+
result = _context19.sent;
|
|
930
968
|
expect(result).toEqual([]);
|
|
931
969
|
expect(provider.dispatch).not.toHaveBeenCalled();
|
|
932
970
|
|
|
933
971
|
case 10:
|
|
934
972
|
case "end":
|
|
935
|
-
return
|
|
973
|
+
return _context19.stop();
|
|
936
974
|
}
|
|
937
|
-
},
|
|
975
|
+
}, _callee19);
|
|
938
976
|
})));
|
|
939
977
|
});
|
|
940
978
|
describe('shareByLink shared drive 409 recovery', function () {
|
|
@@ -960,10 +998,10 @@ describe('shareByLink shared drive 409 recovery', function () {
|
|
|
960
998
|
id: 'file_in_drive',
|
|
961
999
|
driveId: 'drive_123'
|
|
962
1000
|
};
|
|
963
|
-
it('falls back to fetching existing links when create returns 409', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
1001
|
+
it('falls back to fetching existing links when create returns 409', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee20() {
|
|
964
1002
|
var conflict, mockCreateSharingLink, mockFindLinksByIds, mockClient, provider, resp;
|
|
965
|
-
return _regeneratorRuntime.wrap(function
|
|
966
|
-
while (1) switch (
|
|
1003
|
+
return _regeneratorRuntime.wrap(function _callee20$(_context20) {
|
|
1004
|
+
while (1) switch (_context20.prev = _context20.next) {
|
|
967
1005
|
case 0:
|
|
968
1006
|
conflict = Object.assign(new Error('Conflict'), {
|
|
969
1007
|
status: 409
|
|
@@ -978,27 +1016,27 @@ describe('shareByLink shared drive 409 recovery', function () {
|
|
|
978
1016
|
findLinksByIds: mockFindLinksByIds
|
|
979
1017
|
});
|
|
980
1018
|
provider = setupProvider(mockClient);
|
|
981
|
-
|
|
1019
|
+
_context20.next = 8;
|
|
982
1020
|
return provider.shareByLink(driveFile, {
|
|
983
1021
|
verbs: ['GET']
|
|
984
1022
|
});
|
|
985
1023
|
|
|
986
1024
|
case 8:
|
|
987
|
-
resp =
|
|
1025
|
+
resp = _context20.sent;
|
|
988
1026
|
expect(mockCreateSharingLink).toHaveBeenCalled();
|
|
989
1027
|
expect(mockFindLinksByIds).toHaveBeenCalledWith(['file_in_drive']);
|
|
990
1028
|
expect(resp.data.id).toBe(PERM_DRIVE_FILE.id);
|
|
991
1029
|
|
|
992
1030
|
case 12:
|
|
993
1031
|
case "end":
|
|
994
|
-
return
|
|
1032
|
+
return _context20.stop();
|
|
995
1033
|
}
|
|
996
|
-
},
|
|
1034
|
+
}, _callee20);
|
|
997
1035
|
})));
|
|
998
|
-
it('does not duplicate existing links when 409 recovery refetches them', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
1036
|
+
it('does not duplicate existing links when 409 recovery refetches them', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee21() {
|
|
999
1037
|
var conflict, mockCreateSharingLink, mockFindLinksByIds, mockClient, provider, resp, permissions;
|
|
1000
|
-
return _regeneratorRuntime.wrap(function
|
|
1001
|
-
while (1) switch (
|
|
1038
|
+
return _regeneratorRuntime.wrap(function _callee21$(_context21) {
|
|
1039
|
+
while (1) switch (_context21.prev = _context21.next) {
|
|
1002
1040
|
case 0:
|
|
1003
1041
|
conflict = Object.assign(new Error('Conflict'), {
|
|
1004
1042
|
status: 409
|
|
@@ -1013,13 +1051,13 @@ describe('shareByLink shared drive 409 recovery', function () {
|
|
|
1013
1051
|
findLinksByIds: mockFindLinksByIds
|
|
1014
1052
|
});
|
|
1015
1053
|
provider = setupProvider(mockClient, {}, reducer(undefined, addSharingLink(PERM_DRIVE_FILE)));
|
|
1016
|
-
|
|
1054
|
+
_context21.next = 8;
|
|
1017
1055
|
return provider.shareByLink(driveFile, {
|
|
1018
1056
|
verbs: ['GET']
|
|
1019
1057
|
});
|
|
1020
1058
|
|
|
1021
1059
|
case 8:
|
|
1022
|
-
resp =
|
|
1060
|
+
resp = _context21.sent;
|
|
1023
1061
|
permissions = getDocumentPermissions(provider.state, 'file_in_drive');
|
|
1024
1062
|
expect(resp.data.id).toBe(PERM_DRIVE_FILE.id);
|
|
1025
1063
|
expect(provider.dispatch).not.toHaveBeenCalled();
|
|
@@ -1027,14 +1065,14 @@ describe('shareByLink shared drive 409 recovery', function () {
|
|
|
1027
1065
|
|
|
1028
1066
|
case 13:
|
|
1029
1067
|
case "end":
|
|
1030
|
-
return
|
|
1068
|
+
return _context21.stop();
|
|
1031
1069
|
}
|
|
1032
|
-
},
|
|
1070
|
+
}, _callee21);
|
|
1033
1071
|
})));
|
|
1034
|
-
it('rethrows the original error when 409 happens and no link is found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
1072
|
+
it('rethrows the original error when 409 happens and no link is found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee22() {
|
|
1035
1073
|
var conflict, mockCreateSharingLink, mockFindLinksByIds, mockClient, provider;
|
|
1036
|
-
return _regeneratorRuntime.wrap(function
|
|
1037
|
-
while (1) switch (
|
|
1074
|
+
return _regeneratorRuntime.wrap(function _callee22$(_context22) {
|
|
1075
|
+
while (1) switch (_context22.prev = _context22.next) {
|
|
1038
1076
|
case 0:
|
|
1039
1077
|
conflict = Object.assign(new Error('Conflict'), {
|
|
1040
1078
|
status: 409
|
|
@@ -1050,16 +1088,16 @@ describe('shareByLink shared drive 409 recovery', function () {
|
|
|
1050
1088
|
});
|
|
1051
1089
|
provider = setupProvider(mockClient);
|
|
1052
1090
|
provider.dispatch = jest.fn();
|
|
1053
|
-
|
|
1091
|
+
_context22.next = 9;
|
|
1054
1092
|
return expect(provider.shareByLink(driveFile, {
|
|
1055
1093
|
verbs: ['GET']
|
|
1056
1094
|
})).rejects.toBe(conflict);
|
|
1057
1095
|
|
|
1058
1096
|
case 9:
|
|
1059
1097
|
case "end":
|
|
1060
|
-
return
|
|
1098
|
+
return _context22.stop();
|
|
1061
1099
|
}
|
|
1062
|
-
},
|
|
1100
|
+
}, _callee22);
|
|
1063
1101
|
})));
|
|
1064
1102
|
});
|
|
1065
1103
|
describe('updateSharingMemberType', function () {
|
|
@@ -1102,25 +1140,12 @@ describe('updateSharingMemberType', function () {
|
|
|
1102
1140
|
})
|
|
1103
1141
|
};
|
|
1104
1142
|
});
|
|
1105
|
-
it('should throw when sharing is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
1106
|
-
return _regeneratorRuntime.wrap(function _callee22$(_context22) {
|
|
1107
|
-
while (1) switch (_context22.prev = _context22.next) {
|
|
1108
|
-
case 0:
|
|
1109
|
-
_context22.next = 2;
|
|
1110
|
-
return expect(instance.updateSharingMemberType('unknown-id', 1, 'one-way')).rejects.toThrow('Sharing not found');
|
|
1111
|
-
|
|
1112
|
-
case 2:
|
|
1113
|
-
case "end":
|
|
1114
|
-
return _context22.stop();
|
|
1115
|
-
}
|
|
1116
|
-
}, _callee22);
|
|
1117
|
-
})));
|
|
1118
|
-
it('should throw when member is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee23() {
|
|
1143
|
+
it('should throw when sharing is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee23() {
|
|
1119
1144
|
return _regeneratorRuntime.wrap(function _callee23$(_context23) {
|
|
1120
1145
|
while (1) switch (_context23.prev = _context23.next) {
|
|
1121
1146
|
case 0:
|
|
1122
1147
|
_context23.next = 2;
|
|
1123
|
-
return expect(instance.updateSharingMemberType('
|
|
1148
|
+
return expect(instance.updateSharingMemberType('unknown-id', 1, 'one-way')).rejects.toThrow('Sharing not found');
|
|
1124
1149
|
|
|
1125
1150
|
case 2:
|
|
1126
1151
|
case "end":
|
|
@@ -1128,33 +1153,29 @@ describe('updateSharingMemberType', function () {
|
|
|
1128
1153
|
}
|
|
1129
1154
|
}, _callee23);
|
|
1130
1155
|
})));
|
|
1131
|
-
it('should
|
|
1156
|
+
it('should throw when member is not found', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee24() {
|
|
1132
1157
|
return _regeneratorRuntime.wrap(function _callee24$(_context24) {
|
|
1133
1158
|
while (1) switch (_context24.prev = _context24.next) {
|
|
1134
1159
|
case 0:
|
|
1135
1160
|
_context24.next = 2;
|
|
1136
|
-
return instance.updateSharingMemberType('sharing-123',
|
|
1161
|
+
return expect(instance.updateSharingMemberType('sharing-123', 99, 'one-way')).rejects.toThrow('Member not found');
|
|
1137
1162
|
|
|
1138
1163
|
case 2:
|
|
1139
|
-
expect(instance.sharingCol.setReadOnly).toHaveBeenCalledWith(mockSharing, 1);
|
|
1140
|
-
expect(instance.sharingCol.setReadWrite).not.toHaveBeenCalled();
|
|
1141
|
-
|
|
1142
|
-
case 4:
|
|
1143
1164
|
case "end":
|
|
1144
1165
|
return _context24.stop();
|
|
1145
1166
|
}
|
|
1146
1167
|
}, _callee24);
|
|
1147
1168
|
})));
|
|
1148
|
-
it('should call
|
|
1169
|
+
it('should call setReadOnly when switching to one-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee25() {
|
|
1149
1170
|
return _regeneratorRuntime.wrap(function _callee25$(_context25) {
|
|
1150
1171
|
while (1) switch (_context25.prev = _context25.next) {
|
|
1151
1172
|
case 0:
|
|
1152
1173
|
_context25.next = 2;
|
|
1153
|
-
return instance.updateSharingMemberType('sharing-123', 1, '
|
|
1174
|
+
return instance.updateSharingMemberType('sharing-123', 1, 'one-way');
|
|
1154
1175
|
|
|
1155
1176
|
case 2:
|
|
1156
|
-
expect(instance.sharingCol.
|
|
1157
|
-
expect(instance.sharingCol.
|
|
1177
|
+
expect(instance.sharingCol.setReadOnly).toHaveBeenCalledWith(mockSharing, 1);
|
|
1178
|
+
expect(instance.sharingCol.setReadWrite).not.toHaveBeenCalled();
|
|
1158
1179
|
|
|
1159
1180
|
case 4:
|
|
1160
1181
|
case "end":
|
|
@@ -1162,37 +1183,29 @@ describe('updateSharingMemberType', function () {
|
|
|
1162
1183
|
}
|
|
1163
1184
|
}, _callee25);
|
|
1164
1185
|
})));
|
|
1165
|
-
it('should
|
|
1186
|
+
it('should call setReadWrite when switching to two-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee26() {
|
|
1166
1187
|
return _regeneratorRuntime.wrap(function _callee26$(_context26) {
|
|
1167
1188
|
while (1) switch (_context26.prev = _context26.next) {
|
|
1168
1189
|
case 0:
|
|
1169
1190
|
_context26.next = 2;
|
|
1170
|
-
return instance.updateSharingMemberType('sharing-123', 1, '
|
|
1191
|
+
return instance.updateSharingMemberType('sharing-123', 1, 'two-way');
|
|
1171
1192
|
|
|
1172
1193
|
case 2:
|
|
1173
|
-
expect(instance.
|
|
1174
|
-
|
|
1175
|
-
sharing: _objectSpread(_objectSpread({}, mockSharing), {}, {
|
|
1176
|
-
attributes: _objectSpread(_objectSpread({}, mockSharing.attributes), {}, {
|
|
1177
|
-
members: [mockSharing.attributes.members[0], _objectSpread(_objectSpread({}, mockSharing.attributes.members[1]), {}, {
|
|
1178
|
-
read_only: true
|
|
1179
|
-
})]
|
|
1180
|
-
})
|
|
1181
|
-
})
|
|
1182
|
-
});
|
|
1194
|
+
expect(instance.sharingCol.setReadWrite).toHaveBeenCalledWith(mockSharing, 1);
|
|
1195
|
+
expect(instance.sharingCol.setReadOnly).not.toHaveBeenCalled();
|
|
1183
1196
|
|
|
1184
|
-
case
|
|
1197
|
+
case 4:
|
|
1185
1198
|
case "end":
|
|
1186
1199
|
return _context26.stop();
|
|
1187
1200
|
}
|
|
1188
1201
|
}, _callee26);
|
|
1189
1202
|
})));
|
|
1190
|
-
it('should optimistically dispatch a state update when switching to
|
|
1203
|
+
it('should optimistically dispatch a state update when switching to one-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee27() {
|
|
1191
1204
|
return _regeneratorRuntime.wrap(function _callee27$(_context27) {
|
|
1192
1205
|
while (1) switch (_context27.prev = _context27.next) {
|
|
1193
1206
|
case 0:
|
|
1194
1207
|
_context27.next = 2;
|
|
1195
|
-
return instance.updateSharingMemberType('sharing-123', 1, '
|
|
1208
|
+
return instance.updateSharingMemberType('sharing-123', 1, 'one-way');
|
|
1196
1209
|
|
|
1197
1210
|
case 2:
|
|
1198
1211
|
expect(instance.dispatch).toHaveBeenCalledWith({
|
|
@@ -1200,7 +1213,7 @@ describe('updateSharingMemberType', function () {
|
|
|
1200
1213
|
sharing: _objectSpread(_objectSpread({}, mockSharing), {}, {
|
|
1201
1214
|
attributes: _objectSpread(_objectSpread({}, mockSharing.attributes), {}, {
|
|
1202
1215
|
members: [mockSharing.attributes.members[0], _objectSpread(_objectSpread({}, mockSharing.attributes.members[1]), {}, {
|
|
1203
|
-
read_only:
|
|
1216
|
+
read_only: true
|
|
1204
1217
|
})]
|
|
1205
1218
|
})
|
|
1206
1219
|
})
|
|
@@ -1212,13 +1225,24 @@ describe('updateSharingMemberType', function () {
|
|
|
1212
1225
|
}
|
|
1213
1226
|
}, _callee27);
|
|
1214
1227
|
})));
|
|
1215
|
-
it('should
|
|
1228
|
+
it('should optimistically dispatch a state update when switching to two-way', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee28() {
|
|
1216
1229
|
return _regeneratorRuntime.wrap(function _callee28$(_context28) {
|
|
1217
1230
|
while (1) switch (_context28.prev = _context28.next) {
|
|
1218
1231
|
case 0:
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1232
|
+
_context28.next = 2;
|
|
1233
|
+
return instance.updateSharingMemberType('sharing-123', 1, 'two-way');
|
|
1234
|
+
|
|
1235
|
+
case 2:
|
|
1236
|
+
expect(instance.dispatch).toHaveBeenCalledWith({
|
|
1237
|
+
type: 'UPDATE_SHARING',
|
|
1238
|
+
sharing: _objectSpread(_objectSpread({}, mockSharing), {}, {
|
|
1239
|
+
attributes: _objectSpread(_objectSpread({}, mockSharing.attributes), {}, {
|
|
1240
|
+
members: [mockSharing.attributes.members[0], _objectSpread(_objectSpread({}, mockSharing.attributes.members[1]), {}, {
|
|
1241
|
+
read_only: false
|
|
1242
|
+
})]
|
|
1243
|
+
})
|
|
1244
|
+
})
|
|
1245
|
+
});
|
|
1222
1246
|
|
|
1223
1247
|
case 3:
|
|
1224
1248
|
case "end":
|
|
@@ -1226,13 +1250,13 @@ describe('updateSharingMemberType', function () {
|
|
|
1226
1250
|
}
|
|
1227
1251
|
}, _callee28);
|
|
1228
1252
|
})));
|
|
1229
|
-
it('should rethrow error if
|
|
1253
|
+
it('should rethrow error if setReadOnly fails', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee29() {
|
|
1230
1254
|
return _regeneratorRuntime.wrap(function _callee29$(_context29) {
|
|
1231
1255
|
while (1) switch (_context29.prev = _context29.next) {
|
|
1232
1256
|
case 0:
|
|
1233
|
-
instance.sharingCol.
|
|
1257
|
+
instance.sharingCol.setReadOnly.mockRejectedValue(new Error('Network error'));
|
|
1234
1258
|
_context29.next = 3;
|
|
1235
|
-
return expect(instance.updateSharingMemberType('sharing-123', 1, '
|
|
1259
|
+
return expect(instance.updateSharingMemberType('sharing-123', 1, 'one-way')).rejects.toThrow('Network error');
|
|
1236
1260
|
|
|
1237
1261
|
case 3:
|
|
1238
1262
|
case "end":
|
|
@@ -1240,12 +1264,26 @@ describe('updateSharingMemberType', function () {
|
|
|
1240
1264
|
}
|
|
1241
1265
|
}, _callee29);
|
|
1242
1266
|
})));
|
|
1243
|
-
it('should
|
|
1267
|
+
it('should rethrow error if setReadWrite fails', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee30() {
|
|
1244
1268
|
return _regeneratorRuntime.wrap(function _callee30$(_context30) {
|
|
1245
1269
|
while (1) switch (_context30.prev = _context30.next) {
|
|
1246
1270
|
case 0:
|
|
1247
|
-
instance.sharingCol.
|
|
1271
|
+
instance.sharingCol.setReadWrite.mockRejectedValue(new Error('Network error'));
|
|
1248
1272
|
_context30.next = 3;
|
|
1273
|
+
return expect(instance.updateSharingMemberType('sharing-123', 1, 'two-way')).rejects.toThrow('Network error');
|
|
1274
|
+
|
|
1275
|
+
case 3:
|
|
1276
|
+
case "end":
|
|
1277
|
+
return _context30.stop();
|
|
1278
|
+
}
|
|
1279
|
+
}, _callee30);
|
|
1280
|
+
})));
|
|
1281
|
+
it('should rollback optimistic state update if API call fails', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee31() {
|
|
1282
|
+
return _regeneratorRuntime.wrap(function _callee31$(_context31) {
|
|
1283
|
+
while (1) switch (_context31.prev = _context31.next) {
|
|
1284
|
+
case 0:
|
|
1285
|
+
instance.sharingCol.setReadOnly.mockRejectedValue(new Error('Network error'));
|
|
1286
|
+
_context31.next = 3;
|
|
1249
1287
|
return expect(instance.updateSharingMemberType('sharing-123', 1, 'one-way')).rejects.toThrow('Network error');
|
|
1250
1288
|
|
|
1251
1289
|
case 3:
|
|
@@ -1284,14 +1322,14 @@ describe('updateSharingMemberType', function () {
|
|
|
1284
1322
|
|
|
1285
1323
|
case 7:
|
|
1286
1324
|
case "end":
|
|
1287
|
-
return
|
|
1325
|
+
return _context31.stop();
|
|
1288
1326
|
}
|
|
1289
|
-
},
|
|
1327
|
+
}, _callee31);
|
|
1290
1328
|
})));
|
|
1291
|
-
it('should preserve realtime changes when rolling back an API failure', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
1329
|
+
it('should preserve realtime changes when rolling back an API failure', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee33() {
|
|
1292
1330
|
var realtimeSharing;
|
|
1293
|
-
return _regeneratorRuntime.wrap(function
|
|
1294
|
-
while (1) switch (
|
|
1331
|
+
return _regeneratorRuntime.wrap(function _callee33$(_context33) {
|
|
1332
|
+
while (1) switch (_context33.prev = _context33.next) {
|
|
1295
1333
|
case 0:
|
|
1296
1334
|
realtimeSharing = _objectSpread(_objectSpread({}, mockSharing), {}, {
|
|
1297
1335
|
attributes: _objectSpread(_objectSpread({}, mockSharing.attributes), {}, {
|
|
@@ -1303,9 +1341,9 @@ describe('updateSharingMemberType', function () {
|
|
|
1303
1341
|
})]
|
|
1304
1342
|
})
|
|
1305
1343
|
});
|
|
1306
|
-
instance.sharingCol.setReadOnly.mockImplementation( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
1307
|
-
return _regeneratorRuntime.wrap(function
|
|
1308
|
-
while (1) switch (
|
|
1344
|
+
instance.sharingCol.setReadOnly.mockImplementation( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee32() {
|
|
1345
|
+
return _regeneratorRuntime.wrap(function _callee32$(_context32) {
|
|
1346
|
+
while (1) switch (_context32.prev = _context32.next) {
|
|
1309
1347
|
case 0:
|
|
1310
1348
|
instance.state = _objectSpread(_objectSpread({}, instance.state), {}, {
|
|
1311
1349
|
sharings: instance.state.sharings.map(function (sharing) {
|
|
@@ -1316,11 +1354,11 @@ describe('updateSharingMemberType', function () {
|
|
|
1316
1354
|
|
|
1317
1355
|
case 2:
|
|
1318
1356
|
case "end":
|
|
1319
|
-
return
|
|
1357
|
+
return _context32.stop();
|
|
1320
1358
|
}
|
|
1321
|
-
},
|
|
1359
|
+
}, _callee32);
|
|
1322
1360
|
})));
|
|
1323
|
-
|
|
1361
|
+
_context33.next = 4;
|
|
1324
1362
|
return expect(instance.updateSharingMemberType('sharing-123', 1, 'one-way')).rejects.toThrow('Network error');
|
|
1325
1363
|
|
|
1326
1364
|
case 4:
|
|
@@ -1349,9 +1387,9 @@ describe('updateSharingMemberType', function () {
|
|
|
1349
1387
|
|
|
1350
1388
|
case 7:
|
|
1351
1389
|
case "end":
|
|
1352
|
-
return
|
|
1390
|
+
return _context33.stop();
|
|
1353
1391
|
}
|
|
1354
|
-
},
|
|
1392
|
+
}, _callee33);
|
|
1355
1393
|
})));
|
|
1356
1394
|
}); // TODO Convert with react-testing-library
|
|
1357
1395
|
// describe('hasWriteAccess', () => {
|
|
@@ -64,6 +64,7 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
64
64
|
|
|
65
65
|
var _useSharingContext = useSharingContext(),
|
|
66
66
|
canReshare = _useSharingContext.canReshare,
|
|
67
|
+
hasWriteAccess = _useSharingContext.hasWriteAccess,
|
|
67
68
|
share = _useSharingContext.share,
|
|
68
69
|
getSharingById = _useSharingContext.getSharingById,
|
|
69
70
|
getSharingLink = _useSharingContext.getSharingLink,
|
|
@@ -125,7 +126,7 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
125
126
|
}));
|
|
126
127
|
var isInsideSharedDrive = Boolean((existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.driveId) && !isSharedDriveRoot);
|
|
127
128
|
var isCurrentUserOwner = existingDocument !== null && existingDocument !== void 0 && existingDocument.driveId ? Boolean(sharedDriveSharing === null || sharedDriveSharing === void 0 || (_sharedDriveSharing$a2 = sharedDriveSharing.attributes) === null || _sharedDriveSharing$a2 === void 0 ? void 0 : _sharedDriveSharing$a2.owner) : documentId ? isOwner(documentId) : false;
|
|
128
|
-
var isMemberReadOnly = isInsideSharedDrive && !isCurrentUserOwner;
|
|
129
|
+
var isMemberReadOnly = isInsideSharedDrive && !isCurrentUserOwner && !hasWriteAccess(documentId, existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.driveId);
|
|
129
130
|
var canManageSharing = isCurrentUserOwner || (documentId ? canReshare(documentId) : false);
|
|
130
131
|
|
|
131
132
|
var handleRevokeSelf = /*#__PURE__*/function () {
|
|
@@ -318,7 +319,7 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
318
319
|
className: "u-ph-2"
|
|
319
320
|
}, /*#__PURE__*/React.createElement(AntivirusAlert, {
|
|
320
321
|
document: isSending ? frozenDoc : existingDocument
|
|
321
|
-
}),
|
|
322
|
+
}), isMemberReadOnly ? /*#__PURE__*/React.createElement("div", {
|
|
322
323
|
className: styles['share-byemail-onlybylink']
|
|
323
324
|
}, t('Files.share.shareByEmail.onlyByLink', {
|
|
324
325
|
type: t("Files.share.shareByEmail.type.".concat((existingDocument === null || existingDocument === void 0 ? void 0 : existingDocument.type) === 'file' ? 'file' : 'folder'))
|
|
@@ -354,7 +355,7 @@ var FederatedFolderModalContent = function FederatedFolderModalContent(_ref) {
|
|
|
354
355
|
documentType: "Files",
|
|
355
356
|
showGenerateLinkButton: showGenerateLinkButton,
|
|
356
357
|
autoOpenShareRestriction: autoOpenShareRestriction
|
|
357
|
-
}), !
|
|
358
|
+
}), !isMemberReadOnly && /*#__PURE__*/React.createElement(Button, {
|
|
358
359
|
variant: "primary",
|
|
359
360
|
label: t('FederatedFolder.share'),
|
|
360
361
|
busy: isSending,
|