Skip to content

Commit

Permalink
feat(test): add tests for profile, game and user use cases
Browse files Browse the repository at this point in the history
  • Loading branch information
havrydotdev committed Oct 17, 2023
1 parent 4fcc557 commit e23b25f
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 47 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test": "jest --runInBand --detectOpenHandles --forceExit",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
Expand Down
38 changes: 38 additions & 0 deletions src/frameworks/game/typeorm/tests/game.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Test, TestingModule } from '@nestjs/testing';
import { TypeOrmGameService } from '../typeorm-game.service';
import { Game } from 'src/core';
import { Repository } from 'typeorm';
import { TypeOrmModule } from '@nestjs/typeorm';
import { MockDatabaseModule } from 'src/services/mock-database/mock-database.module';

describe('TypeOrmGameService', () => {
let service: TypeOrmGameService;
let repo: Repository<Game>;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [MockDatabaseModule, TypeOrmModule.forFeature([Game])],
providers: [TypeOrmGameService],
}).compile();

service = module.get<TypeOrmGameService>(TypeOrmGameService);
repo = module.get<Repository<Game>>(Repository<Game>);
});

it('should return an array of games', async () => {
const games = [
Game.create({
title: 'Test Game 1',
}),
Game.create({
title: 'Test Game 2',
}),
];

jest.spyOn(repo, 'find').mockResolvedValue(games);

const result = await service.findAll();

expect(result).toEqual(games);
});
});
2 changes: 2 additions & 0 deletions src/frameworks/reply/telegraf/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './telegraf-reply.module';
export * from './/telegraf-reply.service';
2 changes: 1 addition & 1 deletion src/services/reply/reply.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { TelegrafReplyModule } from 'src/frameworks/reply/telegraf/telegraf-reply.module';
import { TelegrafReplyModule } from 'src/frameworks/reply/telegraf';

@Module({
imports: [TelegrafReplyModule],
Expand Down
87 changes: 71 additions & 16 deletions src/use-cases/reply/tests/reply.use-case.spec.ts
Original file line number Diff line number Diff line change
@@ -1,72 +1,127 @@
import { Context } from 'telegraf';
import { Context, Markup } from 'telegraf';
import { ReplyUseCases } from '../reply.use-case';
import { Test, TestingModule } from '@nestjs/testing';
import { IReplyService } from 'src/core';
import { I18nModule } from 'src/services/i18n/i18n.module';
import { ConfigModule } from '@nestjs/config';
import { Language } from 'src/core/enums';

// TODO: di
describe('ReplyUseCases', () => {
let useCases: ReplyUseCases;
let ctx: Context;
let service: IReplyService;

beforeEach(() => {
useCases = new ReplyUseCases();
ctx = {} as Context;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
I18nModule,
ConfigModule.forRoot({
isGlobal: true,
}),
],
providers: [
ReplyUseCases,
{
provide: IReplyService,
useValue: {
reply: jest.fn().mockImplementation(() => Promise.resolve()),
translate: jest.fn().mockImplementation(() => Promise.resolve()),
},
},
],
}).compile();

useCases = module.get<ReplyUseCases>(ReplyUseCases);
service = module.get<IReplyService>(IReplyService);

ctx = {
session: {
lang: Language.UA,
},
from: {
first_name: 'test',
},
} as Context;
});

describe('enterName', () => {
it('should send enter_name message with resize_keyboard and one_time_keyboard options', async () => {
const replySpy = spyOn(useCases.replyService, 'reply');
const replySpy = jest.spyOn(service, 'reply');
await useCases.enterName(ctx);

const fullName = `${ctx.from.first_name}`;

const reply_markup = Markup.keyboard([
[Markup.button.callback(fullName, fullName)],
]).reply_markup;

// resize keyboard to fit screen
reply_markup.resize_keyboard = true;

// hide keyboard after user enters name
reply_markup.one_time_keyboard = true;

expect(replySpy).toHaveBeenCalledWith(ctx, 'messages.enter_name', {
reply_markup: {
resize_keyboard: true,
one_time_keyboard: true,
},
reply_markup,
});
});
});

describe('enterAge', () => {
jest.useFakeTimers();

it('should send enter_age message', async () => {
const replySpy = spyOn(useCases.replyService, 'reply');
const replySpy = jest.spyOn(service, 'reply');
await useCases.enterAge(ctx);
expect(replySpy).toHaveBeenCalledWith(ctx, 'messages.enter_age');
});
});

describe('invalidAge', () => {
jest.useFakeTimers();

it('should send invalid_age message', async () => {
const replySpy = spyOn(useCases.replyService, 'reply');
const replySpy = jest.spyOn(service, 'reply');
await useCases.invalidAge(ctx);
expect(replySpy).toHaveBeenCalledWith(ctx, 'messages.invalid_age');
});
});

describe('sendLocation', () => {
jest.useFakeTimers();

it('should send send_location message', async () => {
const replySpy = spyOn(useCases.replyService, 'reply');
const replySpy = jest.spyOn(service, 'reply');
await useCases.sendLocation(ctx);
expect(replySpy).toHaveBeenCalledWith(ctx, 'messages.send_location');
});
});

describe('sendPicture', () => {
jest.useFakeTimers();

it('should send send_picture message', async () => {
const replySpy = spyOn(useCases.replyService, 'reply');
const replySpy = jest.spyOn(service, 'reply');
await useCases.sendPicture(ctx);
expect(replySpy).toHaveBeenCalledWith(ctx, 'messages.send_picture');
});
});

describe('sendGames', () => {
jest.useFakeTimers();

it('should send send_games message', async () => {
const replySpy = spyOn(useCases.replyService, 'reply');
const replySpy = jest.spyOn(service, 'reply');
await useCases.sendGames(ctx);
expect(replySpy).toHaveBeenCalledWith(ctx, 'messages.send_games');
});
});

describe('invalidGame', () => {
jest.useFakeTimers();

it('should send invalid_game message', async () => {
const replySpy = spyOn(useCases.replyService, 'reply');
const replySpy = jest.spyOn(service, 'reply');
await useCases.invalidGame(ctx);
expect(replySpy).toHaveBeenCalledWith(ctx, 'messages.invalid_game');
});
Expand Down
97 changes: 68 additions & 29 deletions src/use-cases/user/tests/user.use-case.spec.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,92 @@
import { CreateUserDto, IUserService, User } from 'src/core';
import { CreateUserDto, IUserService, UpdateUserDto, User } from 'src/core';
import { UserUseCases } from '../user.use-case';
import { UserFactoryService } from '../user-factory.service';
import { TypeOrmUserService } from 'src/frameworks/user/typeorm/typeorm-user.service';
import { ConfigModule } from '@nestjs/config';
import { Test, TestingModule } from '@nestjs/testing';
import { MockDatabaseModule } from 'src/services/mock-database/mock-database.module';
import { TypeOrmModule } from '@nestjs/typeorm';

// TODO: refactor
describe('UserUseCases', () => {
let userUseCases: UserUseCases;
let userService: IUserService;
let userFactory: UserFactoryService;

beforeEach(() => {
userService = {} as IUserService;
userFactory = {} as UserFactoryService;
userUseCases = new UserUseCases(userService, userFactory);
let useCases: UserUseCases;
let service: IUserService;
let factory: UserFactoryService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
MockDatabaseModule,
TypeOrmModule.forFeature([User]),
ConfigModule.forRoot({
isGlobal: true,
}),
],
providers: [
UserUseCases,
UserFactoryService,
{
provide: IUserService,
useClass: TypeOrmUserService,
},
],
}).compile();

useCases = module.get<UserUseCases>(UserUseCases);
service = module.get<IUserService>(IUserService);
factory = module.get<UserFactoryService>(UserFactoryService);
});

describe('create', () => {
it('should create a new user and return it', async () => {
const dto: CreateUserDto = { name: 'John Doe', age: 30 };
const user: User = { id: 1, name: 'John Doe', age: 30 };
spyOn(userFactory, 'create').and.returnValue(user);
spyOn(userService, 'create').and.returnValue(user);
const result = await userUseCases.create(dto);
expect(userFactory.create).toHaveBeenCalledWith(dto);
expect(userService.create).toHaveBeenCalledWith(user);
const dto: CreateUserDto = { chatId: 123, userId: 312321 };
const user: User = User.create({
...dto,
});

jest.spyOn(factory, 'create').mockReturnValueOnce(user);
jest.spyOn(service, 'create').mockImplementationOnce(async () => user);

const result = await useCases.create(dto);

expect(factory.create).toHaveBeenCalledWith(dto);
expect(service.create).toHaveBeenCalledWith(user);
expect(result).toEqual(user);
});
});

describe('update', () => {
it('should update an existing user and return it', async () => {
const userId = 1;
const dto: UpdateUserDto = { name: 'Jane Doe', age: 35 };
const user: User = { id: 1, name: 'Jane Doe', age: 35 };
spyOn(userFactory, 'update').and.returnValue(user);
spyOn(userService, 'update').and.returnValue(user);
const result = await userUseCases.update(userId, dto);
expect(userFactory.update).toHaveBeenCalledWith(dto);
expect(userService.update).toHaveBeenCalledWith(userId, user);
const dto: UpdateUserDto = { chatId: 123, userId: 312321 };
const user: User = User.create({
...dto,
});

jest.spyOn(factory, 'update').mockReturnValueOnce(user);
jest.spyOn(service, 'update').mockImplementationOnce(async () => user);

const result = await useCases.update(userId, dto);

expect(factory.update).toHaveBeenCalledWith(dto);
expect(service.update).toHaveBeenCalledWith(userId, user);
expect(result).toEqual(user);
});
});

describe('getByTgId', () => {
it('should return a user by their Telegram ID', async () => {
const tgId = 12345;
const user: User = { id: 1, name: 'John Doe', age: 30 };
spyOn(userService, 'findByTgId').and.returnValue(user);
const result = await userUseCases.getByTgId(tgId);
expect(userService.findByTgId).toHaveBeenCalledWith(tgId);
const chatId = 12345;
const user: User = User.create({
chatId,
});

jest
.spyOn(service, 'findByTgId')
.mockImplementationOnce(async () => user);

const result = await useCases.getByTgId(chatId);

expect(service.findByTgId).toHaveBeenCalledWith(chatId);
expect(result).toEqual(user);
});
});
Expand Down

0 comments on commit e23b25f

Please sign in to comment.