Skip to content

Commit

Permalink
feat(statistics): add game launch time spans stats (#1357)
Browse files Browse the repository at this point in the history
  • Loading branch information
garrappachc authored Nov 12, 2021
1 parent 2c39f3d commit e7e6b96
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/games/services/game-event-handler.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ jest.mock('@nestjs/config');
jest.mock('./game-runtime.service');
jest.mock('./games.service');

function flushPromises() {
return new Promise((resolve) => setImmediate(resolve));
}

describe('GameEventHandlerService', () => {
let service: GameEventHandlerService;
let mongod: MongoMemoryServer;
Expand Down Expand Up @@ -147,7 +151,9 @@ describe('GameEventHandlerService', () => {
await service.onMatchEnded(mockGame.id);

jest.advanceTimersByTime(5000);
await flushPromises();
jest.advanceTimersByTime(serverCleanupDelay);
await flushPromises();
expect(gameRuntimeService.cleanupServer).toHaveBeenCalledWith(
gameServerId.toString(),
);
Expand Down
32 changes: 32 additions & 0 deletions src/statistics/controllers/statistics.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,36 @@ describe('StatisticsController', () => {
]);
});
});

describe('#getGameLaunchDays()', () => {
beforeEach(() => {
statisticsService.getGameLaunchTimeSpans.mockResolvedValue([
{
dayOfWeek: 5,
timeOfTheDay: 'afternoon',
count: 1,
},
{
dayOfWeek: 5,
timeOfTheDay: 'evening',
count: 2,
},
]);
});

it('should return game launch time spans stats', async () => {
expect(await controller.getGameLaunchDays()).toEqual([
{
dayOfWeek: 5,
timeOfTheDay: 'afternoon',
count: 1,
},
{
dayOfWeek: 5,
timeOfTheDay: 'evening',
count: 2,
},
]);
});
});
});
5 changes: 5 additions & 0 deletions src/statistics/controllers/statistics.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ export class StatisticsController {
async getPlayedMapsCount() {
return await this.statisticsService.getPlayedMapsCount();
}

@Get('game-launch-time-spans')
async getGameLaunchDays() {
return await this.statisticsService.getGameLaunchTimeSpans();
}
}
11 changes: 11 additions & 0 deletions src/statistics/interfaces/game-launch-time-span.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
type TimeOfTheDay =
| 'morning' /* 06-12 */
| 'afternoon' /* 12-18 */
| 'evening' /* 18-24 */
| 'night' /* 24-06 */;

export interface GameLaunchTimeSpan {
dayOfWeek: number; // day of the week as a number between 1 (Sunday) and 7 (Saturday)
timeOfTheDay: TimeOfTheDay;
count: number;
}
36 changes: 36 additions & 0 deletions src/statistics/services/statistics.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,40 @@ describe('StatisticsService', () => {
]);
});
});

describe('#getGameLaunchTimeSpans()', () => {
beforeEach(async () => {
await gameModel.create([
{
number: 1,
launchedAt: new Date(2021, 10, 11, 13, 0),
map: 'cp_process_f7',
},
{
number: 2,
launchedAt: new Date(2021, 10, 11, 19, 0),
map: 'cp_process_f7',
},
{
number: 3,
launchedAt: new Date(2021, 10, 11, 22, 0),
map: 'cp_process_f7',
},
]);

process.env.TZ = 'GMT';
});

it('should return game launch time spans', async () => {
const ret = await service.getGameLaunchTimeSpans();
expect(
ret.find((r) => r.dayOfWeek === 5 && r.timeOfTheDay === 'afternoon')
.count,
).toBe(1);
expect(
ret.find((r) => r.dayOfWeek === 5 && r.timeOfTheDay === 'evening')
.count,
).toBe(2);
});
});
});
96 changes: 96 additions & 0 deletions src/statistics/services/statistics.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Game, GameDocument } from '@/games/models/game';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { GameLaunchTimeSpan } from '../interfaces/game-launch-time-span';
import { PlayedMapCount } from '../interfaces/played-map-count';

@Injectable()
Expand All @@ -26,4 +27,99 @@ export class StatisticsService {
{ $sort: { count: -1 } },
]);
}

async getGameLaunchTimeSpans(): Promise<GameLaunchTimeSpan[]> {
const timezone = process.env.TZ ?? 'GMT';
return await this.gameModel.aggregate([
{
$project: {
dayOfWeek: {
$dayOfWeek: {
date: '$launchedAt',
timezone,
},
},
timeOfTheDay: {
$switch: {
branches: [
{
case: {
$in: [
{
$hour: {
date: '$launchedAt',
timezone,
},
},
[6, 7, 8, 9, 10, 11],
],
},
then: 'morning',
},
{
case: {
$in: [
{
$hour: {
date: '$launchedAt',
timezone,
},
},
[12, 13, 14, 15, 16, 17],
],
},
then: 'afternoon',
},
{
case: {
$in: [
{
$hour: {
date: '$launchedAt',
timezone,
},
},
[18, 19, 20, 21, 22, 23],
],
},
then: 'evening',
},
{
case: {
$in: [
{
$hour: {
date: '$launchedAt',
timezone,
},
},
[0, 1, 2, 3, 4, 5],
],
},
then: 'night',
},
],
},
},
},
},
{
$group: {
_id: {
dayOfWeek: '$dayOfWeek',
timeOfTheDay: '$timeOfTheDay',
},
count: { $sum: 1 },
},
},
{
$project: {
dayOfWeek: '$_id.dayOfWeek',
timeOfTheDay: '$_id.timeOfTheDay',
count: 1,
_id: 0,
},
},
]);
}
}

0 comments on commit e7e6b96

Please sign in to comment.