-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PB-845: Calculate folder size and expose it via shared & Drive
- Loading branch information
1 parent
e027d9f
commit 1f06f4f
Showing
12 changed files
with
275 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,11 @@ | ||
import { HttpStatus } from '@nestjs/common'; | ||
|
||
export class BaseHttpException extends Error { | ||
private readonly _statusCode: number; | ||
private readonly _code: string; | ||
|
||
constructor( | ||
message: string, | ||
statusCode = HttpStatus.INTERNAL_SERVER_ERROR, | ||
code?: string, | ||
public readonly message: string, | ||
public readonly statusCode = HttpStatus.INTERNAL_SERVER_ERROR, | ||
public readonly code?: string, | ||
) { | ||
super(message); | ||
this.message = message; | ||
this._statusCode = statusCode; | ||
this._code = code; | ||
} | ||
|
||
get statusCode(): number { | ||
return this._statusCode; | ||
} | ||
|
||
get code(): string { | ||
return this._code; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
src/modules/folder/exception/calculate-folder-size-timeout.exception.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { HttpStatus } from '@nestjs/common'; | ||
import { BaseHttpException } from '../../../common/base-http.exception'; | ||
|
||
export class CalculateFolderSizeTimeoutException extends BaseHttpException { | ||
constructor( | ||
message = 'Calculate folder size timeout', | ||
code = 'CALCULATE_FOLDER_SIZE_TIMEOUT', | ||
statusCode = HttpStatus.UNPROCESSABLE_ENTITY, | ||
) { | ||
super(message, statusCode, code); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { createMock } from '@golevelup/ts-jest'; | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
import { FileUseCases } from '../file/file.usecase'; | ||
import { FolderController } from './folder.controller'; | ||
import { FolderUseCases } from './folder.usecase'; | ||
import { CalculateFolderSizeTimeoutException } from './exception/calculate-folder-size-timeout.exception'; | ||
|
||
describe('FolderController', () => { | ||
let folderController: FolderController; | ||
let folderUseCases: FolderUseCases; | ||
|
||
beforeEach(async () => { | ||
const module: TestingModule = await Test.createTestingModule({ | ||
controllers: [FolderController], | ||
providers: [ | ||
{ provide: FolderUseCases, useValue: createMock() }, | ||
{ provide: FileUseCases, useValue: createMock() }, | ||
], | ||
}).compile(); | ||
|
||
folderController = module.get<FolderController>(FolderController); | ||
folderUseCases = module.get<FolderUseCases>(FolderUseCases); | ||
}); | ||
|
||
describe('getFolderSize', () => { | ||
it('When getFolderSizeController is called, Then return folder size', async () => { | ||
const folderUuid = 'valid-uuid'; | ||
const expectedSize = 100; | ||
jest | ||
.spyOn(folderUseCases, 'getFolderSizeByUuid') | ||
.mockResolvedValue(expectedSize); | ||
|
||
const result = await folderController.getFolderSize(folderUuid); | ||
expect(result).toEqual({ size: expectedSize }); | ||
}); | ||
|
||
it('When getFolderSizeController throws timeout exception, Then throws CalculateFolderSizeTimeoutException instance', async () => { | ||
const folderUuid = 'valid-uuid'; | ||
|
||
jest | ||
.spyOn(folderUseCases, 'getFolderSizeByUuid') | ||
.mockRejectedValue(new CalculateFolderSizeTimeoutException()); | ||
|
||
await expect(folderController.getFolderSize(folderUuid)).rejects.toThrow( | ||
CalculateFolderSizeTimeoutException, | ||
); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { createMock } from '@golevelup/ts-jest'; | ||
import { CalculateFolderSizeTimeoutException } from './exception/calculate-folder-size-timeout.exception'; | ||
import { SequelizeFolderRepository } from './folder.repository'; | ||
import { FolderModel } from './folder.model'; | ||
import { Folder } from './folder.domain'; | ||
import { newFolder } from '../../../test/fixtures'; | ||
|
||
jest.mock('./folder.model', () => ({ | ||
FolderModel: { | ||
sequelize: { | ||
query: jest.fn(() => Promise.resolve([[{ totalsize: 100 }]])), | ||
}, | ||
}, | ||
})); | ||
|
||
describe('SequelizeFolderRepository', () => { | ||
const TIMEOUT_SECONDS = 15; | ||
const TIMEOUT_ERROR_CODE = '57014'; | ||
|
||
let repository: SequelizeFolderRepository; | ||
let folderModel: typeof FolderModel; | ||
let folder: Folder; | ||
|
||
beforeEach(async () => { | ||
folderModel = createMock<typeof FolderModel>(); | ||
|
||
repository = new SequelizeFolderRepository(folderModel); | ||
|
||
folder = newFolder(); | ||
}); | ||
|
||
describe('calculate folder size', () => { | ||
it('When calculate folder size is requested, then it works', async () => { | ||
const calculateSizeQuery = ` | ||
BEGIN; | ||
SET LOCAL statement_timeout TO :timeoutSeconds; | ||
WITH RECURSIVE folder_recursive AS ( | ||
SELECT | ||
fl1.uuid, | ||
fl1.parent_uuid, | ||
f1.size AS filesize | ||
FROM folders fl1 | ||
LEFT JOIN files f1 ON f1.folder_uuid = fl1.uuid | ||
WHERE fl1.uuid = :folderUuid | ||
UNION ALL | ||
SELECT | ||
fl2.uuid, | ||
fl2.parent_uuid, | ||
f2.size AS filesize | ||
FROM folders fl2 | ||
INNER JOIN files f2 ON f2.folder_uuid = fl2.uuid | ||
INNER JOIN folder_recursive fr ON fr.uuid = fl2.parent_uuid | ||
) | ||
SELECT COALESCE(SUM(filesize), 0) AS total_size FROM folder_recursive; | ||
COMMIT; | ||
`; | ||
|
||
jest | ||
.spyOn(FolderModel.sequelize, 'query') | ||
.mockResolvedValue([[{ totalsize: 100 }]] as any); | ||
|
||
const size = await repository.calculateFolderSize( | ||
folder.uuid, | ||
TIMEOUT_SECONDS, | ||
); | ||
|
||
expect(size).toBeGreaterThanOrEqual(0); | ||
expect(FolderModel.sequelize.query).toHaveBeenCalledWith( | ||
calculateSizeQuery, | ||
{ | ||
replacements: { | ||
folderUuid: folder.uuid, | ||
timeoutSeconds: TIMEOUT_SECONDS * 1000, | ||
}, | ||
}, | ||
); | ||
}); | ||
|
||
it('When the folder size calculation times out, then throw an exception', async () => { | ||
jest.spyOn(FolderModel.sequelize, 'query').mockRejectedValue({ | ||
original: { | ||
code: TIMEOUT_ERROR_CODE, | ||
}, | ||
}); | ||
|
||
await expect( | ||
repository.calculateFolderSize(folder.uuid, TIMEOUT_SECONDS), | ||
).rejects.toThrow(CalculateFolderSizeTimeoutException); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.