Skip to content

Commit

Permalink
Merge pull request #492 from bounswe/feature/BE/474/follow-info-for-g…
Browse files Browse the repository at this point in the history
…ame-list

added follow info for game list
  • Loading branch information
melihgezerr authored Nov 21, 2023
2 parents f746f6b + 7166b25 commit 3188462
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 3 deletions.
13 changes: 13 additions & 0 deletions ludos/backend/src/controllers/game.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
HttpStatus,
NotFoundException,
Param,
ParseBoolPipe,
ParseIntPipe,
Post,
Put,
Expand Down Expand Up @@ -139,12 +140,20 @@ export class GameController {
description: 'ASC or DESC. Default is ASC',
example: 'ASC',
})
@ApiQuery({
name: 'isFollowed',
required: false,
description: 'Filter by followed games. If false no filter is applied',
example: 'true',
})
@ApiOkResponse({
type: GamePageResponseDto,
})
@ApiBearerAuth()
@UseInterceptors(new SerializerInterceptor(GamePageResponseDto))
@Get()
public async listGames(
@Req() req: AuthorizedRequest,
@Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number = 1,
@Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit: number = 10,
@Query('searchKey') searchKey?: string,
Expand All @@ -154,6 +163,8 @@ export class GameController {
@Query('developer') developer?: string,
@Query('orderByKey') orderByKey?: keyof Game,
@Query('order') order?: 'ASC' | 'DESC',
@Query('isFollowed', new DefaultValuePipe(false), ParseBoolPipe)
isFollowed?: boolean,
) {
return await this.gameService.listGames(
page,
Expand All @@ -165,6 +176,8 @@ export class GameController {
developer,
orderByKey,
order,
req.user && req.user.id,
isFollowed,
);
}
}
3 changes: 3 additions & 0 deletions ludos/backend/src/dtos/game/response/list.response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,7 @@ export class GameListResponseDto {
@Expose()
@ApiProperty()
ageRestriction: string;
@Expose()
@ApiProperty()
isFollowed?: boolean;
}
37 changes: 35 additions & 2 deletions ludos/backend/src/repositories/game.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export class GameRepository extends Repository<Game> {
developer?: string,
orderByKey: keyof Game = 'id',
order: 'ASC' | 'DESC' = 'ASC',
userId?: string, // This is not the creator, this is used for follow check
isFollowed?: boolean,
): Promise<Pagination<Game, IPaginationMeta>> {
const queryBuilder = this.createQueryBuilder('games').where('1=1');
if (searchKey) {
Expand All @@ -58,10 +60,41 @@ export class GameRepository extends Repository<Game> {
if (developer) {
queryBuilder.andWhere('games.developer = :developer', { developer });
}
if (userId && isFollowed) {
const subQuery = this.createQueryBuilder()
.select('1')
.from('game_user_follows', 'guf')
.where(`guf.usersId = '${userId}'`)
.andWhere('guf.gamesId = games.id')
.getQuery();
queryBuilder.andWhere(`EXISTS (${subQuery})`);
}
if (orderByKey) {
queryBuilder.orderBy(`games_${orderByKey}`, order);
}
const games = await paginate<Game>(queryBuilder, { page, limit });
return games;
const paginationResult = await paginate<Game>(queryBuilder, {
page,
limit,
});
if (userId) {
await Promise.all(
paginationResult.items.map(async (game) => {
game.isFollowed = await this.checkIfGameIsFollowed(game.id, userId);
}),
);
}
return paginationResult;
}
private async checkIfGameIsFollowed(
gameId: string,
userId: string,
): Promise<boolean> {
const result = await this.createQueryBuilder()
.select('1')
.from('game_user_follows', 'guf')
.where(`guf.usersId = '${userId}'`)
.andWhere('guf.gamesId = :gameId', { gameId })
.getExists();
return result ? true : false;
}
}
4 changes: 4 additions & 0 deletions ludos/backend/src/services/game.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ export class GameService {
developer?: string,
orderByKey?: keyof Game,
order?: 'ASC' | 'DESC',
userId?: string,
isFollowed?: boolean,
): Promise<Pagination<Game, IPaginationMeta>> {
const tagList = tags ? tags.split(',') : undefined;
const platformList = platforms ? platforms.split(',') : undefined;
Expand All @@ -110,6 +112,8 @@ export class GameService {
developer,
orderByKey,
order,
userId,
isFollowed,
);
}
}
6 changes: 5 additions & 1 deletion ludos/backend/test/game.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { User } from '../src/entities/user.entity';
import { GameRepository } from '../src/repositories/game.repository';
import { UserRepository } from '../src/repositories/user.repository';
import { GameService } from '../src/services/game.service';
import { AuthorizedRequest } from '../src/interfaces/common/authorized-request.interface';
import { RatingRepository } from '../src/repositories/rating.repository';
describe('GameController', () => {
let gameController: GameController;
Expand Down Expand Up @@ -189,7 +190,8 @@ describe('GameController', () => {
const listSpy = jest
.spyOn(gameRepository, 'findGames')
.mockResolvedValue(listResponse);
const response = await gameController.listGames();
const req = {}
const response = await gameController.listGames(req as AuthorizedRequest);
expect(response).toBe(listResponse);
expect(listSpy).toHaveBeenCalledWith(
1,
Expand All @@ -201,6 +203,8 @@ describe('GameController', () => {
undefined,
undefined,
undefined,
undefined,
undefined
);
});
});
Expand Down

0 comments on commit 3188462

Please sign in to comment.