Skip to content

Commit 2f7185d

Browse files
feat(content-sharing): Define sharing service for shared link and access (#4340)
* feat(content-sharing): Define sharing service for shared link and access * feat(content-sharing): Define sharing service for shared link and access * fix: nits * fix: nits --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent e0a67e0 commit 2f7185d

File tree

4 files changed

+207
-60
lines changed

4 files changed

+207
-60
lines changed

src/elements/content-sharing/__tests__/sharingService.test.ts

Lines changed: 89 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { PERMISSION_CAN_DOWNLOAD, PERMISSION_CAN_PREVIEW } from '../../../constants';
1+
import { ACCESS_NONE, PERMISSION_CAN_DOWNLOAD, PERMISSION_CAN_PREVIEW } from '../../../constants';
22
import { CONTENT_SHARING_SHARED_LINK_UPDATE_PARAMS } from '../constants';
33
import { createSharingService } from '../sharingService';
44
import { convertSharedLinkPermissions, convertSharedLinkSettings } from '../utils';
@@ -7,9 +7,20 @@ jest.mock('../utils');
77

88
const mockItemApiInstance = {
99
updateSharedLink: jest.fn(),
10+
share: jest.fn(),
1011
};
1112
const options = { id: '123', permissions: { can_set_share_access: true, can_share: true } };
12-
const mockOnSuccess = jest.fn();
13+
const mockOnUpdateSharedLink = jest.fn();
14+
const mockOnRemoveSharedLink = jest.fn();
15+
16+
const createSharingServiceWrapper = () => {
17+
return createSharingService({
18+
itemApiInstance: mockItemApiInstance,
19+
onUpdateSharedLink: mockOnUpdateSharedLink,
20+
onRemoveSharedLink: mockOnRemoveSharedLink,
21+
options,
22+
});
23+
};
1324

1425
describe('elements/content-sharing/sharingService', () => {
1526
beforeEach(() => {
@@ -29,23 +40,13 @@ describe('elements/content-sharing/sharingService', () => {
2940

3041
describe('changeSharedLinkPermission', () => {
3142
test('should return an object with changeSharedLinkPermission method', () => {
32-
const service = createSharingService({
33-
itemApiInstance: mockItemApiInstance,
34-
onSuccess: mockOnSuccess,
35-
options,
36-
});
37-
43+
const service = createSharingServiceWrapper();
3844
expect(service).toHaveProperty('changeSharedLinkPermission');
3945
expect(typeof service.changeSharedLinkPermission).toBe('function');
4046
});
4147

4248
test('should call updateSharedLink with correct parameters when changeSharedLinkPermission is called', async () => {
43-
const service = createSharingService({
44-
itemApiInstance: mockItemApiInstance,
45-
onSuccess: mockOnSuccess,
46-
options,
47-
});
48-
49+
const service = createSharingServiceWrapper();
4950
const permissionLevel = PERMISSION_CAN_DOWNLOAD;
5051
const expectedPermissions = {
5152
[PERMISSION_CAN_DOWNLOAD]: true,
@@ -57,7 +58,73 @@ describe('elements/content-sharing/sharingService', () => {
5758
expect(mockItemApiInstance.updateSharedLink).toHaveBeenCalledWith(
5859
options,
5960
{ permissions: expectedPermissions },
60-
mockOnSuccess,
61+
mockOnUpdateSharedLink,
62+
{},
63+
CONTENT_SHARING_SHARED_LINK_UPDATE_PARAMS,
64+
);
65+
});
66+
});
67+
68+
describe('changeSharedLinkAccess', () => {
69+
test('should return an object with changeSharedLinkAccess method', () => {
70+
const service = createSharingServiceWrapper();
71+
expect(service).toHaveProperty('changeSharedLinkAccess');
72+
expect(typeof service.changeSharedLinkAccess).toBe('function');
73+
});
74+
75+
test.each(['open', 'company', 'collaborators'])(
76+
'should call share with correct parameters when changeSharedLinkAccess is called',
77+
async access => {
78+
const service = createSharingServiceWrapper();
79+
await service.changeSharedLinkAccess(access);
80+
81+
expect(mockItemApiInstance.share).toHaveBeenCalledWith(
82+
options,
83+
access,
84+
mockOnUpdateSharedLink,
85+
{},
86+
CONTENT_SHARING_SHARED_LINK_UPDATE_PARAMS,
87+
);
88+
},
89+
);
90+
});
91+
92+
describe('createSharedLink', () => {
93+
test('should return an object with createSharedLink method', () => {
94+
const service = createSharingServiceWrapper();
95+
expect(service).toHaveProperty('createSharedLink');
96+
expect(typeof service.createSharedLink).toBe('function');
97+
});
98+
99+
test('should call share with correct parameters when createSharedLink is called', async () => {
100+
const service = createSharingServiceWrapper();
101+
await service.createSharedLink();
102+
103+
expect(mockItemApiInstance.share).toHaveBeenCalledWith(
104+
options,
105+
undefined,
106+
mockOnUpdateSharedLink,
107+
{},
108+
CONTENT_SHARING_SHARED_LINK_UPDATE_PARAMS,
109+
);
110+
});
111+
});
112+
113+
describe('deleteSharedLink', () => {
114+
test('should return an object with deleteSharedLink method', () => {
115+
const service = createSharingServiceWrapper();
116+
expect(service).toHaveProperty('deleteSharedLink');
117+
expect(typeof service.deleteSharedLink).toBe('function');
118+
});
119+
120+
test('should call share with ACCESS_NONE and onRemoveSharedLink when deleteSharedLink is called', async () => {
121+
const service = createSharingServiceWrapper();
122+
await service.deleteSharedLink();
123+
124+
expect(mockItemApiInstance.share).toHaveBeenCalledWith(
125+
options,
126+
ACCESS_NONE,
127+
mockOnRemoveSharedLink,
61128
{},
62129
CONTENT_SHARING_SHARED_LINK_UPDATE_PARAMS,
63130
);
@@ -66,22 +133,14 @@ describe('elements/content-sharing/sharingService', () => {
66133

67134
describe('updateSharedLink', () => {
68135
test('should return an object with updateSharedLink method', () => {
69-
const service = createSharingService({
70-
itemApiInstance: mockItemApiInstance,
71-
onSuccess: mockOnSuccess,
72-
options,
73-
});
136+
const service = createSharingServiceWrapper();
74137

75138
expect(service).toHaveProperty('updateSharedLink');
76139
expect(typeof service.updateSharedLink).toBe('function');
77140
});
78141

79142
test('should call updateSharedLink with basic shared link settings', async () => {
80-
const service = createSharingService({
81-
itemApiInstance: mockItemApiInstance,
82-
onSuccess: mockOnSuccess,
83-
options,
84-
});
143+
const service = createSharingServiceWrapper();
85144

86145
const sharedLinkSettings = {
87146
expiration: null,
@@ -108,7 +167,7 @@ describe('elements/content-sharing/sharingService', () => {
108167
expect(mockItemApiInstance.updateSharedLink).toHaveBeenCalledWith(
109168
options,
110169
expectedConvertedSettings,
111-
mockOnSuccess,
170+
mockOnUpdateSharedLink,
112171
{},
113172
CONTENT_SHARING_SHARED_LINK_UPDATE_PARAMS,
114173
);
@@ -126,7 +185,8 @@ describe('elements/content-sharing/sharingService', () => {
126185

127186
const service = createSharingService({
128187
itemApiInstance: mockItemApiInstance,
129-
onSuccess: mockOnSuccess,
188+
onUpdateSharedLink: mockOnUpdateSharedLink,
189+
onRemoveSharedLink: mockOnRemoveSharedLink,
130190
options: {
131191
...options,
132192
access: 'open',
@@ -155,18 +215,14 @@ describe('elements/content-sharing/sharingService', () => {
155215
expect(mockItemApiInstance.updateSharedLink).toHaveBeenCalledWith(
156216
options,
157217
mockConvertedSharedLinkSettings,
158-
mockOnSuccess,
218+
mockOnUpdateSharedLink,
159219
{},
160220
CONTENT_SHARING_SHARED_LINK_UPDATE_PARAMS,
161221
);
162222
});
163223

164224
test('should handle shared link settings correctly', async () => {
165-
const service = createSharingService({
166-
itemApiInstance: mockItemApiInstance,
167-
onSuccess: mockOnSuccess,
168-
options,
169-
});
225+
const service = createSharingServiceWrapper();
170226

171227
const expirationDate = new Date('2024-12-31T23:59:59Z');
172228
const sharedLinkSettings = {

src/elements/content-sharing/hooks/__tests__/useSharingService.test.ts

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ const mockApi = {
1212
getFileAPI: jest.fn(),
1313
getFolderAPI: jest.fn(),
1414
};
15-
const mockItemApiInstance = {
16-
updateSharedLink: jest.fn(),
17-
};
1815
const mockSharingService = {
16+
createSharedLink: jest.fn(),
17+
changeSharedLinkAccess: jest.fn(),
1918
changeSharedLinkPermission: jest.fn(),
19+
deleteSharedLink: jest.fn(),
20+
updateSharedLink: jest.fn(),
2021
};
2122

2223
const mockItemId = '123';
@@ -43,6 +44,11 @@ const mockSharingServiceProps = {
4344
can_share: true,
4445
};
4546

47+
const mockConvertedData = {
48+
item: mockItem,
49+
sharedLink: mockSharedLink,
50+
};
51+
4652
const mockSetItem = jest.fn();
4753
const mockSetSharedLink = jest.fn();
4854

@@ -104,7 +110,7 @@ describe('elements/content-sharing/hooks/useSharingService', () => {
104110

105111
describe('when itemType is TYPE_FILE', () => {
106112
beforeEach(() => {
107-
mockApi.getFileAPI.mockReturnValue(mockItemApiInstance);
113+
mockApi.getFileAPI.mockReturnValue({});
108114
});
109115

110116
test('should create file API instance and sharing service', () => {
@@ -114,8 +120,9 @@ describe('elements/content-sharing/hooks/useSharingService', () => {
114120
expect(mockApi.getFolderAPI).not.toHaveBeenCalled();
115121
expect(result.current.sharingService).toBe(mockSharingService);
116122
expect(createSharingService).toHaveBeenCalledWith({
117-
itemApiInstance: mockItemApiInstance,
118-
onSuccess: expect.any(Function),
123+
itemApiInstance: {},
124+
onUpdateSharedLink: expect.any(Function),
125+
onRemoveSharedLink: expect.any(Function),
119126
options: {
120127
access: mockSharedLink.access,
121128
isDownloadAvailable: mockSharedLink.settings.isDownloadAvailable,
@@ -126,30 +133,36 @@ describe('elements/content-sharing/hooks/useSharingService', () => {
126133
});
127134
});
128135

129-
test('should handle success callback correctly', () => {
130-
const mockConvertedData = {
131-
item: {
132-
id: mockItemId,
133-
permissions: { can_download: false, can_preview: true },
134-
},
135-
sharedLink: {},
136-
};
136+
test('should handle update shared link success callback correctly', () => {
137+
(convertItemResponse as jest.Mock).mockReturnValue(mockConvertedData);
138+
renderHookWithProps();
139+
140+
// Get the callbacks that were passed to mock createSharingService
141+
const createSharingServiceArgs = (createSharingService as jest.Mock).mock.calls[0][0];
142+
createSharingServiceArgs.onUpdateSharedLink(mockConvertedData);
143+
144+
expect(convertItemResponse).toHaveBeenCalledWith(mockConvertedData);
145+
expect(mockSetItem).toHaveBeenCalledTimes(1);
146+
expect(mockSetSharedLink).toHaveBeenCalledTimes(1);
147+
});
137148

149+
test('should handle remove shared link success callback correctly', () => {
138150
(convertItemResponse as jest.Mock).mockReturnValue(mockConvertedData);
139151
renderHookWithProps();
140152

141-
// Get the onSuccess callback that was passed to mock createSharingService
142-
const onSuccessCallback = (createSharingService as jest.Mock).mock.calls[0][0].onSuccess;
143-
onSuccessCallback(mockConvertedData);
153+
// Get the callbacks that were passed to mock createSharingService
154+
const createSharingServiceArgs = (createSharingService as jest.Mock).mock.calls[0][0];
155+
createSharingServiceArgs.onRemoveSharedLink(mockConvertedData);
144156

157+
expect(convertItemResponse).toHaveBeenCalledWith(mockConvertedData);
145158
expect(mockSetItem).toHaveBeenCalledTimes(1);
146159
expect(mockSetSharedLink).toHaveBeenCalledTimes(1);
147160
});
148161
});
149162

150163
describe('when itemType is TYPE_FOLDER', () => {
151164
beforeEach(() => {
152-
mockApi.getFolderAPI.mockReturnValue(mockItemApiInstance);
165+
mockApi.getFolderAPI.mockReturnValue({});
153166
});
154167

155168
test('should create folder API instance and sharing service', () => {
@@ -159,8 +172,9 @@ describe('elements/content-sharing/hooks/useSharingService', () => {
159172
expect(mockApi.getFileAPI).not.toHaveBeenCalled();
160173
expect(result.current.sharingService).toBe(mockSharingService);
161174
expect(createSharingService).toHaveBeenCalledWith({
162-
itemApiInstance: mockItemApiInstance,
163-
onSuccess: expect.any(Function),
175+
itemApiInstance: {},
176+
onUpdateSharedLink: expect.any(Function),
177+
onRemoveSharedLink: expect.any(Function),
164178
options: {
165179
access: mockSharedLink.access,
166180
isDownloadAvailable: mockSharedLink.settings.isDownloadAvailable,
@@ -170,5 +184,31 @@ describe('elements/content-sharing/hooks/useSharingService', () => {
170184
},
171185
});
172186
});
187+
188+
test('should handle update shared link success callback correctly for folders', () => {
189+
(convertItemResponse as jest.Mock).mockReturnValue(mockConvertedData);
190+
renderHookWithProps({ itemType: TYPE_FOLDER });
191+
192+
// Get the callbacks that were passed to mock createSharingService
193+
const createSharingServiceArgs = (createSharingService as jest.Mock).mock.calls[0][0];
194+
createSharingServiceArgs.onUpdateSharedLink(mockConvertedData);
195+
196+
expect(convertItemResponse).toHaveBeenCalledWith(mockConvertedData);
197+
expect(mockSetItem).toHaveBeenCalledTimes(1);
198+
expect(mockSetSharedLink).toHaveBeenCalledTimes(1);
199+
});
200+
201+
test('should handle remove shared link success callback correctly for folders', () => {
202+
(convertItemResponse as jest.Mock).mockReturnValue(mockConvertedData);
203+
renderHookWithProps({ itemType: TYPE_FOLDER });
204+
205+
// Get the callbacks that were passed to mock createSharingService
206+
const createSharingServiceArgs = (createSharingService as jest.Mock).mock.calls[0][0];
207+
createSharingServiceArgs.onRemoveSharedLink(mockConvertedData);
208+
209+
expect(convertItemResponse).toHaveBeenCalledWith(mockConvertedData);
210+
expect(mockSetItem).toHaveBeenCalledTimes(1);
211+
expect(mockSetSharedLink).toHaveBeenCalledTimes(1);
212+
});
173213
});
174214
});

src/elements/content-sharing/hooks/useSharingService.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,24 @@ export const useSharingService = ({
4343
isDownloadAvailable: sharedLink.settings?.isDownloadAvailable ?? false,
4444
};
4545

46-
const handleSuccess = updatedItemData => {
46+
const handleUpdateSharedLink = updatedItemData => {
4747
const { item: updatedItem, sharedLink: updatedSharedLink } = convertItemResponse(updatedItemData);
4848
setItem(prevItem => ({ ...prevItem, ...updatedItem }));
4949
setSharedLink(prevSharedLink => ({ ...prevSharedLink, ...updatedSharedLink }));
5050
};
5151

52-
return createSharingService({ itemApiInstance, onSuccess: handleSuccess, options });
52+
const handleRemoveSharedLink = itemData => {
53+
const { item: updatedItem } = convertItemResponse(itemData);
54+
setItem(prevItem => ({ ...prevItem, ...updatedItem }));
55+
setSharedLink({});
56+
};
57+
58+
return createSharingService({
59+
itemApiInstance,
60+
onUpdateSharedLink: handleUpdateSharedLink,
61+
onRemoveSharedLink: handleRemoveSharedLink,
62+
options,
63+
});
5364
}, [itemApiInstance, itemId, sharedLink, sharingServiceProps, setItem, setSharedLink]);
5465

5566
return { sharingService };

0 commit comments

Comments
 (0)