Skip to content

Commit

Permalink
chore: added tests for usage repository
Browse files Browse the repository at this point in the history
  • Loading branch information
apsantiso committed Dec 10, 2024
1 parent b3100c6 commit f968a38
Show file tree
Hide file tree
Showing 3 changed files with 222 additions and 1 deletion.
67 changes: 67 additions & 0 deletions src/modules/file/file.usecase.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { SharingService } from '../sharing/sharing.service';
import { SharingItemType } from '../sharing/sharing.domain';
import { CreateFileDto } from './dto/create-file.dto';
import { UpdateFileMetaDto } from './dto/update-file-meta.dto';
import { UsageUseCases } from '../usage/usage.usecase';

const fileId = '6295c99a241bb000083f1c6a';
const userId = 1;
Expand All @@ -48,6 +49,8 @@ describe('FileUseCases', () => {
let sharingService: SharingService;
let bridgeService: BridgeService;
let cryptoService: CryptoService;
let usageUsecases: UsageUseCases;
let networkService: BridgeService;

const userMocked = User.build({
id: 1,
Expand Down Expand Up @@ -94,6 +97,8 @@ describe('FileUseCases', () => {
bridgeService = module.get<BridgeService>(BridgeService);
cryptoService = module.get<CryptoService>(CryptoService);
sharingService = module.get<SharingService>(SharingService);
usageUsecases = module.get<UsageUseCases>(UsageUseCases);
networkService = module.get<BridgeService>(BridgeService);
});

afterEach(() => {
Expand Down Expand Up @@ -1114,4 +1119,66 @@ describe('FileUseCases', () => {
);
});
});

describe('replaceFile', () => {
const originalFile = newFile({
attributes: {
size: BigInt(500),
status: FileStatus.EXISTS,
},
});

const newFileData = {
fileId: v4(),
size: BigInt(1000),
};

it('When the file does not exist, it should throw', async () => {
jest.spyOn(fileRepository, 'findByUuid').mockResolvedValueOnce(null);

await expect(
service.replaceFile(userMocked, originalFile.uuid, newFileData),
).rejects.toThrow(NotFoundException);
});

it('When the file was deleted or trashed, it should throw', async () => {
const trashedFile = newFile({
attributes: { ...originalFile, status: FileStatus.DELETED },
});

jest
.spyOn(fileRepository, 'findByUuid')
.mockResolvedValueOnce(trashedFile);

await expect(
service.replaceFile(userMocked, originalFile.uuid, newFileData),
).rejects.toThrow(NotFoundException);
});

it('When the file exists and is valid, it updates the file data correctly', async () => {
jest
.spyOn(fileRepository, 'findByUuid')
.mockResolvedValueOnce(originalFile);
jest.spyOn(networkService, 'deleteFile').mockResolvedValueOnce(null);
jest.spyOn(fileRepository, 'updateByUuidAndUserId');
jest
.spyOn(usageUsecases, 'addDailyUsageChangeOnFileSizeChange')
.mockResolvedValueOnce(null);

await service.replaceFile(userMocked, originalFile.uuid, newFileData);

expect(fileRepository.updateByUuidAndUserId).toHaveBeenCalledWith(
originalFile.uuid,
userMocked.id,
newFileData,
);
expect(
usageUsecases.addDailyUsageChangeOnFileSizeChange,
).toHaveBeenCalledWith(
userMocked,
originalFile,
expect.objectContaining(newFileData),
);
});
});
});
154 changes: 154 additions & 0 deletions src/modules/usage/usage.repository.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { Test, TestingModule } from '@nestjs/testing';
import { SequelizeUsageRepository } from './usage.repository';
import { UsageModel } from './usage.model';
import { getModelToken } from '@nestjs/sequelize';
import { createMock } from '@golevelup/ts-jest';
import { Usage, UsageType } from './usage.domain';
import { newUsage, newUser } from '../../../test/fixtures';

const mockUsageInstance = (usageData): Partial<UsageModel> => ({
...usageData,
toJSON: jest.fn().mockReturnValue(usageData),
});

const mockedUser = newUser();
const mockSequelizeQuery = jest.fn();

describe('SequelizeUsageRepository', () => {
let repository: SequelizeUsageRepository;
let usageModel: typeof UsageModel;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [SequelizeUsageRepository],
})
.useMocker((token) => {
if (token === getModelToken(UsageModel)) {
return {
findAll: jest.fn(),
findOne: jest.fn(),
create: jest.fn(),
sequelize: {
query: mockSequelizeQuery,
},
};
}
return createMock();
})
.compile();

repository = module.get<SequelizeUsageRepository>(SequelizeUsageRepository);
usageModel = module.get<typeof UsageModel>(getModelToken(UsageModel));
});

describe('getUserUsages', () => {
it('When usages are found for a user, it should return successfully', async () => {
const mockUsages = [
mockUsageInstance(newUsage()),
mockUsageInstance(newUsage()),
];
jest
.spyOn(usageModel, 'findAll')
.mockResolvedValueOnce(mockUsages as any);

const result = await repository.getUserUsages(mockedUser.uuid);

expect(result).toHaveLength(mockUsages.length);
expect(result[0]).toBeInstanceOf(Usage);
});

it('When no usages are found for a user, it should return nothing', async () => {
jest.spyOn(usageModel, 'findAll').mockResolvedValueOnce([]);

const result = await repository.getUserUsages(mockedUser.uuid);

expect(result).toEqual([]);
});
});

describe('create', () => {
it('When usage is created, it should return successfully', async () => {
const usage = newUsage();
const mockUsage = mockUsageInstance(usage);
jest.spyOn(usageModel, 'create').mockResolvedValueOnce(mockUsage as any);

const result = await repository.create(usage);

expect(result).toBeInstanceOf(Usage);
expect(result.id).toEqual(mockUsage.id);
});
});

describe('getMostRecentMonthlyOrYearlyUsage', () => {
it('When the most recent monthly or yearly usage exists, it should return successfully', async () => {
const mockUsage = mockUsageInstance(
newUsage({ attributes: { type: UsageType.Monthly } }),
);
jest.spyOn(usageModel, 'findOne').mockResolvedValueOnce(mockUsage as any);

const result = await repository.getMostRecentMonthlyOrYearlyUsage(
mockedUser.uuid,
);

expect(result).toBeInstanceOf(Usage);
expect(result.type).toBe(UsageType.Monthly);
});

it('When no recent monthly or yearly usage exists, it should return nothing', async () => {
jest.spyOn(usageModel, 'findOne').mockResolvedValueOnce(null);

const result = await repository.getMostRecentMonthlyOrYearlyUsage(
mockedUser.uuid,
);

expect(result).toBeNull();
});
});

describe('getUsage', () => {
it('When a usage is found, it should return successfully', async () => {
const mockUsage = mockUsageInstance(newUsage());
jest.spyOn(usageModel, 'findOne').mockResolvedValueOnce(mockUsage as any);

const result = await repository.getUsage({ type: UsageType.Daily });

expect(result).toBeInstanceOf(Usage);
expect(result.type).toBe(UsageType.Daily);
});

it('When no usage is found, it should return null', async () => {
jest.spyOn(usageModel, 'findOne').mockResolvedValueOnce(null);

const result = await repository.getUsage({ type: UsageType.Daily });

expect(result).toBeNull();
expect(usageModel.findOne).toHaveBeenCalledWith({
where: { type: UsageType.Daily },
order: undefined,
});
});
});

describe('getUserUsage', () => {
it('When user usage is requested, it should return the aggregated totals', async () => {
mockSequelizeQuery.mockResolvedValueOnce([
[
{
total_yearly_delta: 500,
total_monthly_delta: 200,
},
],
]);

const result = await repository.getUserUsage(mockedUser.uuid);

expect(mockSequelizeQuery).toHaveBeenCalledWith(expect.any(String), {
replacements: { userUuid: mockedUser.uuid },
});
expect(result).toEqual({
total_yearly_delta: 500,
total_monthly_delta: 200,
});
});
});
});
2 changes: 1 addition & 1 deletion src/modules/usage/usage.usecase.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('UsageUseCases', () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UsageUseCases],
})
.useMocker(createMock)
.useMocker(() => createMock())
.compile();

usageUseCases = module.get<UsageUseCases>(UsageUseCases);
Expand Down

0 comments on commit f968a38

Please sign in to comment.