diff --git a/src/modules/workspaces/workspaces.usecase.spec.ts b/src/modules/workspaces/workspaces.usecase.spec.ts index dfd8e438..779c7ab2 100644 --- a/src/modules/workspaces/workspaces.usecase.spec.ts +++ b/src/modules/workspaces/workspaces.usecase.spec.ts @@ -4265,6 +4265,9 @@ describe('WorkspacesUsecases', () => { workspaceId: workspace.id, member: workspaceOwner, memberId: workspaceOwner.uuid, + attributes: { + spaceLimit: 1099511627776, // 1TB + }, }); jest @@ -4272,8 +4275,8 @@ describe('WorkspacesUsecases', () => { .mockResolvedValueOnce(workspace); jest .spyOn(workspaceRepository, 'findWorkspaceUser') - .mockResolvedValueOnce(memberWorkspaceUser) - .mockResolvedValueOnce(ownerWorkspaceUser); + .mockResolvedValueOnce(ownerWorkspaceUser) + .mockResolvedValueOnce(memberWorkspaceUser); jest .spyOn(userRepository, 'findByUuid') .mockResolvedValueOnce(workspaceNetworkUser); @@ -4286,6 +4289,10 @@ describe('WorkspacesUsecases', () => { jest .spyOn(folderUseCases, 'getFoldersInWorkspace') .mockResolvedValueOnce([]); + jest + .spyOn(service, 'calculateFilesSizeSum') + .mockResolvedValueOnce(0) + .mockResolvedValueOnce(483183820800); // 450 GB await expect( service.transferPersonalItemsToWorkspaceOwner(workspace.id, member), @@ -4293,6 +4300,55 @@ describe('WorkspacesUsecases', () => { expect(folderUseCases.moveFolder).not.toHaveBeenCalled(); }); + it("When owner doesn't have enough free space then it shoudl throw", async () => { + const workspaceOwner = newUser(); + const workspaceNetworkUser = newUser(); + const member = newUser(); + const workspace = newWorkspace({ + owner: workspaceOwner, + }); + const folderToMove = newFolder(); + const memberWorkspaceUser = newWorkspaceUser({ + workspaceId: workspace.id, + member: member, + memberId: member.uuid, + attributes: { + rootFolderId: folderToMove.uuid, + }, + }); + const ownerWorkspaceUser = newWorkspaceUser({ + workspaceId: workspace.id, + member: workspaceOwner, + memberId: workspaceOwner.uuid, + attributes: { + spaceLimit: 1099511627776, // 1TB + }, + }); + + jest + .spyOn(workspaceRepository, 'findById') + .mockResolvedValueOnce(workspace); + jest + .spyOn(workspaceRepository, 'findWorkspaceUser') + .mockResolvedValueOnce(ownerWorkspaceUser) + .mockResolvedValueOnce(memberWorkspaceUser); + jest + .spyOn(userRepository, 'findByUuid') + .mockResolvedValueOnce(workspaceNetworkUser); + jest + .spyOn(folderUseCases, 'getByUuid') + .mockResolvedValueOnce(folderToMove); + + jest + .spyOn(service, 'calculateFilesSizeSum') + .mockResolvedValueOnce(483183820800) // 450GB + .mockResolvedValueOnce(644245094400); // 600 GB + + await expect( + service.transferPersonalItemsToWorkspaceOwner(workspace.id, member), + ).rejects.toThrow(BadRequestException); + }); + it("When user is not the owner of the workspace, then it should move the member's root folder to the workspace owner's root folder", async () => { const workspaceOwner = newUser(); const workspaceNetworkUser = newUser(); @@ -4313,6 +4369,9 @@ describe('WorkspacesUsecases', () => { workspaceId: workspace.id, member: workspaceOwner, memberId: workspaceOwner.uuid, + attributes: { + spaceLimit: 1099511627776, // 1TB + }, }); const resultingFolder = Object.assign(newFolder(), folderToMove, { parentUuid: ownerWorkspaceUser.rootFolderId, @@ -4331,8 +4390,8 @@ describe('WorkspacesUsecases', () => { .mockResolvedValueOnce(workspace); jest .spyOn(workspaceRepository, 'findWorkspaceUser') - .mockResolvedValueOnce(memberWorkspaceUser) - .mockResolvedValueOnce(ownerWorkspaceUser); + .mockResolvedValueOnce(ownerWorkspaceUser) + .mockResolvedValueOnce(memberWorkspaceUser); jest .spyOn(userRepository, 'findByUuid') .mockResolvedValueOnce(workspaceNetworkUser); @@ -4351,6 +4410,10 @@ describe('WorkspacesUsecases', () => { jest .spyOn(folderUseCases, 'renameFolder') .mockResolvedValueOnce(resultingRenamedFolder); + jest + .spyOn(service, 'calculateFilesSizeSum') + .mockResolvedValueOnce(483183820800) // 450 GB + .mockResolvedValueOnce(483183820800); // 450 GB const shortIdentifier = Buffer.from(memberWorkspaceUser.id) .toString('base64') @@ -4413,6 +4476,9 @@ describe('WorkspacesUsecases', () => { workspaceId: workspace.id, memberId: member.uuid, member, + attributes: { + spaceLimit: 1099511627776, // 1TB + }, }); jest @@ -4422,6 +4488,10 @@ describe('WorkspacesUsecases', () => { .spyOn(workspaceRepository, 'findById') .mockResolvedValue(workspace); jest.spyOn(workspaceRepository, 'deleteUserFromWorkspace'); + jest + .spyOn(service, 'calculateFilesSizeSum') + .mockResolvedValueOnce(483183820800) // 450 GB + .mockResolvedValueOnce(483183820800); // 450 GB expect( await service.removeWorkspaceMember(workspace.id, member.uuid), @@ -4462,6 +4532,9 @@ describe('WorkspacesUsecases', () => { const workspaceUser = newWorkspaceUser({ memberId: user.uuid, workspaceId: workspace.id, + attributes: { + spaceLimit: 1099511627776, // 1TB + }, }); jest .spyOn(workspaceRepository, 'findById') @@ -4470,6 +4543,10 @@ describe('WorkspacesUsecases', () => { .spyOn(workspaceRepository, 'findWorkspaceUser') .mockResolvedValue(workspaceUser); jest.spyOn(service, 'transferPersonalItemsToWorkspaceOwner'); + jest + .spyOn(service, 'calculateFilesSizeSum') + .mockResolvedValueOnce(483183820800) // 450 GB + .mockResolvedValueOnce(483183820800); // 450 GB await service.leaveWorkspace(workspace.id, user); @@ -4485,6 +4562,9 @@ describe('WorkspacesUsecases', () => { const workspaceUser = newWorkspaceUser({ memberId: user.uuid, workspaceId: workspace.id, + attributes: { + spaceLimit: 1099511627776, // 1TB + }, }); const team = newWorkspaceTeam({ workspaceId: workspace.id, @@ -4500,6 +4580,10 @@ describe('WorkspacesUsecases', () => { jest .spyOn(teamRepository, 'getTeamsWhereUserIsManagerByWorkspaceId') .mockResolvedValue([team]); + jest + .spyOn(service, 'calculateFilesSizeSum') + .mockResolvedValueOnce(483183820800) // 450 GB + .mockResolvedValueOnce(483183820800); // 450 GB await service.leaveWorkspace(workspace.id, user); @@ -4516,28 +4600,37 @@ describe('WorkspacesUsecases', () => { workspaceRepository.deleteUserFromWorkspace, ).toHaveBeenCalledWith(user.uuid, workspace.id); }); - }); - it('When user is not a manager of any teams and has no items in the workspace, then they should leave the workspace', async () => { - const user = newUser(); - const workspace = newWorkspace(); - const workspaceUser = newWorkspaceUser({ - memberId: user.uuid, - workspaceId: workspace.id, - }); + it('When user is not a manager of any teams and has no items in the workspace, then they should leave the workspace', async () => { + const user = newUser(); + const workspace = newWorkspace(); + const workspaceUser = newWorkspaceUser({ + memberId: user.uuid, + workspaceId: workspace.id, + attributes: { + spaceLimit: 1099511627776, // 1TB + }, + }); - jest.spyOn(workspaceRepository, 'findById').mockResolvedValue(workspace); - jest - .spyOn(workspaceRepository, 'findWorkspaceUser') - .mockResolvedValue(workspaceUser); + jest + .spyOn(workspaceRepository, 'findById') + .mockResolvedValue(workspace); + jest + .spyOn(workspaceRepository, 'findWorkspaceUser') + .mockResolvedValue(workspaceUser); + jest + .spyOn(service, 'calculateFilesSizeSum') + .mockResolvedValueOnce(0) // 450 GB + .mockResolvedValueOnce(483183820800); // 450 GB - await service.leaveWorkspace(workspace.id, user); + await service.leaveWorkspace(workspace.id, user); - expect(workspaceRepository.deleteUserFromWorkspace).toHaveBeenCalledWith( - user.uuid, - workspace.id, - ); + expect( + workspaceRepository.deleteUserFromWorkspace, + ).toHaveBeenCalledWith(user.uuid, workspace.id); + }); }); + describe('upload workspace Avatar', () => { const newAvatarKey = v4(); const newAvatarURL = `http://localhost:9000/${newAvatarKey}`; diff --git a/src/modules/workspaces/workspaces.usecase.ts b/src/modules/workspaces/workspaces.usecase.ts index ce213773..a214b503 100644 --- a/src/modules/workspaces/workspaces.usecase.ts +++ b/src/modules/workspaces/workspaces.usecase.ts @@ -2203,6 +2203,33 @@ export class WorkspacesUsecases { throw new ForbiddenException('You are the owner of this workspace'); } + const memberUsage = await this.calculateFilesSizeSum( + user.uuid, + workspace.id, + [FileStatus.EXISTS, FileStatus.TRASHED], + ); + + const ownerUsage = await this.calculateFilesSizeSum( + workspace.ownerId, + workspace.id, + [FileStatus.EXISTS, FileStatus.TRASHED], + ); + + const combinedUsage = Number(memberUsage) + Number(ownerUsage); + + const ownerWorkspaceUser = await this.workspaceRepository.findWorkspaceUser( + { + workspaceId, + memberId: workspace.ownerId, + }, + ); + + if (Number(ownerWorkspaceUser.spaceLimit) < combinedUsage) { + throw new BadRequestException( + 'Owner does not have enough space to receive the files', + ); + } + const memberWorkspaceUser = await this.workspaceRepository.findWorkspaceUser({ workspaceId, @@ -2224,7 +2251,6 @@ export class WorkspacesUsecases { }, { limit: 1, offset: 0 }, ); - const filesInPersonalRootFolder = await this.fileUseCases.getFilesInWorkspace( user.uuid, @@ -2248,13 +2274,6 @@ export class WorkspacesUsecases { workspace.workspaceUserId, ); - const ownerWorkspaceUser = await this.workspaceRepository.findWorkspaceUser( - { - workspaceId, - memberId: workspace.ownerId, - }, - ); - const movedFolder = await this.folderUseCases.moveFolder( workspaceNetworkUser, memberRootFolder.uuid,