Skip to content

Commit

Permalink
#15 - Rework sharing endpoints to work recursively
Browse files Browse the repository at this point in the history
  • Loading branch information
frederikpyt committed Oct 10, 2023
1 parent cf983a0 commit 29d0085
Show file tree
Hide file tree
Showing 10 changed files with 418 additions and 105 deletions.
57 changes: 36 additions & 21 deletions src/modules/item/__test__/item.service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('ItemService', () => {
itemService = new ItemService();
userService = new UserService();
folderService = new FolderService();
sharingService = new SharingService();
sharingService = new SharingService(itemService);
blobService = new BlobService();
shortcutService = new ShortcutService();

Expand Down Expand Up @@ -137,10 +137,13 @@ describe('ItemService', () => {
parentId: null,
});

await sharingService.createSharing({
itemId: folder.id,
userId: otherUser.id,
});
await sharingService.createSharing(
{
itemId: folder.id,
userId: otherUser.id,
},
user.id,
);

const blob1 = await blobService.createBlob({
mimeType: 'text/plain',
Expand Down Expand Up @@ -177,20 +180,29 @@ describe('ItemService', () => {
parentId: folder.id,
});

await sharingService.createSharing({
itemId: blob1.id,
userId: otherUser.id,
});
await sharingService.createSharing(
{
itemId: blob1.id,
userId: otherUser.id,
},
user.id,
);

await sharingService.createSharing({
itemId: folder1.id,
userId: otherUser.id,
});
await sharingService.createSharing(
{
itemId: folder1.id,
userId: otherUser.id,
},
user.id,
);

await sharingService.createSharing({
itemId: folder3.id,
userId: otherUser.id,
});
await sharingService.createSharing(
{
itemId: folder3.id,
userId: otherUser.id,
},
user.id,
);

const shortcut1 = await shortcutService.createShortcut({
name: 'Shortcut1',
Expand All @@ -206,10 +218,13 @@ describe('ItemService', () => {
parentId: folder.id,
});

await sharingService.createSharing({
itemId: shortcut1.id,
userId: otherUser.id,
});
await sharingService.createSharing(
{
itemId: shortcut1.id,
userId: otherUser.id,
},
user.id,
);

const itemsOwner = await itemService.getAllOwnedAndSharredItemsByParentIdAndUserId(
user.id,
Expand Down
26 changes: 26 additions & 0 deletions src/modules/item/item.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,32 @@ export default class ItemService {
return this.formatItems(items);
}

public async getAllOwnedAndSharredItemsByParentIdAndUserIdRecursively(
userId: number,
parentId: number | null,
): Promise<ItemWithProperties[]> {
const returnItems = [];

const items = await this.getAllOwnedAndSharredItemsByParentIdAndUserId(userId, parentId);
returnItems.push(...items);

await Promise.all(
items.map(async (item) => {
if (item.mimeType !== 'application/vnd.cloudstore.folder') {
return;
}

const childItems = await this.getAllOwnedAndSharredItemsByParentIdAndUserId(
userId,
item.id,
);
returnItems.push(...childItems);
}),
);

return returnItems;
}

public async getAllOwnedAndSharredItemsByParentIdAndUserId(
userId: number,
parentId: number | null,
Expand Down
13 changes: 8 additions & 5 deletions src/modules/item/sharing/__test__/access.service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('ItemService', () => {
beforeAll(async () => {
itemService = new ItemService();
userService = new UserService();
sharingService = new SharingService();
sharingService = new SharingService(itemService);
accessService = new AccessService(itemService, sharingService);

user = await userService.createUser({
Expand Down Expand Up @@ -52,10 +52,13 @@ describe('ItemService', () => {
parentId: null,
mimeType: 'text/plain',
});
await sharingService.createSharing({
itemId: createdItem.id,
userId: user.id,
});
await sharingService.createSharing(
{
itemId: createdItem.id,
userId: user.id,
},
otherUser.id,
);

const hasAccessToItem = await accessService.hasAccessToItem(createdItem.id, user.id);

Expand Down
91 changes: 86 additions & 5 deletions src/modules/item/sharing/__test__/add.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import UserService from '../../../auth/user.service';
import AuthService from '../../../auth/auth.service';
import ItemService from '../../item.service';
import SharingService from '../sharing.service';
import FolderService from '../../folder/folder.service';

describe('POST /api/sharing', () => {
let userService: UserService;
let authService: AuthService;
let itemService: ItemService;
let folderService: FolderService;
let sharingService: SharingService;

let user: User;
Expand All @@ -17,7 +19,8 @@ describe('POST /api/sharing', () => {
authService = new AuthService();
userService = new UserService();
itemService = new ItemService();
sharingService = new SharingService();
folderService = new FolderService();
sharingService = new SharingService(itemService);

user = await userService.createUser({
name: 'Joe Biden the 1st',
Expand Down Expand Up @@ -63,6 +66,81 @@ describe('POST /api/sharing', () => {
});
});

it('should return status 200, return the created sharing and recursively create sharings on all child items', async () => {
const { accessToken } = await authService.createTokens(user.id);

const folder = await folderService.createFolder({
name: 'root',
ownerId: user.id,
parentId: null,
color: 'red',
});

const item1 = await itemService.createItem({
name: 'test1.txt',
ownerId: user.id,
parentId: folder.id,
mimeType: 'text/plain',
});

const item2 = await itemService.createItem({
name: 'test2.txt',
ownerId: user.id,
parentId: folder.id,
mimeType: 'text/plain',
});

const subFolder = await folderService.createFolder({
name: 'sub',
ownerId: user.id,
parentId: folder.id,
color: 'red',
});

const item3 = await itemService.createItem({
name: 'test3.txt',
ownerId: user.id,
parentId: subFolder.id,
mimeType: 'text/plain',
});

const response = await global.fastify.inject({
method: 'POST',
url: '/api/sharing',
headers: {
authorization: 'Bearer ' + accessToken,
},
payload: {
itemId: folder.id,
userId: otherUser.id,
},
});

expect(response.statusCode).toBe(200);
expect(response.json()).toEqual({
id: expect.any(Number),
itemId: folder.id,
userId: otherUser.id,
createdAt: expect.any(String),
updatedAt: expect.any(String),
});
await expect(
sharingService.getByItemIdAndUserId(folder.id, otherUser.id),
).resolves.toBeDefined();
await expect(
sharingService.getByItemIdAndUserId(item1.id, otherUser.id),
).resolves.toBeDefined();
await expect(
sharingService.getByItemIdAndUserId(item2.id, otherUser.id),
).resolves.toBeDefined();
await expect(
sharingService.getByItemIdAndUserId(subFolder.id, otherUser.id),
).resolves.toBeDefined();
await expect(
sharingService.getByItemIdAndUserId(item3.id, otherUser.id),
).resolves.toBeDefined();
});

it('should return status 401, when unauthorized', async () => {
const item = await itemService.createItem({
name: 'test.txt',
Expand Down Expand Up @@ -135,10 +213,13 @@ describe('POST /api/sharing', () => {
mimeType: 'text/plain',
});

await sharingService.createSharing({
itemId: item.id,
userId: user.id,
});
await sharingService.createSharing(
{
itemId: item.id,
userId: user.id,
},
otherUser.id,
);

const response = await global.fastify.inject({
method: 'POST',
Expand Down
Loading

0 comments on commit 29d0085

Please sign in to comment.