finish unit tests

main
Ayush Mukherjee 2 years ago
parent 41d1a5071b
commit 06ec629862

@ -11,8 +11,6 @@
- [x] add 100 pts - [x] add 100 pts
- [x] get standings - [x] get standings
- [x] get user score history - [x] get user score history
- [x] controller tests
## additional notes - [x] user
- [x] rank
- unit tests
- eslint

@ -24,5 +24,4 @@ import { RankModule } from './rank/rank.module';
RankModule, RankModule,
], ],
}) })
export class AppModule {} export class AppModule {}

@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthController } from './auth.controller';
describe('AuthController', () => {
let controller: AuthController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AuthController],
}).compile();
controller = module.get<AuthController>(AuthController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

@ -1,6 +1,5 @@
import { Body, Controller, Post, Req, UseGuards } from '@nestjs/common'; import { Body, Controller, Post, Req, UseGuards } from '@nestjs/common';
import * as bcrypt from 'bcrypt'; import * as bcrypt from 'bcrypt';
import { Request } from 'express';
import { CreateUserDto } from 'src/user/dtos/CreateUserDto'; import { CreateUserDto } from 'src/user/dtos/CreateUserDto';
import { UserService } from 'src/user/user.service'; import { UserService } from 'src/user/user.service';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
@ -8,10 +7,9 @@ import { LocalAuthGuard } from './local-auth.guard';
@Controller('auth') @Controller('auth')
export class AuthController { export class AuthController {
constructor( constructor(
private userService: UserService, private userService: UserService,
private authService: AuthService private authService: AuthService,
) {} ) {}
@UseGuards(LocalAuthGuard) @UseGuards(LocalAuthGuard)
@ -25,5 +23,4 @@ export class AuthController {
user.password = await bcrypt.hash(user.password, 10); user.password = await bcrypt.hash(user.password, 10);
this.userService.create(user); this.userService.create(user);
} }
} }

@ -22,14 +22,10 @@ import { JwtStrategy } from './jwt.strategy';
expiresIn: configService.get<string>('JWT_EXPIRY'), expiresIn: configService.get<string>('JWT_EXPIRY'),
}, },
}; };
} },
}), }),
], ],
providers: [ providers: [AuthService, LocalStrategy, JwtStrategy],
AuthService, controllers: [AuthController],
LocalStrategy,
JwtStrategy,
],
controllers: [AuthController]
}) })
export class AuthModule {} export class AuthModule {}

@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from './auth.service';
describe('AuthService', () => {
let service: AuthService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AuthService],
}).compile();
service = module.get<AuthService>(AuthService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

@ -7,13 +7,12 @@ import { JwtService } from '@nestjs/jwt';
export class AuthService { export class AuthService {
constructor( constructor(
private userService: UserService, private userService: UserService,
private jwtService: JwtService private jwtService: JwtService,
) {} ) {}
async validate(email: string, password: string): Promise<any> { async validate(email: string, password: string): Promise<any> {
const user = await this.userService.findByEmail(email); const user = await this.userService.findByEmail(email);
if (user && if (user && bcrypt.compare(password, user.password)) {
bcrypt.compare(password, user.password)) {
const { password, ...result } = user; const { password, ...result } = user;
return result; return result;
} }

@ -1,5 +1,5 @@
import { Injectable } from "@nestjs/common"; import { Injectable } from '@nestjs/common';
import { AuthGuard } from "@nestjs/passport"; import { AuthGuard } from '@nestjs/passport';
@Injectable() @Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {} export class JwtAuthGuard extends AuthGuard('jwt') {}

@ -1,7 +1,7 @@
import { Injectable } from "@nestjs/common"; import { Injectable } from '@nestjs/common';
import { ConfigService } from "@nestjs/config"; import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from "@nestjs/passport"; import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from "passport-jwt"; import { ExtractJwt, Strategy } from 'passport-jwt';
@Injectable() @Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) { export class JwtStrategy extends PassportStrategy(Strategy) {

@ -1,5 +1,5 @@
import { Injectable } from "@nestjs/common"; import { Injectable } from '@nestjs/common';
import { AuthGuard } from "@nestjs/passport"; import { AuthGuard } from '@nestjs/passport';
@Injectable() @Injectable()
export class LocalAuthGuard extends AuthGuard('local') {} export class LocalAuthGuard extends AuthGuard('local') {}

@ -7,7 +7,7 @@ import { AuthService } from './auth.service';
export class LocalStrategy extends PassportStrategy(Strategy) { export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) { constructor(private authService: AuthService) {
super({ super({
usernameField: 'email' usernameField: 'email',
}); });
} }

@ -1,13 +1,46 @@
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { RankController } from './rank.controller'; import { RankController } from './rank.controller';
import { RankService } from './rank.service';
describe('RankController', () => { describe('RankController', () => {
let controller: RankController; let controller: RankController;
const mockRankList = [];
const mockRank = {
id: `${Date.now()}`,
points: 100,
createdAt: Date.now(),
updatedAt: Date.now(),
userId: `${Date.now()}`,
};
mockRankList.push(mockRank);
const mockRankService = {
findRankList: jest.fn(() => mockRankList),
findByUserLatest: jest.fn((_: string) => mockRank),
findByUser: jest.fn((_: string) => mockRankList),
create: jest.fn((pts: number) => ({
...mockRank,
points: mockRank.points + pts
})),
};
const mockGuard = {
canActivate: jest.fn(() => true)
};
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
controllers: [RankController], controllers: [RankController],
}).compile(); providers: [RankService],
}).overrideProvider(RankService)
.useValue(mockRankService)
.overrideGuard(JwtAuthGuard)
.useValue(mockGuard)
.compile();
controller = module.get<RankController>(RankController); controller = module.get<RankController>(RankController);
}); });
@ -15,4 +48,46 @@ describe('RankController', () => {
it('should be defined', () => { it('should be defined', () => {
expect(controller).toBeDefined(); expect(controller).toBeDefined();
}); });
it('should return rank list', () => {
expect(controller.getRankList()).toEqual(mockRankList);
});
it('should get latest score of user', () => {
expect(controller.getUserRank(mockRank.userId)).toEqual(mockRank);
});
it('should get user rank history', () => {
expect(controller.getUserHistory(mockRank.userId)).toEqual(mockRankList);
});
it('should create new rank and add 20 points', () => {
const req = {
user: { id: mockRank.id },
};
expect(controller.add20Points(req)).toEqual({
...mockRank,
points: 120,
});
});
it('should create new rank and add 60 points', () => {
const req = {
user: { id: mockRank.id },
};
expect(controller.add60Points(req)).toEqual({
...mockRank,
points: 160,
});
});
it('should create new rank and add 100 points', () => {
const req = {
user: { id: mockRank.id },
};
expect(controller.add100Points(req)).toEqual({
...mockRank,
points: 200,
});
});
}); });

@ -1,6 +1,5 @@
import { Controller, Get, Param, Post, Req, UseGuards } from '@nestjs/common'; import { Controller, Get, Param, Post, Req, UseGuards } from '@nestjs/common';
import { Request } from 'express'; import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';
import { Rank } from './rank.model'; import { Rank } from './rank.model';
import { RankService } from './rank.service'; import { RankService } from './rank.service';
@ -9,37 +8,37 @@ export class RankController {
constructor(private rankService: RankService) {} constructor(private rankService: RankService) {}
@Get() @Get()
async getRankList(): Promise<Rank[]> { getRankList(): Promise<Rank[]> {
return this.rankService.findRankList(); return this.rankService.findRankList();
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get('/:id') @Get('/:id')
async getUserRank(@Param('id') userId: string): Promise<Rank> { getUserRank(@Param('id') userId: string): Promise<Rank> {
return this.rankService.findByUserLatest(userId); return this.rankService.findByUserLatest(userId);
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get('/:id/all') @Get('/:id/all')
async getUserHistory(@Param('id') userId: string): Promise<Rank[]> { getUserHistory(@Param('id') userId: string): Promise<Rank[]> {
return this.rankService.findByUser(userId); return this.rankService.findByUser(userId);
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/add/20') @Post('/add/20')
async add20Points(@Req() req): Promise<any> { add20Points(@Req() req): Promise<Rank> {
this.rankService.create(20, req.user.id); return this.rankService.create(20, req.user.id);
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/add/60') @Post('/add/60')
async add60Points(@Req() req): Promise<void> { add60Points(@Req() req): Promise<Rank> {
this.rankService.create(60, req.user.id); return this.rankService.create(60, req.user.id);
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/add/100') @Post('/add/100')
async add100Points(@Req() req): Promise<void> { add100Points(@Req() req): Promise<Rank> {
this.rankService.create(100, req.user.id); return this.rankService.create(100, req.user.id);
} }
} }

@ -1,5 +1,17 @@
import { BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Model, NotEmpty, PrimaryKey, Table, UpdatedAt } from "sequelize-typescript"; import {
import { User } from "src/user/user.model"; BelongsTo,
Column,
CreatedAt,
DataType,
Default,
ForeignKey,
Model,
NotEmpty,
PrimaryKey,
Table,
UpdatedAt,
} from 'sequelize-typescript';
import { User } from '../user/user.model';
@Table({ @Table({
timestamps: true, timestamps: true,

@ -5,10 +5,8 @@ import { SequelizeModule } from '@nestjs/sequelize';
import { Rank } from './rank.model'; import { Rank } from './rank.model';
@Module({ @Module({
imports: [ imports: [SequelizeModule.forFeature([Rank])],
SequelizeModule.forFeature([Rank]),
],
providers: [RankService], providers: [RankService],
controllers: [RankController] controllers: [RankController],
}) })
export class RankModule {} export class RankModule {}

@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { RankService } from './rank.service';
describe('RankService', () => {
let service: RankService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [RankService],
}).compile();
service = module.get<RankService>(RankService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

@ -2,23 +2,22 @@ import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize'; import { InjectModel } from '@nestjs/sequelize';
import { Op } from 'sequelize'; import { Op } from 'sequelize';
import { col, fn } from 'sequelize'; import { col, fn } from 'sequelize';
import { User } from 'src/user/user.model'; import { User } from '../user/user.model';
import { Rank } from './rank.model'; import { Rank } from './rank.model';
@Injectable() @Injectable()
export class RankService { export class RankService {
constructor( constructor(@InjectModel(Rank) private rankModel: typeof Rank) {}
@InjectModel(Rank) private rankModel: typeof Rank
) {}
async create(points, userId): Promise<Rank> { async create(points, userId): Promise<Rank> {
const rank = await this.findByUserLatest(userId);
return this.rankModel.create({ return this.rankModel.create({
points, points: rank ? rank.points + points : points,
userId userId,
}); });
} }
async findAll(): Promise<Rank[]>{ async findAll(): Promise<Rank[]> {
return this.rankModel.findAll(); return this.rankModel.findAll();
} }
@ -40,29 +39,29 @@ export class RankService {
} }
async findRankList(): Promise<Rank[]> { async findRankList(): Promise<Rank[]> {
return this.rankModel.findAll({ return this.rankModel
attributes: [ .findAll({
'id', attributes: ['id', [fn('MAX', col('createdAt')), 'mDate'], 'userId'],
[fn('MAX', col('createdAt')), 'mDate'],
'userId',
],
group: ['userId'], group: ['userId'],
}).then((res) => { })
.then((res) => {
const maxIds = []; const maxIds = [];
res.forEach(r => { res.forEach((r) => {
maxIds.push(r.id); maxIds.push(r.id);
}); });
return this.rankModel.findAll({ return this.rankModel.findAll({
attributes: ['id', 'points'], attributes: ['id', 'points'],
where: { where: {
id: { id: {
[Op.in]: maxIds [Op.in]: maxIds,
}, },
}, },
include: [{ include: [
{
model: User, model: User,
attributes: ['name'], attributes: ['name'],
}], },
],
}); });
}); });
} }

@ -1,13 +1,32 @@
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
import { UserController } from './user.controller'; import { UserController } from './user.controller';
import { UserService } from './user.service';
describe('UserController', () => { describe('UserController', () => {
let controller: UserController; let controller: UserController;
const mockUsers = [
{
id: `${Date.now()}`,
name: 'User 1',
email: 'email1@email.com',
createdAt: Date.now(),
updatedAt: Date.now(),
},
];
const mockUserService = {
findAll: jest.fn(() => mockUsers),
};
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
controllers: [UserController], controllers: [UserController],
}).compile(); providers: [UserService],
})
.overrideProvider(UserService)
.useValue(mockUserService)
.compile();
controller = module.get<UserController>(UserController); controller = module.get<UserController>(UserController);
}); });
@ -15,4 +34,8 @@ describe('UserController', () => {
it('should be defined', () => { it('should be defined', () => {
expect(controller).toBeDefined(); expect(controller).toBeDefined();
}); });
it('should return all users', () => {
expect(controller.findAll()).toEqual(mockUsers);
});
}); });

@ -4,7 +4,6 @@ import { UserService } from './user.service';
@Controller('user') @Controller('user')
export class UserController { export class UserController {
constructor(private userService: UserService) {} constructor(private userService: UserService) {}
@Get() @Get()

@ -1,5 +1,16 @@
import { Column, Model, Table, CreatedAt, UpdatedAt, PrimaryKey, DataType, NotEmpty, Default, HasMany } from 'sequelize-typescript'; import {
import { Rank } from 'src/rank/rank.model'; Column,
Model,
Table,
CreatedAt,
UpdatedAt,
PrimaryKey,
DataType,
NotEmpty,
Default,
HasMany,
} from 'sequelize-typescript';
import { Rank } from '../rank/rank.model';
@Table({ @Table({
timestamps: true, timestamps: true,

@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserService } from './user.service';
describe('UserService', () => {
let service: UserService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserService],
}).compile();
service = module.get<UserService>(UserService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

@ -7,7 +7,7 @@ import { User } from './user.model';
export class UserService { export class UserService {
constructor( constructor(
@InjectModel(User) @InjectModel(User)
private userModel: typeof User private userModel: typeof User,
) {} ) {}
async create(data: CreateUserDto) { async create(data: CreateUserDto) {
@ -19,7 +19,7 @@ export class UserService {
return { return {
id, id,
name name,
}; };
} }

@ -1,24 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});
Loading…
Cancel
Save