From 85b48744cec5504fda8f35799896b99cf2e51441 Mon Sep 17 00:00:00 2001
From: Mehdi Benouhoud <mehdi.benouhoud@polymtl.ca>
Date: Tue, 16 Apr 2024 19:21:42 -0400
Subject: [PATCH 1/8] debut tests

---
 .../classes/rooms/random/random.room.spec.ts  | 127 +++++++++++++++---
 1 file changed, 105 insertions(+), 22 deletions(-)

diff --git a/server/app/game/classes/rooms/random/random.room.spec.ts b/server/app/game/classes/rooms/random/random.room.spec.ts
index 5951b01b..620e9ab3 100644
--- a/server/app/game/classes/rooms/random/random.room.spec.ts
+++ b/server/app/game/classes/rooms/random/random.room.spec.ts
@@ -1,41 +1,124 @@
+import { RandomRoom } from '@app/game/classes/rooms/random/random.room';
+import * as TimerModule from '@app/game/classes/timer/timer.class';
 import { Game } from '@common/game';
+import { QuestionType } from '@common/question';
 import { Quiz } from '@common/quiz';
+import { RANDOM_GAME_DURATION, RANDOM_GAME_ID, RANDOM_GAME_TITLE } from '@common/random-game';
 import * as sinon from 'sinon';
-import { Server } from 'socket.io';
-import { RandomRoom } from './random.room';
+import { BroadcastOperator, Server, Socket } from 'socket.io';
+import type { DefaultEventsMap } from 'socket.io/dist/typed-events';
+import { HOST_USERNAME } from './random.room.constants';
+import { Answer } from '@common/player';
+import { AnswerManager } from '../../managers/answer/answer.manager';
 
-describe('RandomRoom', () => {
-    let randomRoom: RandomRoom;
+class TestableRandomRoom extends RandomRoom {
+    startWithDelay = this.startWithDelay;
+    sendResults = this.sendResults;
+    sendFinalResults = this.sendFinalResults;
+    finalize = this.finalize;
+    continueWithDelay = this.continueWithDelay;
+    onQuestionEnd = this.onQuestionEnd;
+}
 
-    let server: sinon.SinonStubbedInstance<Server>;
+class MockTimer {
+    constructorSpy = sinon.spy();
+    dispose = sinon.spy();
+    start = sinon.spy();
+
+    constructor(...args: unknown[]) {
+        this.constructorSpy(...args);
+    }
+}
 
-    let quiz: Quiz;
-    let game: Game;
+(TimerModule.Timer as unknown) = MockTimer;
+describe('RandomRoom', () => {
+    let randomRoom: TestableRandomRoom;
+    let server: sinon.SinonStubbedInstance<Server>;
+    let serverRoom: sinon.SinonStubbedInstance<Socket>;
+    let answerManager: sinon.SinonStubbedInstance<AnswerManager>;
+    let randomRoomQuizMock: Quiz;
+    let randomRoomGameMock: Game;
 
     beforeEach(() => {
-        server = sinon.createStubInstance<Server>(Server);
+        randomRoomGameMock = {
+            id: '1234',
+            pin: '1234',
+            duration: 60,
+            nQuestions: 5,
+            title: 'randomGameTitle',
+        };
 
-        quiz = {
-            _id: 'testQuizId',
-            title: 'foo',
-            duration: 10,
-            questions: [],
+        randomRoomQuizMock = {
+            _id: RANDOM_GAME_ID,
             isAvailable: true,
+            questions: [
+                {
+                    _id: '1234',
+                    type: QuestionType.Qcm,
+                    choices: [],
+                    text: 'testQuestion',
+                    points: 10,
+                },
+                {
+                    _id: '1235',
+                    type: QuestionType.Qcm,
+                    choices: [],
+                    text: 'testQuestion2',
+                    points: 10,
+                },
+            ],
             lastModification: new Date(),
-            description: 'Test Quiz Description',
-        } as Quiz;
+            title: RANDOM_GAME_TITLE,
+            description: 'partie aleatoire testee',
+            duration: RANDOM_GAME_DURATION,
+        };
 
-        game = {
-            id: 'testGameId',
-            pin: '1234',
-            title: 'Test Game',
-            duration: 60,
-        } as Game;
+        server = sinon.createStubInstance<Server>(Server);
+        serverRoom = sinon.createStubInstance<Socket>(Socket);
+        answerManager = sinon.createStubInstance<AnswerManager>(AnswerManager);
+        server.to.callsFake(() => serverRoom as unknown as BroadcastOperator<DefaultEventsMap, unknown>);
+
+        randomRoom = new TestableRandomRoom(randomRoomGameMock, randomRoomQuizMock, server);
 
-        randomRoom = new RandomRoom(game, quiz, server);
+        randomRoom['answers'] = answerManager;
+    });
+
+    afterEach(() => {
+        jest.restoreAllMocks();
     });
 
     it('should create', () => {
         expect(randomRoom).toBeTruthy();
     });
+
+    describe('sendResults', () => {
+        beforeEach(() => {
+            randomRoom['currentQuestionIndex'] = 0;
+        });
+        it('should call super.sendResults', () => {
+            const sendResultsSpy = jest.spyOn(randomRoom, 'sendResults');
+            randomRoom['sendResults']();
+            expect(sendResultsSpy).toHaveBeenCalled();
+        });
+
+        it('should call continueWithDelay', () => {
+            const continueSpy = jest.spyOn(randomRoom, 'continueWithDelay');
+            randomRoom['sendResults']();
+            expect(continueSpy).toHaveBeenCalled();
+        });
+    });
+
+    describe('demoteHostPlayer', () => {
+        it("should call players.add with the host's id and HOST_USERNAME", () => {
+            const addSpy = jest.spyOn(randomRoom['players'], 'add');
+            randomRoom['hostId'] = 'testHostId';
+            randomRoom['demoteHostToPlayer']();
+            expect(addSpy).toHaveBeenCalledWith('testHostId', HOST_USERNAME);
+        });
+        it('should set hostId to a blank string', () => {
+            randomRoom['hostId'] = 'testHostId';
+            randomRoom['demoteHostToPlayer']();
+            expect(randomRoom['hostId']).toBe('');
+        });
+    });
 });
-- 
GitLab


From e43963c705a0b461571a2c5a6afeb85494f60928 Mon Sep 17 00:00:00 2001
From: Mehdi Benouhoud <mehdi.benouhoud@polymtl.ca>
Date: Tue, 16 Apr 2024 19:39:23 -0400
Subject: [PATCH 2/8] sovled things

---
 .../classes/rooms/random/random.room.spec.ts  | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/server/app/game/classes/rooms/random/random.room.spec.ts b/server/app/game/classes/rooms/random/random.room.spec.ts
index 620e9ab3..2a8060d8 100644
--- a/server/app/game/classes/rooms/random/random.room.spec.ts
+++ b/server/app/game/classes/rooms/random/random.room.spec.ts
@@ -76,6 +76,27 @@ describe('RandomRoom', () => {
         server = sinon.createStubInstance<Server>(Server);
         serverRoom = sinon.createStubInstance<Socket>(Socket);
         answerManager = sinon.createStubInstance<AnswerManager>(AnswerManager);
+        answerManager.getAll.returns([{
+            score: 1,
+            finalizedTimestamp: 1,
+            answerTimestamp: 1,
+            forceFinalize: true,
+            type: QuestionType.Qcm,
+            isCorrect: true,
+            choices: [true, true, false, false],
+            bonusObtained: true
+        }, 
+        {
+            score: 1,
+            finalizedTimestamp: 1,
+            answerTimestamp: 1,
+            forceFinalize: true,
+            type: QuestionType.Qcm,
+            isCorrect: true,
+            choices: [true, true, false, false],
+            bonusObtained: true
+        }
+        ] as Answer[]);
         server.to.callsFake(() => serverRoom as unknown as BroadcastOperator<DefaultEventsMap, unknown>);
 
         randomRoom = new TestableRandomRoom(randomRoomGameMock, randomRoomQuizMock, server);
@@ -108,6 +129,10 @@ describe('RandomRoom', () => {
         });
     });
 
+    describe('sendFinalResults', () => {
+        
+    });
+
     describe('demoteHostPlayer', () => {
         it("should call players.add with the host's id and HOST_USERNAME", () => {
             const addSpy = jest.spyOn(randomRoom['players'], 'add');
-- 
GitLab


From bb6ade1f9b716bd82b71a44a53136d27877cf3b5 Mon Sep 17 00:00:00 2001
From: Caaf14 <cata-araya@outlook.com>
Date: Tue, 16 Apr 2024 19:51:57 -0400
Subject: [PATCH 3/8] start done

---
 .../classes/rooms/random/random.room.spec.ts  | 88 +++++++++++++------
 1 file changed, 63 insertions(+), 25 deletions(-)

diff --git a/server/app/game/classes/rooms/random/random.room.spec.ts b/server/app/game/classes/rooms/random/random.room.spec.ts
index 2a8060d8..da38527d 100644
--- a/server/app/game/classes/rooms/random/random.room.spec.ts
+++ b/server/app/game/classes/rooms/random/random.room.spec.ts
@@ -1,15 +1,17 @@
+import { AnswerManager } from '@app/game/classes/managers/answer/answer.manager';
+import { DELAY_BEFORE_START_S } from '@app/game/classes/rooms/game/game.room.constants';
 import { RandomRoom } from '@app/game/classes/rooms/random/random.room';
 import * as TimerModule from '@app/game/classes/timer/timer.class';
 import { Game } from '@common/game';
+import { Answer } from '@common/player';
 import { QuestionType } from '@common/question';
 import { Quiz } from '@common/quiz';
 import { RANDOM_GAME_DURATION, RANDOM_GAME_ID, RANDOM_GAME_TITLE } from '@common/random-game';
+import { WsException } from '@nestjs/websockets';
 import * as sinon from 'sinon';
 import { BroadcastOperator, Server, Socket } from 'socket.io';
 import type { DefaultEventsMap } from 'socket.io/dist/typed-events';
 import { HOST_USERNAME } from './random.room.constants';
-import { Answer } from '@common/player';
-import { AnswerManager } from '../../managers/answer/answer.manager';
 
 class TestableRandomRoom extends RandomRoom {
     startWithDelay = this.startWithDelay;
@@ -76,26 +78,27 @@ describe('RandomRoom', () => {
         server = sinon.createStubInstance<Server>(Server);
         serverRoom = sinon.createStubInstance<Socket>(Socket);
         answerManager = sinon.createStubInstance<AnswerManager>(AnswerManager);
-        answerManager.getAll.returns([{
-            score: 1,
-            finalizedTimestamp: 1,
-            answerTimestamp: 1,
-            forceFinalize: true,
-            type: QuestionType.Qcm,
-            isCorrect: true,
-            choices: [true, true, false, false],
-            bonusObtained: true
-        }, 
-        {
-            score: 1,
-            finalizedTimestamp: 1,
-            answerTimestamp: 1,
-            forceFinalize: true,
-            type: QuestionType.Qcm,
-            isCorrect: true,
-            choices: [true, true, false, false],
-            bonusObtained: true
-        }
+        answerManager.getAll.returns([
+            {
+                score: 1,
+                finalizedTimestamp: 1,
+                answerTimestamp: 1,
+                forceFinalize: true,
+                type: QuestionType.Qcm,
+                isCorrect: true,
+                choices: [true, true, false, false],
+                bonusObtained: true,
+            },
+            {
+                score: 1,
+                finalizedTimestamp: 1,
+                answerTimestamp: 1,
+                forceFinalize: true,
+                type: QuestionType.Qcm,
+                isCorrect: true,
+                choices: [true, true, false, false],
+                bonusObtained: true,
+            },
         ] as Answer[]);
         server.to.callsFake(() => serverRoom as unknown as BroadcastOperator<DefaultEventsMap, unknown>);
 
@@ -112,6 +115,43 @@ describe('RandomRoom', () => {
         expect(randomRoom).toBeTruthy();
     });
 
+    describe('start', () => {
+        let host: Socket;
+        let nonHost: Socket;
+        let demoteHostToPlayerStub: sinon.SinonStub;
+        let startWithDelayStub: sinon.SinonStub;
+
+        beforeEach(() => {
+            host = { id: 'hostId' } as Socket;
+            nonHost = { id: 'nonHostId' } as Socket;
+            randomRoom['hostId'] = 'hostId';
+            randomRoom['isLocked'] = true;
+            // eslint-disable-next-line @typescript-eslint/no-explicit-any
+            demoteHostToPlayerStub = sinon.stub(randomRoom as any, 'demoteHostToPlayer');
+            startWithDelayStub = sinon.stub(randomRoom, 'startWithDelay');
+        });
+
+        it('should throw an error if a non-host tries to start the game', () => {
+            expect(() => randomRoom.start(nonHost)).toThrow(WsException);
+        });
+
+        it('should throw an error if the game is not locked', () => {
+            randomRoom['isLocked'] = false;
+            expect(() => randomRoom.start(host)).toThrow(WsException);
+        });
+
+        it('should set the start timestamp, demote the host to player, and start the game with delay', () => {
+            const now = Date.now();
+            sinon.useFakeTimers(now);
+
+            randomRoom.start(host);
+
+            expect(randomRoom['startTimestamp']).toBe(now);
+            expect(demoteHostToPlayerStub.calledOnce).toBeTruthy();
+            expect(startWithDelayStub.calledWith(DELAY_BEFORE_START_S)).toBeTruthy();
+        });
+    });
+
     describe('sendResults', () => {
         beforeEach(() => {
             randomRoom['currentQuestionIndex'] = 0;
@@ -129,9 +169,7 @@ describe('RandomRoom', () => {
         });
     });
 
-    describe('sendFinalResults', () => {
-        
-    });
+    describe('sendFinalResults', () => {});
 
     describe('demoteHostPlayer', () => {
         it("should call players.add with the host's id and HOST_USERNAME", () => {
-- 
GitLab


From ab362c73f0416495e075e91bb737f8e6cc43ea33 Mon Sep 17 00:00:00 2001
From: Caaf14 <cata-araya@outlook.com>
Date: Tue, 16 Apr 2024 20:18:28 -0400
Subject: [PATCH 4/8] timer fixed

---
 server/app/game/classes/rooms/random/random.room.spec.ts | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/server/app/game/classes/rooms/random/random.room.spec.ts b/server/app/game/classes/rooms/random/random.room.spec.ts
index da38527d..d003ae9c 100644
--- a/server/app/game/classes/rooms/random/random.room.spec.ts
+++ b/server/app/game/classes/rooms/random/random.room.spec.ts
@@ -184,4 +184,13 @@ describe('RandomRoom', () => {
             expect(randomRoom['hostId']).toBe('');
         });
     });
+
+    it('should dispose the timer when sendFinalResults is called', () => {
+        const oldTimer = { dispose: sinon.spy() };
+        randomRoom['timer'] = oldTimer as unknown as TimerModule.Timer;
+
+        randomRoom.sendFinalResults();
+
+        expect(oldTimer.dispose.called).toBe(true);
+    });
 });
-- 
GitLab


From d6da6918c4208c06e828ffcff675cfc6e6c36d3b Mon Sep 17 00:00:00 2001
From: Mehdi Benouhoud <mehdi.benouhoud@polymtl.ca>
Date: Tue, 16 Apr 2024 19:47:16 -0400
Subject: [PATCH 5/8] continue sendfinalresults

---
 .../classes/rooms/random/random.room.spec.ts  | 25 +++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/server/app/game/classes/rooms/random/random.room.spec.ts b/server/app/game/classes/rooms/random/random.room.spec.ts
index d003ae9c..f7ccf6b3 100644
--- a/server/app/game/classes/rooms/random/random.room.spec.ts
+++ b/server/app/game/classes/rooms/random/random.room.spec.ts
@@ -11,7 +11,10 @@ import { WsException } from '@nestjs/websockets';
 import * as sinon from 'sinon';
 import { BroadcastOperator, Server, Socket } from 'socket.io';
 import type { DefaultEventsMap } from 'socket.io/dist/typed-events';
-import { HOST_USERNAME } from './random.room.constants';
+import { DELAY_BEFORE_END_S, HOST_USERNAME } from './random.room.constants';
+import { Answer } from '@common/player';
+import { AnswerManager } from '../../managers/answer/answer.manager';
+import exp from 'constants';
 
 class TestableRandomRoom extends RandomRoom {
     startWithDelay = this.startWithDelay;
@@ -169,7 +172,25 @@ describe('RandomRoom', () => {
         });
     });
 
-    describe('sendFinalResults', () => {});
+    describe('sendFinalResults', () => {
+        it('should instantiate a new Timer', () => {
+            const timer = randomRoom['timer'] as unknown as MockTimer;
+            expect(timer.constructorSpy.called).toBe(true);
+        });
+
+        it('should start the timer and super.sendFinalResults afterwards', () => {
+            const endSpy = jest.spyOn(TestableRandomRoom.prototype, 'end').mockImplementation(jest.fn());
+            randomRoom.sendFinalResults();
+
+            const timer = randomRoom['timer'] as unknown as MockTimer;
+            expect(timer.start.called).toBe(true);
+
+            expect(endSpy).not.toHaveBeenCalled();
+            const callback = timer.start.getCall(0).args[0] as () => void;
+            callback();
+            expect(endSpy).toHaveBeenCalled();
+        });
+    });
 
     describe('demoteHostPlayer', () => {
         it("should call players.add with the host's id and HOST_USERNAME", () => {
-- 
GitLab


From 874f2dffe5c51006902a3927f98e6a5d113943aa Mon Sep 17 00:00:00 2001
From: Caaf14 <cata-araya@outlook.com>
Date: Tue, 16 Apr 2024 20:22:10 -0400
Subject: [PATCH 6/8] fix timer good version

---
 .../classes/rooms/random/random.room.spec.ts  | 25 ++-----------------
 1 file changed, 2 insertions(+), 23 deletions(-)

diff --git a/server/app/game/classes/rooms/random/random.room.spec.ts b/server/app/game/classes/rooms/random/random.room.spec.ts
index f7ccf6b3..d003ae9c 100644
--- a/server/app/game/classes/rooms/random/random.room.spec.ts
+++ b/server/app/game/classes/rooms/random/random.room.spec.ts
@@ -11,10 +11,7 @@ import { WsException } from '@nestjs/websockets';
 import * as sinon from 'sinon';
 import { BroadcastOperator, Server, Socket } from 'socket.io';
 import type { DefaultEventsMap } from 'socket.io/dist/typed-events';
-import { DELAY_BEFORE_END_S, HOST_USERNAME } from './random.room.constants';
-import { Answer } from '@common/player';
-import { AnswerManager } from '../../managers/answer/answer.manager';
-import exp from 'constants';
+import { HOST_USERNAME } from './random.room.constants';
 
 class TestableRandomRoom extends RandomRoom {
     startWithDelay = this.startWithDelay;
@@ -172,25 +169,7 @@ describe('RandomRoom', () => {
         });
     });
 
-    describe('sendFinalResults', () => {
-        it('should instantiate a new Timer', () => {
-            const timer = randomRoom['timer'] as unknown as MockTimer;
-            expect(timer.constructorSpy.called).toBe(true);
-        });
-
-        it('should start the timer and super.sendFinalResults afterwards', () => {
-            const endSpy = jest.spyOn(TestableRandomRoom.prototype, 'end').mockImplementation(jest.fn());
-            randomRoom.sendFinalResults();
-
-            const timer = randomRoom['timer'] as unknown as MockTimer;
-            expect(timer.start.called).toBe(true);
-
-            expect(endSpy).not.toHaveBeenCalled();
-            const callback = timer.start.getCall(0).args[0] as () => void;
-            callback();
-            expect(endSpy).toHaveBeenCalled();
-        });
-    });
+    describe('sendFinalResults', () => {});
 
     describe('demoteHostPlayer', () => {
         it("should call players.add with the host's id and HOST_USERNAME", () => {
-- 
GitLab


From e6652f4d04dfd0166ca9598d1b84eeb77bf63388 Mon Sep 17 00:00:00 2001
From: Mehdi Benouhoud <mehdi.benouhoud@polymtl.ca>
Date: Tue, 16 Apr 2024 20:25:31 -0400
Subject: [PATCH 7/8] removed s** tests

---
 server/app/game/classes/rooms/random/random.room.spec.ts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/server/app/game/classes/rooms/random/random.room.spec.ts b/server/app/game/classes/rooms/random/random.room.spec.ts
index d003ae9c..e6c64407 100644
--- a/server/app/game/classes/rooms/random/random.room.spec.ts
+++ b/server/app/game/classes/rooms/random/random.room.spec.ts
@@ -169,8 +169,6 @@ describe('RandomRoom', () => {
         });
     });
 
-    describe('sendFinalResults', () => {});
-
     describe('demoteHostPlayer', () => {
         it("should call players.add with the host's id and HOST_USERNAME", () => {
             const addSpy = jest.spyOn(randomRoom['players'], 'add');
-- 
GitLab


From 91e41789d9f528476dd00f14d4265405ca19ed45 Mon Sep 17 00:00:00 2001
From: Mehdi Benouhoud <mehdi.benouhoud@polymtl.ca>
Date: Tue, 16 Apr 2024 20:49:02 -0400
Subject: [PATCH 8/8] fix lint

---
 server/app/game/classes/rooms/random/random.room.spec.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/server/app/game/classes/rooms/random/random.room.spec.ts b/server/app/game/classes/rooms/random/random.room.spec.ts
index e6c64407..e52f1c82 100644
--- a/server/app/game/classes/rooms/random/random.room.spec.ts
+++ b/server/app/game/classes/rooms/random/random.room.spec.ts
@@ -1,3 +1,4 @@
+/* eslint-disable max-classes-per-file */
 import { AnswerManager } from '@app/game/classes/managers/answer/answer.manager';
 import { DELAY_BEFORE_START_S } from '@app/game/classes/rooms/game/game.room.constants';
 import { RandomRoom } from '@app/game/classes/rooms/random/random.room';
-- 
GitLab