Skip to content

Commit

Permalink
chore(tests): refactor generated tests, feat(game use cases): add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
havrydotdev committed Oct 17, 2023
1 parent f8f034e commit 4fcc557
Show file tree
Hide file tree
Showing 30 changed files with 478 additions and 18 deletions.
Binary file modified dev.sqlite
Binary file not shown.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 13 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "nest-clean-arch",
"name": "ua-teammates",
"version": "0.0.1",
"description": "",
"author": "",
"description": "Bot for searching teammates for games from Ukraine",
"author": "Havrylenko Ivan",
"private": true,
"license": "UNLICENSED",
"license": "MIT",
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
Expand Down Expand Up @@ -62,10 +62,18 @@
"json",
"ts"
],
"moduleNameMapper": {
"^src/(.*)$": "<rootDir>/$1"
},
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
"^.+\\.(t|j)s$": [
"ts-jest",
{
"isolatedModules": true
}
]
},
"collectCoverageFrom": [
"**/*.(t|j)s"
Expand Down
4 changes: 4 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { UserUseCasesModule } from './use-cases/user';
import { ReplyUseCasesModule } from './use-cases/reply';
import { I18nModule } from './services/i18n/i18n.module';
import { RegisterWizard } from './controllers/register.wizard';
import { GameModule } from './services/game/game.module';
import { GameUseCasesModule } from './use-cases/game';

@Module({
imports: [
Expand All @@ -19,6 +21,8 @@ import { RegisterWizard } from './controllers/register.wizard';
UserUseCasesModule,
ReplyModule,
ReplyUseCasesModule,
GameModule,
GameUseCasesModule,
I18nModule,
],
providers: [AppUpdate, RegisterWizard],
Expand Down
108 changes: 105 additions & 3 deletions src/controllers/register.wizard.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import { Ctx, Message, On, Wizard, WizardStep } from 'nestjs-telegraf';
import { Game } from 'src/core';
import { REGISTER_WIZARD_ID } from 'src/core/constants';
import { GameUseCases } from 'src/use-cases/game';
import { ReplyUseCases } from 'src/use-cases/reply';
import { UserUseCases } from 'src/use-cases/user/user.use-case';
import { UserUseCases } from 'src/use-cases/user';
import { Context } from 'telegraf/typings';
import { Message as MessageType } from 'telegraf/typings/core/types/typegram';
import { WizardContext } from 'telegraf/typings/scenes';

@Wizard(REGISTER_WIZARD_ID)
export class RegisterWizard {
private games: Game[];

constructor(
private readonly userUseCases: UserUseCases,
private readonly replyUseCases: ReplyUseCases,
) {}
private readonly gameUseCases: GameUseCases,
) {
this.gameUseCases.findAll().then((games: Game[]) => {
this.games = games;
});
}

@WizardStep(1)
async onEnter(@Ctx() ctx: Context & WizardContext) {
Expand All @@ -29,6 +39,98 @@ export class RegisterWizard {

ctx.wizard.next();

// await this.replyUseCases.enterSurname(ctx);
await this.replyUseCases.enterAge(ctx);
}

@On('text')
@WizardStep(3)
async onAge(
@Ctx() ctx: Context & WizardContext,
@Message() msg: { text: string },
) {
const age = parseInt(msg.text);

if (isNaN(age)) {
await this.replyUseCases.invalidAge(ctx);

return;
}

ctx.wizard.state['age'] = age;

ctx.wizard.next();

await this.replyUseCases.sendLocation(ctx);
}

@On('text')
@WizardStep(4)
async onLocation(
@Ctx() ctx: Context & WizardContext,
@Message() msg: { text: string },
) {
const location = msg.text;

ctx.wizard.state['location'] = location;

ctx.wizard.next();

await this.replyUseCases.sendGames(ctx);
}

@On('text')
@WizardStep(5)
async onGame(
@Ctx() ctx: Context & WizardContext,
@Message() msg: { text: string },
) {
if (msg.text === '✅') {
ctx.wizard.next();

return;
}

const game = this.games.find((game) => game.title === msg.text);
if (!game) {
await this.replyUseCases.invalidGame(ctx);

return;
}

ctx.wizard.state['games'].push(game.id);

await this.replyUseCases.sendPicture(ctx);
}

@On('photo')
@WizardStep(6)
async onPhoto(
@Ctx()
ctx: Context & WizardContext,
@Message() msg: MessageType.PhotoMessage,
) {
const imageId = msg.photo.pop().file_id;

ctx.wizard.state['photo'] = imageId;

ctx.wizard.next();
}

@WizardStep(7)
async onDone(
@Ctx()
ctx: Context &
WizardContext & {
wizard: {
state: {
name: string;
location: string;
age: number;
games: number[];
};
};
},
) {
console.log(ctx.wizard.state);
}
}
7 changes: 7 additions & 0 deletions src/core/abstracts/game.abstract.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Game } from '../entities';

abstract class IGameService {
abstract findAll(): Promise<Game[]>;
}

export { IGameService };
2 changes: 2 additions & 0 deletions src/core/abstracts/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from './profile.abstract.service';
export * from './user.abstract.service';
export * from './game.abstract.service';
export * from './reply.abstract.service';
2 changes: 1 addition & 1 deletion src/core/abstracts/profile.abstract.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ abstract class IProfileService {

abstract findByUser(userId: number): Promise<void>;

abstract findRecommended(user: User): Promise<void>;
abstract findRecommended(user: User, skip: number): Promise<void>;
}

export { IProfileService };
2 changes: 2 additions & 0 deletions src/frameworks/game/typeorm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './typeorm-game.module';
export * from './typeorm-game.service';
17 changes: 17 additions & 0 deletions src/frameworks/game/typeorm/typeorm-game.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Game } from 'src/core';
import { TypeOrmGameService } from './typeorm-game.service';
import { IGameService } from 'src/core/abstracts/game.abstract.service';

@Module({
imports: [TypeOrmModule.forFeature([Game])],
providers: [
{
provide: IGameService,
useClass: TypeOrmGameService,
},
],
exports: [IGameService],
})
export class TypeOrmGameModule {}
16 changes: 16 additions & 0 deletions src/frameworks/game/typeorm/typeorm-game.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Game } from 'src/core';
import { IGameService } from 'src/core/abstracts/game.abstract.service';
import { Repository } from 'typeorm';

@Injectable()
export class TypeOrmGameService implements IGameService {
constructor(
@InjectRepository(Game) private readonly gameRepo: Repository<Game>,
) {}

async findAll(): Promise<Game[]> {
return this.gameRepo.find();
}
}
Empty file.
Empty file.
30 changes: 30 additions & 0 deletions src/frameworks/profile/typeorm/typeorm-profile.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Injectable } from '@nestjs/common';
import {
CreateProfileDto,
IProfileService,
UpdateProfileDto,
User,
} from 'src/core';

@Injectable()
export class TypeOrmProfileService implements IProfileService {
async createProfile(dto: CreateProfileDto): Promise<void> {
throw new Error('Method not implemented.');
}

async updateProfile(dto: UpdateProfileDto): Promise<void> {
throw new Error('Method not implemented.');
}

async deleteProfile(id: number): Promise<void> {
throw new Error('Method not implemented.');
}

async findByUser(userId: number): Promise<void> {
throw new Error('Method not implemented.');
}

async findRecommended(user: User, skip: number): Promise<void> {
throw new Error('Method not implemented.');
}
}
6 changes: 6 additions & 0 deletions src/generated/i18n.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ export type I18nTranslations = {
"new_user": string;
"update_lang": string;
"enter_name": string;
"enter_age": string;
"invalid_age": string;
"send_picture": string;
"send_location": string;
"send_games": string;
"invalid_game": string;
};
};
export type I18nPath = Path<I18nTranslations>;
8 changes: 7 additions & 1 deletion src/i18n/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@
"select_lang": "Firstly, select interface language",
"new_user": "Let's start with creating your profile",
"update_lang": "Select new interface language",
"enter_name": "Enter your name"
"enter_name": "Enter your name",
"enter_age": "Enter your age",
"invalid_age": "Please, enter valid age",
"send_picture": "Send photo for your profile",
"send_location": "Send city you live in",
"send_games": "Send games you play",
"invalid_game": "Please, enter valid game"
}
8 changes: 7 additions & 1 deletion src/i18n/ru/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@
"select_lang": "пішовнахуйпішовнахуйпішовнахуй",
"new_user": "пішовнахуйпішовнахуй",
"update_lang": "пішовнахуйпішовнахуйпішовнахуй",
"enter_name": "пішовнахуйпішовнахуйпішовнахуйпішовнахуйпішовнахуй"
"enter_name": "пішовнахуйпішовнахуйпішовнахуйпішовнахуйпішовнахуй",
"enter_age": "пішовнахуйпішовнахуйпішовнахуй",
"invalid_age": "пішовнахуйпішовнахуйпішовнахуй",
"send_picture": "пішовнахуйпішовнахуйпішовнахуй",
"send_location": "пішовнахуйпішовнахуйпішовнахуй",
"send_games": "пішовнахуйпішовнахуйпішовнахуй",
"invalid_game": "пішовнахуйпішовнахуйпішовнахуй"
}
8 changes: 7 additions & 1 deletion src/i18n/ua/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@
"select_lang": "Спочатку, обери мову інтерфейсу:",
"update_lang": "Обери нову мову інтерфейсу:",
"new_user": "Тепер, давай заповнимо твій профіль",
"enter_name": "Введи своє ім'я"
"enter_name": "Введи своє ім'я",
"enter_age": "Введи свій вік",
"invalid_age": "Вік повинен бути числом",
"send_picture": "Тепер, надішли мені фото для твого профілю",
"send_location": "Введи назву населенного пункту, в якому ти живеш",
"send_games": "Майже готово! Тепер, обери ігри, в які ти граєш",
"invalid_game": "Ця гра не існує або не підтримується"
}
2 changes: 1 addition & 1 deletion src/services/database/database.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
host: config.get<string>('DB_HOST'),
password: config.get<string>('DB_PASSWORD'),
synchronize: config.get<string>('DB_SYNCHRONIZE') === 'true',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
};
},
inject: [ConfigService],
Expand Down
8 changes: 8 additions & 0 deletions src/services/game/game.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Module } from '@nestjs/common';
import { TypeOrmGameModule } from 'src/frameworks/game/typeorm';

@Module({
imports: [TypeOrmGameModule],
exports: [TypeOrmGameModule],
})
export class GameModule {}
17 changes: 17 additions & 0 deletions src/services/mock-database/mock-database.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
TypeOrmModule.forRoot({
type: 'better-sqlite3',
database: ':memory:',
entities: [__dirname + '/../../../**/*.entity{.ts,.js}'],
}),
],
})
export class MockDatabaseModule {}
4 changes: 2 additions & 2 deletions src/types/telegraf.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { Context } from 'telegraf';
import { Language } from 'src/core/enums';

declare module 'telegraf/typings' {
export interface Context extends CustomSessionContext, CustomSceneContext {}
interface Context extends CustomSessionContext, CustomSceneContext {}
}

declare module 'telegraf/typings/scenes' {
export interface WizardContext extends CustomSessionContext {}
interface WizardContext extends CustomSessionContext {}
}

interface CustomSessionContext {
Expand Down
Loading

0 comments on commit 4fcc557

Please sign in to comment.