tests & endgame logic (start)
This commit is contained in:
parent
08fa0563e7
commit
ced62ddfba
14 changed files with 132 additions and 30 deletions
18
package-lock.json
generated
18
package-lock.json
generated
|
|
@ -41,7 +41,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/schematics": "^10.0.3",
|
"@nestjs/schematics": "^10.0.3",
|
||||||
"@nestjs/testing": "^10.2.8",
|
"@nestjs/testing": "^10.4.7",
|
||||||
"@types/cron": "^2.0.1",
|
"@types/cron": "^2.0.1",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
"@types/jest": "^29.5.8",
|
"@types/jest": "^29.5.8",
|
||||||
|
|
@ -1905,12 +1905,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@nestjs/testing": {
|
"node_modules/@nestjs/testing": {
|
||||||
"version": "10.2.8",
|
"version": "10.4.7",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.4.7.tgz",
|
||||||
"integrity": "sha512-9Kj5IQhM67/nj/MT6Wi2OmWr5YQnCMptwKVFrX1TDaikpY12196v7frk0jVjdT7wms7rV07GZle9I2z0aSjqtQ==",
|
"integrity": "sha512-aS3sQ0v4g8cyHDzW3xJv1+8MiFAkxUNXmnau588IFFI/nBIo/kevLNHNPr85keYekkJ/lwNDW72h8UGg8BYd9w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "2.6.2"
|
"tslib": "2.7.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
|
|
@ -1931,6 +1932,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nestjs/testing/node_modules/tslib": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "0BSD"
|
||||||
|
},
|
||||||
"node_modules/@nestjs/websockets": {
|
"node_modules/@nestjs/websockets": {
|
||||||
"version": "10.2.8",
|
"version": "10.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-10.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-10.2.8.tgz",
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/schematics": "^10.0.3",
|
"@nestjs/schematics": "^10.0.3",
|
||||||
"@nestjs/testing": "^10.2.8",
|
"@nestjs/testing": "^10.4.7",
|
||||||
"@types/cron": "^2.0.1",
|
"@types/cron": "^2.0.1",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
"@types/jest": "^29.5.8",
|
"@types/jest": "^29.5.8",
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { GiveOutAPrizeCommand } from '../commands/give-out-a-prize.command';
|
||||||
import { GameService } from '../game.service';
|
import { GameService } from '../game.service';
|
||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
import { GameQueueTypes } from '../../schemas/game-queue.schema';
|
import { GameQueueTypes } from '../../schemas/game-queue.schema';
|
||||||
|
import {GuestsService} from "../../guests/guests.service";
|
||||||
|
|
||||||
@CommandHandler(GiveOutAPrizeCommand)
|
@CommandHandler(GiveOutAPrizeCommand)
|
||||||
export class GameGiveOutAPrizeCommandHandler
|
export class GameGiveOutAPrizeCommandHandler
|
||||||
|
|
@ -10,11 +11,12 @@ export class GameGiveOutAPrizeCommandHandler
|
||||||
|
|
||||||
private readonly logger = new Logger(GameGiveOutAPrizeCommandHandler.name);
|
private readonly logger = new Logger(GameGiveOutAPrizeCommandHandler.name);
|
||||||
|
|
||||||
constructor(private gameService: GameService) {
|
constructor(private gameService: GameService, private guestService: GuestsService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(command: GiveOutAPrizeCommand): Promise<any> {
|
async execute(command: GiveOutAPrizeCommand): Promise<any> {
|
||||||
this.logger.verbose(`Player winning a prize ${command.telegramId}`);
|
this.logger.verbose(`Player winning a prize ${command.telegramId}`);
|
||||||
|
await this.guestService.incrementPrizeCount(command.telegramId);
|
||||||
return this.gameService.addTaskToGameQueue(
|
return this.gameService.addTaskToGameQueue(
|
||||||
command.telegramId,
|
command.telegramId,
|
||||||
GameQueueTypes.giveOutAPrize,
|
GameQueueTypes.giveOutAPrize,
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ import {MqtMessageModel} from "../messaging/models/mqt-message.model";
|
||||||
import {ConfigService} from "@nestjs/config";
|
import {ConfigService} from "@nestjs/config";
|
||||||
import {StringHelper} from "../helpers/stringhelper";
|
import {StringHelper} from "../helpers/stringhelper";
|
||||||
import {DebuffsConsts} from "../game/entities/debuffs.consts";
|
import {DebuffsConsts} from "../game/entities/debuffs.consts";
|
||||||
import {CreateNewQueueItemCommand} from "../game/commands/create-new-queue-item.command";
|
|
||||||
import {GameQueueTypes} from "../schemas/game-queue.schema";
|
|
||||||
import {VoiceService} from "../voice/voice.service";
|
import {VoiceService} from "../voice/voice.service";
|
||||||
import {screpaDictManyInvalidAnswersDict} from "../voice/dicts/screpa-dict-many-invalid-answers.dict";
|
import {screpaDictManyInvalidAnswersDict} from "../voice/dicts/screpa-dict-many-invalid-answers.dict";
|
||||||
import {GuestPropertiesConsts} from "../schemas/properties.consts";
|
import {GuestPropertiesConsts} from "../schemas/properties.consts";
|
||||||
|
|
@ -66,6 +64,10 @@ export class GuestsService {
|
||||||
return this.guestModel.find().exec();
|
return this.guestModel.find().exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getModel() {
|
||||||
|
return this.guestModel;
|
||||||
|
}
|
||||||
|
|
||||||
async filter(properties: object) {
|
async filter(properties: object) {
|
||||||
return this.guestModel.find(properties).exec();
|
return this.guestModel.find(properties).exec();
|
||||||
}
|
}
|
||||||
|
|
@ -340,4 +342,16 @@ export class GuestsService {
|
||||||
guest.invalidAnswersInRow = 0;
|
guest.invalidAnswersInRow = 0;
|
||||||
await guest.save();
|
await guest.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async incrementPrizeCount(telegramId: number) {
|
||||||
|
const guest = await this.findById(telegramId);
|
||||||
|
guest.rewardsReceived += 1;
|
||||||
|
await guest.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
async updatePenaltiesCount(user: number) {
|
||||||
|
const guest = await this.findById(user);
|
||||||
|
guest.penaltiesReceived += 1;
|
||||||
|
await guest.save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
src/mocks/gift-service.mock.ts
Normal file
3
src/mocks/gift-service.mock.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export const GiftServiceMock = {
|
||||||
|
getRemainingPrizeCount: () => jest.fn(),
|
||||||
|
}
|
||||||
3
src/mocks/quiz-service.mock.ts
Normal file
3
src/mocks/quiz-service.mock.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export const QuizServiceMock = {
|
||||||
|
getRemainQuestionCount: () =>jest.fn(),
|
||||||
|
}
|
||||||
3
src/mocks/shared-service.mock.ts
Normal file
3
src/mocks/shared-service.mock.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export const SharedServiceMock = {
|
||||||
|
sendSocketNotificationToAllClients: jest.fn(),
|
||||||
|
}
|
||||||
3
src/mocks/state-service.mock.ts
Normal file
3
src/mocks/state-service.mock.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export const StateServiceMock = {
|
||||||
|
setState: jest.fn(),
|
||||||
|
}
|
||||||
|
|
@ -50,4 +50,10 @@ export class QuizController {
|
||||||
async dealPrize() {
|
async dealPrize() {
|
||||||
return this.quizService.dealPrize();
|
return this.quizService.dealPrize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('endgame-extrapoints')
|
||||||
|
async endgameExtrapoints()
|
||||||
|
{
|
||||||
|
return await this.quizService.addEndgamePoints();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,11 @@ import {ValidAnswerReceivedEvent} from '../game/events/valid-answer.recieved';
|
||||||
import {QuestionStorage, QuestionStorageDocument,} from '../schemas/question-storage.schema';
|
import {QuestionStorage, QuestionStorageDocument,} from '../schemas/question-storage.schema';
|
||||||
import {WrongAnswerReceivedEvent} from '../game/events/wrong-answer-received.event';
|
import {WrongAnswerReceivedEvent} from '../game/events/wrong-answer-received.event';
|
||||||
import {ProceedGameQueueCommand} from '../game/commands/proceed-game-queue.command';
|
import {ProceedGameQueueCommand} from '../game/commands/proceed-game-queue.command';
|
||||||
import {getRandomInt} from 'src/helpers/rand-number';
|
import {getRandomInt} from '../helpers/rand-number';
|
||||||
import {Messages} from "../messaging/tg.text";
|
import {Messages} from "../messaging/tg.text";
|
||||||
import {CreateNewQueueItemCommand} from "../game/commands/create-new-queue-item.command";
|
import {CreateNewQueueItemCommand} from "../game/commands/create-new-queue-item.command";
|
||||||
import {GameQueueTypes} from "../schemas/game-queue.schema";
|
import {GameQueueTypes} from "../schemas/game-queue.schema";
|
||||||
import {IncreasePlayerWinningRateCommand} from "../game/commands/increase-player-winning-rate.command";
|
import {IncreasePlayerWinningRateCommand} from "../game/commands/increase-player-winning-rate.command";
|
||||||
import {SocketEvents} from "../shared/events.consts";
|
|
||||||
import {IncreasePlayerScoreCommand} from "../guests/command/increase-player-score.command";
|
import {IncreasePlayerScoreCommand} from "../guests/command/increase-player-score.command";
|
||||||
|
|
||||||
@Injectable({ scope: Scope.TRANSIENT })
|
@Injectable({ scope: Scope.TRANSIENT })
|
||||||
|
|
@ -156,10 +155,36 @@ export class QuizService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
targetUser = lastInvalidAnswer.user;
|
targetUser = lastInvalidAnswer.user;
|
||||||
|
await this.guestService.updatePenaltiesCount(lastInvalidAnswer.user);
|
||||||
await this.commandBus.execute(new CreateNewQueueItemCommand(lastInvalidAnswer.user, GameQueueTypes.penalty));
|
await this.commandBus.execute(new CreateNewQueueItemCommand(lastInvalidAnswer.user, GameQueueTypes.penalty));
|
||||||
}
|
}
|
||||||
await this.commandBus.execute(new CreateNewQueueItemCommand(targetUser, GameQueueTypes.showresults));
|
await this.commandBus.execute(new CreateNewQueueItemCommand(targetUser, GameQueueTypes.showresults));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async addEndgamePoints() {
|
||||||
|
const maxInvalidAnswersPromise = this.guestService.getModel().find({}).sort({ ['invalidAnswers']: 'desc'}).exec();
|
||||||
|
const maxRewardsPromise = this.guestService.getModel().find({}).sort({['rewardsReceived']: "desc"}).exec();
|
||||||
|
const maxPenaltiesPromise = this.guestService.getModel().find({}).sort({['penaltiesReceived']: 'desc'}).exec();
|
||||||
|
|
||||||
|
//const { maxRewards, maxInvalidAnswers } = Promise.all([maxRewardsPromise, maxInvalidAnswersPromise]);
|
||||||
|
const [maxRewards, maxInvalidAnswers, maxPenaltiesReceived] = await Promise.all([maxRewardsPromise, maxInvalidAnswersPromise, maxPenaltiesPromise]);
|
||||||
|
return {
|
||||||
|
maxInvalidAnswers: {
|
||||||
|
id: maxInvalidAnswers[0].id,
|
||||||
|
count: maxInvalidAnswers[0].invalidAnswers,
|
||||||
|
name: maxInvalidAnswers[0].name,
|
||||||
|
},
|
||||||
|
maxRewards: {
|
||||||
|
id: maxRewards[0].id,
|
||||||
|
count: maxRewards[0].rewardsReceived,
|
||||||
|
name: maxRewards[0].name,
|
||||||
|
},
|
||||||
|
maxPenalties: {
|
||||||
|
id: maxPenaltiesReceived[0].id,
|
||||||
|
count: maxPenaltiesReceived[0].penaltiesReceived,
|
||||||
|
name: maxPenaltiesReceived[0].name,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getNextQuestion() {
|
private async getNextQuestion() {
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,55 @@
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { SchedulerService } from './scheduler.service';
|
import { SchedulerService } from './scheduler.service';
|
||||||
|
import {GiftsService} from "../gifts/gifts.service";
|
||||||
|
import {GiftServiceMock} from "../mocks/gift-service.mock";
|
||||||
|
import {StateService} from "../state/state.service";
|
||||||
|
import {StateServiceMock} from "../mocks/state-service.mock";
|
||||||
|
import {QuizService} from "../quiz/quiz.service";
|
||||||
|
import {QuizServiceMock} from "../mocks/quiz-service.mock";
|
||||||
|
import {SharedService} from "../shared/shared.service";
|
||||||
|
import {SharedServiceMock} from "../mocks/shared-service.mock";
|
||||||
|
|
||||||
|
|
||||||
describe('SchedulerService', () => {
|
describe('SchedulerService', () => {
|
||||||
let service: SchedulerService;
|
let service: SchedulerService;
|
||||||
|
let giftService: GiftsService;
|
||||||
|
let sharedService: SharedService;
|
||||||
|
let stateService: StateService;
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
jest.clearAllMocks();
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
providers: [SchedulerService],
|
providers: [SchedulerService,
|
||||||
|
{ provide: GiftsService, useValue: GiftServiceMock },
|
||||||
|
{ provide: StateService, useValue: StateServiceMock },
|
||||||
|
{ provide: QuizService, useValue: QuizServiceMock },
|
||||||
|
{ provide: SharedService, useValue: SharedServiceMock },
|
||||||
|
],
|
||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
service = module.get<SchedulerService>(SchedulerService);
|
service = module.get<SchedulerService>(SchedulerService);
|
||||||
|
giftService = module.get<GiftsService>(GiftsService);
|
||||||
|
sharedService = module.get<SharedService>(SharedService);
|
||||||
|
stateService = module.get<StateService>(StateService);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be defined', () => {
|
it('should be defined', () => {
|
||||||
expect(service).toBeDefined();
|
expect(service).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should finish game if prizes count is 0', async () => {
|
||||||
|
const getRemainingPrizeCountFn = jest.spyOn(giftService, 'getRemainingPrizeCount').mockImplementation(() => Promise.resolve(0));
|
||||||
|
const notificationFn = jest.spyOn(sharedService,'sendSocketNotificationToAllClients').mockImplementation();
|
||||||
|
const setStateFn = jest.spyOn(stateService,'setState').mockImplementation((name,newstate) => Promise.resolve({ state: name, value: newstate}));
|
||||||
|
await service.gameStatus();
|
||||||
|
expect(getRemainingPrizeCountFn).toHaveBeenCalled();
|
||||||
|
expect(notificationFn).toHaveBeenCalled();
|
||||||
|
expect(notificationFn).toHaveBeenCalledWith('state_changed', expect.objectContaining({ state: 'main', value: 'finish'}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not finish game if prizes count above 0', async () => {
|
||||||
|
const getRemainingPrizeCountFn = jest.spyOn(giftService, 'getRemainingPrizeCount').mockImplementation(() => Promise.resolve(5));
|
||||||
|
const notificationFn = jest.spyOn(sharedService,'sendSocketNotificationToAllClients').mockImplementation()
|
||||||
|
await service.gameStatus();
|
||||||
|
expect(notificationFn).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,10 @@
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { Cron } from '@nestjs/schedule';
|
import { Cron } from '@nestjs/schedule';
|
||||||
import { StateService } from '../state/state.service';
|
import { StateService } from '../state/state.service';
|
||||||
import {CommandBus, QueryBus} from '@nestjs/cqrs';
|
import { QuizService } from '../quiz/quiz.service';
|
||||||
import { GiftsService } from 'src/gifts/gifts.service';
|
import { GiftsService } from '../gifts/gifts.service';
|
||||||
import { QuizService } from 'src/quiz/quiz.service';
|
import { SharedService } from '../shared/shared.service';
|
||||||
import { SharedService } from 'src/shared/shared.service';
|
|
||||||
import {GetGuestPropertyQuery} from "../guests/command/get-guest-property.handler";
|
|
||||||
import {GuestPropertiesConsts} from "../schemas/properties.consts";
|
|
||||||
import {GetGuestQuery} from "../guests/queries/getguest.query";
|
|
||||||
import {StringHelper} from "../helpers/stringhelper";
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SchedulerService {
|
export class SchedulerService {
|
||||||
private readonly logger = new Logger(SchedulerService.name);
|
private readonly logger = new Logger(SchedulerService.name);
|
||||||
|
|
@ -17,8 +13,6 @@ export class SchedulerService {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private cmdBus: CommandBus,
|
|
||||||
private queryBus: QueryBus,
|
|
||||||
private giftsService: GiftsService,
|
private giftsService: GiftsService,
|
||||||
private quizService: QuizService,
|
private quizService: QuizService,
|
||||||
private sharedService: SharedService,
|
private sharedService: SharedService,
|
||||||
|
|
@ -38,6 +32,7 @@ export class SchedulerService {
|
||||||
const giftsLeft = await this.giftsService.getRemainingPrizeCount();
|
const giftsLeft = await this.giftsService.getRemainingPrizeCount();
|
||||||
if (giftsLeft === 0) {
|
if (giftsLeft === 0) {
|
||||||
const state = await this.stateService.setState('main', 'finish');
|
const state = await this.stateService.setState('main', 'finish');
|
||||||
|
console.log(this.state);
|
||||||
this.sharedService.sendSocketNotificationToAllClients(
|
this.sharedService.sendSocketNotificationToAllClients(
|
||||||
'state_changed',
|
'state_changed',
|
||||||
state,
|
state,
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,6 @@ export class Guest {
|
||||||
@Prop({ default: 10 })
|
@Prop({ default: 10 })
|
||||||
prizeChance: number;
|
prizeChance: number;
|
||||||
@Prop({ default: 0 })
|
@Prop({ default: 0 })
|
||||||
prizesCount: number;
|
|
||||||
@Prop({ default: 0 })
|
|
||||||
validAnswers: number;
|
validAnswers: number;
|
||||||
@Prop({ default: 0 })
|
@Prop({ default: 0 })
|
||||||
invalidAnswers: number;
|
invalidAnswers: number;
|
||||||
|
|
@ -34,6 +32,8 @@ export class Guest {
|
||||||
invalidAnswersInRow: number;
|
invalidAnswersInRow: number;
|
||||||
@Prop({ default:0 })
|
@Prop({ default:0 })
|
||||||
rewardsReceived: number;
|
rewardsReceived: number;
|
||||||
|
@Prop({ default: 0})
|
||||||
|
penaltiesReceived: number;
|
||||||
@Prop({ type: Map })
|
@Prop({ type: Map })
|
||||||
properties: Record<string, string>;
|
properties: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@ export class StateService {
|
||||||
const stateEntity = await this.getState(name);
|
const stateEntity = await this.getState(name);
|
||||||
stateEntity.value = newValue;
|
stateEntity.value = newValue;
|
||||||
await stateEntity.save();
|
await stateEntity.save();
|
||||||
return stateEntity;
|
return {
|
||||||
|
state: stateEntity.state,
|
||||||
|
value: stateEntity.value,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue