Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(players): add bot user #483

Merged
merged 3 commits into from
Jul 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ API_URL=http://localhost:3000
# An URL to where the client is hosted
CLIENT_URL=http://localhost:4200

# The bot name; it can be changed via the web client afterwards
BOT_NAME=tf2pickup.pl

# MongoDB
MONGODB_HOST=localhost
MONGODB_PORT=27017
Expand Down
1 change: 1 addition & 0 deletions src/environment/environment.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe('Environment', () => {
[
'API_URL',
'CLIENT_URL',
'BOT_NAME',
'MONGODB_HOST',
'MONGODB_PORT',
'MONGODB_DB',
Expand Down
4 changes: 4 additions & 0 deletions src/environment/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export class Environment {
return this.configService.get<string>('CLIENT_URL');
}

get botName() {
return this.configService.get<string>('BOT_NAME');
}

get mongoDbHost() {
return this.configService.get<string>('MONGODB_HOST');
}
Expand Down
2 changes: 1 addition & 1 deletion src/players/models/player-role.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export type PlayerRole = 'admin' | 'super-user';
export type PlayerRole = 'admin' | 'super-user' | 'bot';
9 changes: 4 additions & 5 deletions src/players/models/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ import { PlayerRole } from './player-role';
import { TwitchTvUser } from './twitch-tv-user';

@index({ steamId: 'hashed' })
@index({ etf2lProfileId: 1 })
export class Player {
id: string;

@prop({ required: true, unique: true, trim: true })
name!: string;

@prop({ required: true, unique: true })
steamId!: string;
@prop({ unique: true })
steamId?: string;

@prop({ default: () => new Date() })
joinedAt?: Date;
Expand All @@ -23,9 +22,9 @@ export class Player {
role?: PlayerRole;

@prop({ default: false })
hasAcceptedRules!: boolean;
hasAcceptedRules?: boolean;

@prop()
@prop({ index: true })
etf2lProfileId?: number;

@prop({ type: TwitchTvUser })
Expand Down
48 changes: 48 additions & 0 deletions src/players/services/players.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jest.mock('@/discord/services/discord.service');

class EnvironmentStub {
superUser = null;
botName = 'FAKE_BOT_NAME';
}

class Etf2lProfileServiceStub {
Expand Down Expand Up @@ -120,12 +121,43 @@ describe('PlayersService', () => {
expect(service).toBeDefined();
});

describe('#onModuleInit()', () => {
describe('when the bot user is not yet created', () => {
it('should create the bot user', async () => {
await service.onModuleInit();
expect(await playerModel.findOne({ name: 'FAKE_BOT_NAME' })).toBeTruthy();
});
});

describe('when the bot user is already created', () => {
beforeEach(async () => {
await service.onModuleInit();
});

it('should not create any users', async () => {
await service.onModuleInit();
expect((await playerModel.find({ name: 'FAKE_BOT_NAME' })).length).toEqual(1);
});
});
});

describe('#getAll()', () => {
it('should retrieve all players from the database', async () => {
const ret = await service.getAll();
expect(ret.length).toEqual(1);
expect(ret[0].toObject()).toEqual(mockPlayer.toObject());
});

describe('when the bot user is created', () => {
beforeEach(async () => {
await service.onModuleInit();
});

it('should exclude the bot from the player list', async () => {
const ret = await service.getAll();
expect(ret.length).toEqual(1);
});
});
});

describe('#getById()', () => {
Expand Down Expand Up @@ -169,6 +201,22 @@ describe('PlayersService', () => {
});
});

describe('#findBot()', () => {
beforeEach(async () => {
await playerModel.create({
name: 'FAKE_BOT_NAME',
role: 'bot',
})
});

it('should find the bot', async () => {
expect(await service.findBot()).toMatchObject({
name: 'FAKE_BOT_NAME',
role: 'bot',
});
});
});

describe('#createPlayer()', () => {
const mockSteamProfile: SteamProfile = {
provider: 'steam',
Expand Down
20 changes: 17 additions & 3 deletions src/players/services/players.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable, Logger, Inject, forwardRef } from '@nestjs/common';
import { Injectable, Logger, Inject, forwardRef, OnModuleInit } from '@nestjs/common';
import { Environment } from '@/environment/environment';
import { Player } from '../models/player';
import { DocumentType, ReturnModelType } from '@typegoose/typegoose';
Expand All @@ -18,7 +18,7 @@ import { ObjectId } from 'mongodb';
import { minimumTf2InGameHours, requireEtf2lAccount } from '@configs/players';

@Injectable()
export class PlayersService {
export class PlayersService implements OnModuleInit {

private logger = new Logger(PlayersService.name);
private _playerRegistered = new Subject<string>();
Expand All @@ -37,8 +37,18 @@ export class PlayersService {
private discordService: DiscordService,
) { }

async onModuleInit() {
const bot = await this.findBot();
if (bot === null) {
await this.playerModel.create({
name: this.environment.botName,
role: 'bot',
})
}
}

async getAll(): Promise<DocumentType<Player>[]> {
return await this.playerModel.find();
return await this.playerModel.find({ role: { $ne: 'bot' } });
}

async getById(id: string | ObjectId): Promise<DocumentType<Player>> {
Expand All @@ -57,6 +67,10 @@ export class PlayersService {
return await this.playerModel.findOne({ 'twitchTvUser.userId': twitchTvUserId });
}

async findBot() {
return this.playerModel.findOne({ name: this.environment.botName });
}

async createPlayer(steamProfile: SteamProfile): Promise<DocumentType<Player>> {
await this.verifyTf2InGameHours(steamProfile.id);

Expand Down