diff --git a/src/modules/folder/folder.repository.spec.ts b/src/modules/folder/folder.repository.spec.ts index 5b4da79ee..d287bdaf1 100644 --- a/src/modules/folder/folder.repository.spec.ts +++ b/src/modules/folder/folder.repository.spec.ts @@ -4,6 +4,7 @@ import { SequelizeFolderRepository } from './folder.repository'; import { FolderModel } from './folder.model'; import { Folder } from './folder.domain'; import { newFolder } from '../../../test/fixtures'; +import { FileStatus } from '../file/file.domain'; jest.mock('./folder.model', () => ({ FolderModel: { @@ -39,7 +40,7 @@ describe('SequelizeFolderRepository', () => { 1 AS row_num, fl1.user_id as owner_id FROM folders fl1 - LEFT JOIN files f1 ON f1.folder_uuid = fl1.uuid AND f1.status != 'DELETED' + LEFT JOIN files f1 ON f1.folder_uuid = fl1.uuid AND f1.status IN (:fileStatusCondition) WHERE fl1.uuid = :folderUuid AND fl1.removed = FALSE AND fl1.deleted = FALSE @@ -53,7 +54,7 @@ describe('SequelizeFolderRepository', () => { fr.row_num + 1, fr.owner_id FROM folders fl2 - LEFT JOIN files f2 ON f2.folder_uuid = fl2.uuid AND f2.status != 'DELETED' + LEFT JOIN files f2 ON f2.folder_uuid = fl2.uuid AND f2.status IN (:fileStatusCondition) INNER JOIN folder_recursive fr ON fr.uuid = fl2.parent_uuid WHERE fr.row_num < 100000 AND fl2.user_id = fr.owner_id @@ -75,11 +76,25 @@ describe('SequelizeFolderRepository', () => { { replacements: { folderUuid: folder.uuid, + fileStatusCondition: [FileStatus.EXISTS, FileStatus.TRASHED], }, }, ); }); + it('When calculate folder size is requested without trashed files, then it should only request existent files', async () => { + const folderModelSpy = jest.spyOn(FolderModel.sequelize, 'query'); + + await repository.calculateFolderSize(folder.uuid, false); + + expect(folderModelSpy).toHaveBeenCalledWith(expect.any(String), { + replacements: { + folderUuid: folder.uuid, + fileStatusCondition: [FileStatus.EXISTS], + }, + }); + }); + it('When the folder size calculation times out, then throw an exception', async () => { jest.spyOn(FolderModel.sequelize, 'query').mockRejectedValue({ original: { diff --git a/src/modules/folder/folder.repository.ts b/src/modules/folder/folder.repository.ts index bd1332067..13c905c57 100644 --- a/src/modules/folder/folder.repository.ts +++ b/src/modules/folder/folder.repository.ts @@ -13,6 +13,7 @@ import { FolderModel } from './folder.model'; import { SharingModel } from '../sharing/models'; import { CalculateFolderSizeTimeoutException } from './exception/calculate-folder-size-timeout.exception'; import { Literal } from 'sequelize/types/utils'; +import { FileStatus } from '../file/file.domain'; function mapSnakeCaseToCamelCase(data) { const camelCasedObject = {}; @@ -515,8 +516,15 @@ export class SequelizeFolderRepository implements FolderRepository { return folders.map((folder) => this.toDomain(folder)); } - async calculateFolderSize(folderUuid: string): Promise { + async calculateFolderSize( + folderUuid: string, + includeTrash = true, + ): Promise { try { + const fileStatusCondition = includeTrash + ? [FileStatus.EXISTS, FileStatus.TRASHED] + : [FileStatus.EXISTS]; + const calculateSizeQuery = ` WITH RECURSIVE folder_recursive AS ( SELECT @@ -526,7 +534,7 @@ export class SequelizeFolderRepository implements FolderRepository { 1 AS row_num, fl1.user_id as owner_id FROM folders fl1 - LEFT JOIN files f1 ON f1.folder_uuid = fl1.uuid AND f1.status != 'DELETED' + LEFT JOIN files f1 ON f1.folder_uuid = fl1.uuid AND f1.status IN (:fileStatusCondition) WHERE fl1.uuid = :folderUuid AND fl1.removed = FALSE AND fl1.deleted = FALSE @@ -540,7 +548,7 @@ export class SequelizeFolderRepository implements FolderRepository { fr.row_num + 1, fr.owner_id FROM folders fl2 - LEFT JOIN files f2 ON f2.folder_uuid = fl2.uuid AND f2.status != 'DELETED' + LEFT JOIN files f2 ON f2.folder_uuid = fl2.uuid AND f2.status IN (:fileStatusCondition) INNER JOIN folder_recursive fr ON fr.uuid = fl2.parent_uuid WHERE fr.row_num < 100000 AND fl2.user_id = fr.owner_id @@ -555,6 +563,7 @@ export class SequelizeFolderRepository implements FolderRepository { { replacements: { folderUuid, + fileStatusCondition, }, }, ); diff --git a/src/modules/folder/folder.usecase.spec.ts b/src/modules/folder/folder.usecase.spec.ts index 4561365f2..837682de1 100644 --- a/src/modules/folder/folder.usecase.spec.ts +++ b/src/modules/folder/folder.usecase.spec.ts @@ -617,6 +617,24 @@ describe('FolderUseCases', () => { expect(folderRepository.calculateFolderSize).toHaveBeenCalledTimes(1); expect(folderRepository.calculateFolderSize).toHaveBeenCalledWith( folder.uuid, + true, + ); + }); + + it('When the folder size is required without including trashed files, then it should request the size without trash', async () => { + const mockSize = 123456789; + + jest + .spyOn(folderRepository, 'calculateFolderSize') + .mockResolvedValueOnce(mockSize); + + const result = await service.getFolderSizeByUuid(folder.uuid, false); + + expect(result).toBe(mockSize); + expect(folderRepository.calculateFolderSize).toHaveBeenCalledTimes(1); + expect(folderRepository.calculateFolderSize).toHaveBeenCalledWith( + folder.uuid, + false, ); }); diff --git a/src/modules/folder/folder.usecase.ts b/src/modules/folder/folder.usecase.ts index a5d1cb42c..ba054d686 100644 --- a/src/modules/folder/folder.usecase.ts +++ b/src/modules/folder/folder.usecase.ts @@ -316,7 +316,9 @@ export class FolderUseCases { const folders = foldersById.concat(foldersByUuid); const backups = folders.filter((f) => f.isBackup(driveRootFolder)); - const driveFolders = folders.filter((f) => !f.isBackup(driveRootFolder) && f.id !== user.rootFolderId); + const driveFolders = folders.filter( + (f) => !f.isBackup(driveRootFolder) && f.id !== user.rootFolderId, + ); await Promise.all([ driveFolders.length > 0 @@ -632,7 +634,13 @@ export class FolderUseCases { await this.folderRepository.deleteByUser(user, folders); } - getFolderSizeByUuid(folderUuid: Folder['uuid']): Promise { - return this.folderRepository.calculateFolderSize(folderUuid); + getFolderSizeByUuid( + folderUuid: Folder['uuid'], + includeTrashedFiles = true, + ): Promise { + return this.folderRepository.calculateFolderSize( + folderUuid, + includeTrashedFiles, + ); } } diff --git a/src/modules/sharing/sharing.service.ts b/src/modules/sharing/sharing.service.ts index 8a093ad66..738250197 100644 --- a/src/modules/sharing/sharing.service.ts +++ b/src/modules/sharing/sharing.service.ts @@ -2089,6 +2089,6 @@ export class SharingService { throw new SharingNotFoundException(); } - return this.folderUsecases.getFolderSizeByUuid(sharing.itemId); + return this.folderUsecases.getFolderSizeByUuid(sharing.itemId, false); } }