Skip to content

Commit 8b0db1d

Browse files
committed
Use record and folder endpoints to populate the existing share link
In order to get the share-link for an item, a call to either record or folder will be made using the id. ISSUE: PER-10397
1 parent 53b9905 commit 8b0db1d

2 files changed

Lines changed: 217 additions & 5 deletions

File tree

src/app/core/services/edit/edit.service.spec.ts

Lines changed: 197 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@ import { cloneDeep } from 'lodash';
44
import { EditService } from '@core/services/edit/edit.service';
55
import { ApiService } from '@shared/services/api/api.service';
66
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
7-
import { ArchiveVO, RecordVO } from '@models/index';
7+
import { ArchiveVO, FolderVO, RecordVO } from '@models/index';
88
import { AccountService } from '@shared/services/account/account.service';
99
import { RecordRepo } from '@shared/services/api/record.repo';
10+
import { FolderRepo } from '@shared/services/api/folder.repo';
1011
import { MessageService } from '@shared/services/message/message.service';
1112
import { DataService } from '@shared/services/data/data.service';
1213
import { ShareLinksApiService } from '@root/app/share-links/services/share-links-api.service';
14+
import { ShareLink } from '@root/app/share-links/models/share-link';
15+
import { DeviceService } from '@shared/services/device/device.service';
16+
import { DialogCdkService } from '@root/app/dialog-cdk/dialog-cdk.service';
17+
import { SharingComponent } from '@fileBrowser/components/sharing/sharing.component';
18+
import { SharingDialogComponent } from '@fileBrowser/components/sharing-dialog/sharing-dialog.component';
1319
import { FolderPickerService } from '../folder-picker/folder-picker.service';
1420

1521
const mockDataService = {
@@ -24,11 +30,25 @@ describe('EditService', () => {
2430
let apiService: jasmine.SpyObj<ApiService>;
2531
let accountService: jasmine.SpyObj<AccountService>;
2632
let shareLinksApiService: jasmine.SpyObj<ShareLinksApiService>;
33+
let deviceService: jasmine.SpyObj<DeviceService>;
34+
let dialogService: jasmine.SpyObj<DialogCdkService>;
35+
2736
beforeEach(() => {
28-
apiService = jasmine.createSpyObj('ApiService', ['record']);
37+
apiService = jasmine.createSpyObj('ApiService', [
38+
'record',
39+
'folder',
40+
'share',
41+
]);
2942
apiService.record = {
3043
update: jasmine.createSpy('update'),
44+
getRecordShareLink: jasmine.createSpy('getRecordShareLink'),
3145
} as unknown as RecordRepo;
46+
apiService.folder = {
47+
getFolderShareLink: jasmine.createSpy('getFolderShareLink'),
48+
} as unknown as FolderRepo;
49+
apiService.share = {
50+
getShareLink: jasmine.createSpy('getShareLink'),
51+
} as any;
3252

3353
accountService = jasmine.createSpyObj('AccountService', ['getArchive']);
3454
accountService.getArchive.and.returnValue(
@@ -42,6 +62,9 @@ describe('EditService', () => {
4262
'deleteShareLink',
4363
]);
4464

65+
deviceService = jasmine.createSpyObj('DeviceService', ['isMobile']);
66+
dialogService = jasmine.createSpyObj('DialogCdkService', ['open']);
67+
4568
const config = cloneDeep(Testing.BASE_TEST_CONFIG);
4669
config.imports.push(NgbTooltipModule);
4770
TestBed.configureTestingModule({
@@ -53,6 +76,8 @@ describe('EditService', () => {
5376
{ provide: ApiService, useValue: apiService },
5477
{ provide: AccountService, useValue: accountService },
5578
{ provide: ShareLinksApiService, useValue: shareLinksApiService },
79+
{ provide: DeviceService, useValue: deviceService },
80+
{ provide: DialogCdkService, useValue: dialogService },
5681
],
5782
});
5883

@@ -94,4 +119,174 @@ describe('EditService', () => {
94119
expect(apiService.record.update).toHaveBeenCalled();
95120
expect(recordMock.update).not.toHaveBeenCalled();
96121
});
122+
123+
describe('openShareDialog', () => {
124+
const mockShareLink: ShareLink = {
125+
id: 'link1',
126+
itemId: '123',
127+
itemType: 'record',
128+
token: 'abc',
129+
permissionsLevel: 'viewer',
130+
accessRestrictions: 'none',
131+
maxUses: null,
132+
usesExpended: null,
133+
createdAt: new Date('2024-01-01'),
134+
updatedAt: new Date('2024-01-01'),
135+
};
136+
137+
describe('desktop', () => {
138+
beforeEach(() => {
139+
deviceService.isMobile.and.returnValue(false);
140+
});
141+
142+
it('should open SharingDialogComponent for a record', async () => {
143+
const record = new RecordVO({ recordId: 123 });
144+
(apiService.record.getRecordShareLink as jasmine.Spy).and.resolveTo([
145+
mockShareLink,
146+
]);
147+
148+
await service.openShareDialog(record);
149+
150+
expect(apiService.record.getRecordShareLink).toHaveBeenCalledWith(
151+
record,
152+
);
153+
154+
expect(dialogService.open).toHaveBeenCalledWith(
155+
SharingDialogComponent,
156+
{
157+
data: {
158+
item: record,
159+
newShare: mockShareLink,
160+
},
161+
width: '600px',
162+
panelClass: 'dialog',
163+
},
164+
);
165+
});
166+
167+
it('should open SharingDialogComponent for a folder', async () => {
168+
const folder = new FolderVO({ folderId: 456 });
169+
(apiService.folder.getFolderShareLink as jasmine.Spy).and.resolveTo([
170+
mockShareLink,
171+
]);
172+
173+
await service.openShareDialog(folder);
174+
175+
expect(apiService.folder.getFolderShareLink).toHaveBeenCalledWith(
176+
folder,
177+
);
178+
179+
expect(dialogService.open).toHaveBeenCalledWith(
180+
SharingDialogComponent,
181+
{
182+
data: {
183+
item: folder,
184+
newShare: mockShareLink,
185+
},
186+
width: '600px',
187+
panelClass: 'dialog',
188+
},
189+
);
190+
});
191+
192+
it('should pass undefined as newShare when no share links exist', async () => {
193+
const record = new RecordVO({ recordId: 123 });
194+
(apiService.record.getRecordShareLink as jasmine.Spy).and.resolveTo([]);
195+
196+
await service.openShareDialog(record);
197+
198+
expect(dialogService.open).toHaveBeenCalledWith(
199+
SharingDialogComponent,
200+
{
201+
data: {
202+
item: record,
203+
newShare: undefined,
204+
},
205+
width: '600px',
206+
panelClass: 'dialog',
207+
},
208+
);
209+
});
210+
211+
it('should not open dialog when getShareLinkByItemId throws an error', async () => {
212+
const record = new RecordVO({ recordId: 123 });
213+
(apiService.record.getRecordShareLink as jasmine.Spy).and.rejectWith(
214+
new Error('API error'),
215+
);
216+
217+
await service.openShareDialog(record);
218+
219+
expect(dialogService.open).not.toHaveBeenCalled();
220+
});
221+
});
222+
223+
describe('mobile', () => {
224+
beforeEach(() => {
225+
deviceService.isMobile.and.returnValue(true);
226+
});
227+
228+
it('should open SharingComponent for a record', async () => {
229+
const record = new RecordVO({ recordId: 123 });
230+
const mockShareByUrlVO = { shareby_urlId: 123 };
231+
const mockResponse = {
232+
getShareByUrlVO: () => mockShareByUrlVO,
233+
};
234+
235+
(apiService.share.getShareLink as jasmine.Spy).and.resolveTo(
236+
mockResponse,
237+
);
238+
shareLinksApiService.getShareLinksById.and.resolveTo([mockShareLink]);
239+
240+
await service.openShareDialog(record);
241+
242+
expect(apiService.share.getShareLink).toHaveBeenCalledWith(record);
243+
expect(shareLinksApiService.getShareLinksById).toHaveBeenCalledWith([
244+
123,
245+
]);
246+
247+
expect(dialogService.open).toHaveBeenCalledWith(SharingComponent, {
248+
panelClass: 'dialog',
249+
data: {
250+
item: record,
251+
link: mockShareByUrlVO,
252+
newShare: mockShareLink,
253+
},
254+
});
255+
});
256+
257+
it('should not open dialog when getShareLink throws an error', async () => {
258+
const record = new RecordVO({ recordId: 123 });
259+
(apiService.share.getShareLink as jasmine.Spy).and.rejectWith(
260+
new Error('API error'),
261+
);
262+
263+
await service.openShareDialog(record);
264+
265+
expect(dialogService.open).not.toHaveBeenCalled();
266+
});
267+
268+
it('should pass undefined as newShare when getShareByUrlVO returns null', async () => {
269+
const record = new RecordVO({ recordId: 123 });
270+
const mockResponse = {
271+
getShareByUrlVO: () => null,
272+
};
273+
274+
(apiService.share.getShareLink as jasmine.Spy).and.resolveTo(
275+
mockResponse,
276+
);
277+
278+
await service.openShareDialog(record);
279+
280+
expect(shareLinksApiService.getShareLinksById).not.toHaveBeenCalled();
281+
expect(dialogService.open).toHaveBeenCalledWith(SharingComponent, {
282+
panelClass: 'dialog',
283+
data: {
284+
item: record,
285+
link: null,
286+
newShare: undefined,
287+
},
288+
});
289+
});
290+
});
291+
});
97292
});

src/app/core/services/edit/edit.service.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -529,10 +529,10 @@ export class EditService {
529529
}
530530

531531
async openShareDialog(item: ItemVO) {
532-
const response = await this.api.share.getShareLink(item);
533-
const newShareLink = await this.fetchShareLinkFromResponse(response);
534532
if (this.device.isMobile()) {
535533
try {
534+
const response = await this.api.share.getShareLink(item);
535+
const newShareLink = await this.fetchShareLinkFromResponse(response);
536536
this.dialog.open(SharingComponent, {
537537
panelClass: 'dialog',
538538
data: {
@@ -544,10 +544,10 @@ export class EditService {
544544
} catch (err) {}
545545
} else {
546546
try {
547+
const newShareLink = await this.getShareLinkByItemId(item);
547548
this.dialog.open(SharingDialogComponent, {
548549
data: {
549550
item,
550-
link: response.getShareByUrlVO(),
551551
newShare: newShareLink,
552552
},
553553
width: '600px',
@@ -577,6 +577,23 @@ export class EditService {
577577
}
578578
return undefined;
579579
}
580+
private async getShareLinkByItemId(
581+
item: ItemVO,
582+
): Promise<ShareLink | undefined> {
583+
let shareResponse: ShareLink[] | undefined;
584+
585+
if (item.isRecord) {
586+
shareResponse = await this.api.record.getRecordShareLink(
587+
item as RecordVO,
588+
);
589+
} else if (item.isFolder) {
590+
shareResponse = await this.api.folder.getFolderShareLink(
591+
item as FolderVO,
592+
);
593+
}
594+
595+
return shareResponse?.[0];
596+
}
580597

581598
async openTagsDialog(item: ItemVO, type: string) {
582599
this.dialog.open(EditTagsComponent, {

0 commit comments

Comments
 (0)