fix expectations, remove outdated specs

This commit is contained in:
AlecM33
2023-08-03 18:42:00 -04:00
parent 19f12ca1a8
commit 7c61b3a724
10 changed files with 57 additions and 90 deletions

View File

@@ -18,7 +18,7 @@ export class Lobby {
this.startGameHandler = (e) => {
e.preventDefault();
if (!stateBucket.currentGameState.isFull) {
if (!stateBucket.currentGameState.isStartable) {
toast('The number of players does not match the number of cards. ' +
'You must either add/remove players or edit roles and their quantities.', 'error');
return;
@@ -171,10 +171,10 @@ export class Lobby {
}
setSocketHandlers () {
this.socket.on(globals.EVENT_IDS.PLAYER_JOINED, (player, gameIsFull) => {
this.socket.on(globals.EVENT_IDS.PLAYER_JOINED, (player, gameisStartable) => {
toast(player.name + ' joined!', 'success', true, true, 'short');
this.stateBucket.currentGameState.people.push(player);
this.stateBucket.currentGameState.isFull = gameIsFull;
this.stateBucket.currentGameState.isStartable = gameisStartable;
this.populatePlayers();
if ((
this.stateBucket.currentGameState.client.userType === globals.USER_TYPES.MODERATOR
@@ -193,7 +193,7 @@ export class Lobby {
);
});
this.socket.on(globals.EVENT_IDS.KICK_PERSON, (kickedId, gameIsFull) => {
this.socket.on(globals.EVENT_IDS.KICK_PERSON, (kickedId, gameisStartable) => {
if (kickedId === this.stateBucket.currentGameState.client.id) {
window.location = '/?message=' + encodeURIComponent('You were kicked by the moderator.');
} else {
@@ -202,7 +202,7 @@ export class Lobby {
this.stateBucket.currentGameState.people
.splice(kickedIndex, 1);
}
this.stateBucket.currentGameState.isFull = gameIsFull;
this.stateBucket.currentGameState.isStartable = gameisStartable;
SharedStateUtil.setNumberOfSpectators(
this.stateBucket.currentGameState.people.filter(p => p.userType === globals.USER_TYPES.SPECTATOR).length,
document.getElementById('spectator-count')
@@ -222,7 +222,7 @@ export class Lobby {
this.socket.on(globals.EVENT_IDS.UPDATE_GAME_ROLES, (deck, gameSize) => {
this.stateBucket.currentGameState.deck = deck;
this.stateBucket.currentGameState.gameSize = gameSize;
this.stateBucket.currentGameState.isFull = this.stateBucket.currentGameState.people
this.stateBucket.currentGameState.isStartable = this.stateBucket.currentGameState.people
.filter(person => person.userType === globals.USER_TYPES.PLAYER
|| person.userType === globals.USER_TYPES.TEMPORARY_MODERATOR).length === gameSize;
this.setLink(getTimeString(this.stateBucket.currentGameState));

View File

@@ -27,7 +27,7 @@ class Game {
this.previousModeratorId = null;
this.createTime = createTime;
this.timerParams = timerParams;
this.isFull = (this.gameSize === 1 && !this.hasDedicatedModerator) || isTestGame;
this.isStartable = (this.gameSize === 1 && !this.hasDedicatedModerator) || isTestGame;
this.timeRemaining = null;
}
}

View File

@@ -7,19 +7,14 @@ const Events = [
{
id: EVENT_IDS.PLAYER_JOINED,
stateChange: async (game, socketArgs, vars) => {
const toBeAssignedIndex = game.people.findIndex(
(person) => person.id === socketArgs.id && person.assigned === false
);
if (toBeAssignedIndex >= 0) {
game.people[toBeAssignedIndex] = socketArgs;
game.isFull = vars.gameManager.isGameFull(game);
}
game.people.push(socketArgs);
game.isStartable = vars.gameManager.isGameStartable(game);
},
communicate: async (game, socketArgs, vars) => {
vars.gameManager.namespace.in(game.accessCode).emit(
globals.EVENTS.PLAYER_JOINED,
GameStateCurator.mapPerson(socketArgs),
game.isFull
game.isStartable
);
}
},
@@ -31,14 +26,14 @@ const Events = [
);
if (toBeClearedIndex >= 0) {
game.people.splice(toBeClearedIndex, 1);
game.isFull = vars.gameManager.isGameFull(game);
game.isStartable = vars.gameManager.isGameStartable(game);
}
},
communicate: async (game, socketArgs, vars) => {
vars.gameManager.namespace.in(game.accessCode).emit(
EVENT_IDS.KICK_PERSON,
socketArgs.personId,
game.isFull
game.isStartable
);
}
},
@@ -51,7 +46,7 @@ const Events = [
(accumulator, currentValue) => accumulator + currentValue.quantity,
0
);
game.isFull = vars.gameManager.isGameFull(game);
game.isStartable = vars.gameManager.isGameStartable(game);
}
},
communicate: async (game, socketArgs, vars) => {
@@ -109,7 +104,7 @@ const Events = [
{
id: EVENT_IDS.START_GAME,
stateChange: async (game, socketArgs, vars) => {
if (game.isFull) {
if (game.isStartable) {
game.status = globals.STATUS.IN_PROGRESS;
vars.gameManager.deal(game);
if (game.hasTimer) {

View File

@@ -71,7 +71,7 @@ function getGameStateBasedOnPermissions (game, person) {
gameSize: game.gameSize,
people: GameStateCurator.mapPeopleForModerator(game.people, client),
timerParams: game.timerParams,
isFull: game.isFull
isStartable: game.isStartable
};
case globals.USER_TYPES.TEMPORARY_MODERATOR:
case globals.USER_TYPES.SPECTATOR:
@@ -90,7 +90,7 @@ function getGameStateBasedOnPermissions (game, person) {
})
.map((filteredPerson) => GameStateCurator.mapPerson(filteredPerson)),
timerParams: game.timerParams,
isFull: game.isFull
isStartable: game.isStartable
};
default:
break;

View File

@@ -181,7 +181,7 @@ class GameManager {
&& game.people.filter(person => person.userType === globals.USER_TYPES.SPECTATOR).length === globals.MAX_SPECTATORS
) {
return Promise.reject({ status: 400, reason: 'There are too many people already spectating.' });
} else if (joinAsSpectator || this.isGameFull(game)) {
} else if (joinAsSpectator || this.isGameStartable(game)) {
console.log('game is full');
return await addSpectator(game, name, this.logger, this.namespace, this.eventManager, this.instanceId, this.refreshGame);
}
@@ -206,12 +206,12 @@ class GameManager {
newPlayer.assigned = true;
game.people.push(newPlayer);
}
game.isFull = this.isGameFull(game);
game.isStartable = this.isGameStartable(game);
await this.refreshGame(game);
this.namespace.in(game.accessCode).emit(
globals.EVENTS.PLAYER_JOINED,
GameStateCurator.mapPerson(moderator || newPlayer),
game.isFull
game.isStartable
);
await this.eventManager.publisher?.publish(
globals.REDIS_CHANNELS.ACTIVE_GAME_STREAM,
@@ -318,7 +318,7 @@ class GameManager {
}
}
isGameFull = (game) => {
isGameStartable = (game) => {
return game.people.filter(person => person.userType === globals.USER_TYPES.PLAYER
|| person.userType === globals.USER_TYPES.TEMPORARY_MODERATOR).length === game.gameSize;
}

View File

@@ -67,7 +67,7 @@ describe('Create page', function () {
.toEqual('Test name');
});
it('should successfully update custom role information after creating it', () => {
it('should successstartabley update custom role information after creating it', () => {
document.getElementById('role-category-custom').click();
document.getElementById('custom-role-btn').click();
document.getElementById('role-name').value = 'Test name';

View File

@@ -69,18 +69,6 @@ describe('game page', () => {
expect(document.getElementById('current-info-message').innerText).toEqual('Jane joined!');
});
it('should activate the start button for the moderator when the game is full', () => {
expect(document.getElementById('start-game-button').classList.contains('disabled')).toBeTrue();
mockSocket.eventHandlers[globals.EVENT_IDS.PLAYER_JOINED]({
name: 'Jack',
id: '456',
userType: globals.USER_TYPES.PLAYER,
out: false,
revealed: false
}, true);
expect(document.getElementById('start-game-button').classList.contains('disabled')).toBeFalse();
});
afterAll(() => {
document.body.innerHTML = '';
});

View File

@@ -46,7 +46,7 @@ export const mockGames = {
paused: true,
timeRemaining: 600000
},
isFull: false
isStartable: false
},
inProgressGame: {
accessCode: 'TVV6',
@@ -163,7 +163,7 @@ export const mockGames = {
paused: true,
timeRemaining: 600000
},
isFull: true
isStartable: true
},
moderatorGame:
{
@@ -306,6 +306,6 @@ export const mockGames = {
paused: true,
timeRemaining: 600000
},
isFull: true
isStartable: true
}
};

View File

@@ -34,10 +34,10 @@ describe('Events', () => {
STATUS.LOBBY,
[
{ id: 'a', assigned: true, out: true, killed: false, userType: USER_TYPES.MODERATOR },
{ id: 'b', gameRole: 'Villager', alignment: 'good', assigned: false, out: false, killed: false, userType: USER_TYPES.PLAYER },
{ id: 'b', gameRole: 'Villager', alignment: 'good', assigned: true, out: false, killed: false, userType: USER_TYPES.PLAYER },
{ id: 'c', assigned: true, out: true, killed: false, userType: USER_TYPES.SPECTATOR }
],
[{ quantity: 2 }],
[{ quantity: 1 }, { quantity: 1 }],
false,
'a',
true,
@@ -50,7 +50,7 @@ describe('Events', () => {
spyOn(socket, 'to').and.callThrough();
spyOn(namespace.in(), 'emit').and.callThrough();
spyOn(namespace.to(), 'emit').and.callThrough();
spyOn(gameManager, 'isGameFull').and.callThrough();
spyOn(gameManager, 'isGameStartable').and.callThrough();
spyOn(GameStateCurator, 'mapPerson').and.callThrough();
spyOn(eventManager.publisher, 'publish').and.callThrough();
spyOn(eventManager, 'createMessageToPublish').and.stub();
@@ -60,38 +60,32 @@ describe('Events', () => {
describe(EVENT_IDS.PLAYER_JOINED, () => {
describe('stateChange', () => {
it('should let a player join and mark the game as full', async () => {
it('should let a player join and mark the game as startable', async () => {
await Events.find((e) => e.id === EVENT_IDS.PLAYER_JOINED)
.stateChange(game, { id: 'b', assigned: true }, { gameManager: gameManager });
expect(gameManager.isGameFull).toHaveBeenCalled();
expect(game.isFull).toEqual(true);
.stateChange(game, { id: 'd', assigned: true, userType: USER_TYPES.PLAYER }, { gameManager: gameManager });
expect(gameManager.isGameStartable).toHaveBeenCalled();
expect(game.isStartable).toEqual(true);
expect(game.people.find(p => p.id === 'b').assigned).toEqual(true);
});
it('should let a player join and mark the game as NOT full', async () => {
game.people.push({ id: 'd', assigned: false, userType: USER_TYPES.PLAYER });
it('should let too many players join and mark the game as NOT startable', async () => {
game.people.push({ id: 'e', assigned: true, userType: USER_TYPES.PLAYER });
game.people.push({ id: 'f', assigned: true, userType: USER_TYPES.PLAYER });
await Events.find((e) => e.id === EVENT_IDS.PLAYER_JOINED)
.stateChange(game, { id: 'b', assigned: true }, { gameManager: gameManager });
expect(gameManager.isGameFull).toHaveBeenCalled();
expect(game.isFull).toEqual(false);
expect(gameManager.isGameStartable).toHaveBeenCalled();
expect(game.isStartable).toEqual(false);
expect(game.people.find(p => p.id === 'b').assigned).toEqual(true);
});
it('should not let the player join if their id does not match some unassigned person', async () => {
await Events.find((e) => e.id === EVENT_IDS.PLAYER_JOINED)
.stateChange(game, { id: 'd', assigned: true }, { gameManager: gameManager });
expect(gameManager.isGameFull).not.toHaveBeenCalled();
expect(game.isFull).toEqual(false);
expect(game.people.find(p => p.id === 'd')).not.toBeDefined();
});
});
describe('communicate', () => {
it('should communicate the join event to the rooms sockets, sending the new player', async () => {
await Events.find((e) => e.id === EVENT_IDS.PLAYER_JOINED)
.communicate(game, { id: 'b', assigned: true }, { gameManager: gameManager });
.communicate(game, { id: 'd', assigned: true, userType: USER_TYPES.PLAYER }, { gameManager: gameManager });
expect(namespace.in).toHaveBeenCalledWith(game.accessCode);
expect(namespace.in().emit).toHaveBeenCalledWith(
globals.EVENTS.PLAYER_JOINED,
GameStateCurator.mapPerson({ id: 'b', assigned: true }),
game.isFull
GameStateCurator.mapPerson({ id: 'd', assigned: true, userType: USER_TYPES.PLAYER }),
game.isStartable
);
});
});
@@ -102,8 +96,8 @@ describe('Events', () => {
it('should add a spectator', async () => {
await Events.find((e) => e.id === EVENT_IDS.ADD_SPECTATOR)
.stateChange(game, { id: 'e', name: 'ghost', assigned: true }, { gameManager: gameManager });
expect(gameManager.isGameFull).not.toHaveBeenCalled();
expect(game.isFull).toEqual(false);
expect(gameManager.isGameStartable).not.toHaveBeenCalled();
expect(game.isStartable).toEqual(false);
expect(game.people.find(p => p.id === 'e').assigned).toEqual(true);
expect(game.people.find(p => p.id === 'e').name).toEqual('ghost');
});
@@ -197,18 +191,18 @@ describe('Events', () => {
describe(EVENT_IDS.START_GAME, () => {
describe('stateChange', () => {
it('should start the game', async () => {
game.isFull = true;
game.isStartable = true;
await Events.find((e) => e.id === EVENT_IDS.START_GAME)
.stateChange(game, { id: 'b', assigned: true }, { gameManager: gameManager });
expect(game.status).toEqual(STATUS.IN_PROGRESS);
});
it('should not start the game if it is not full', async () => {
it('should not start the game if it is not startable', async () => {
await Events.find((e) => e.id === EVENT_IDS.START_GAME)
.stateChange(game, { id: 'b', assigned: true }, { gameManager: gameManager });
expect(game.status).toEqual(STATUS.LOBBY);
});
it('should start the game and run the timer if the game has one', async () => {
game.isFull = true;
game.isStartable = true;
game.hasTimer = true;
game.timerParams = {};
spyOn(timerManager, 'runTimer').and.callFake((a, b) => {});

View File

@@ -37,8 +37,8 @@ describe('GameManager', () => {
'ABCD',
STATUS.LOBBY,
[{ id: 'a', name: 'person1', assigned: true, out: true, killed: false, userType: USER_TYPES.MODERATOR },
{ id: 'b', name: 'person2', gameRole: 'Villager', alignment: 'good', assigned: false, out: false, killed: false, userType: USER_TYPES.PLAYER }],
[{ quantity: 2 }],
{ id: 'b', name: 'person2', gameRole: 'Villager', alignment: 'good', assigned: true, out: false, killed: false, userType: USER_TYPES.PLAYER }],
[{ quantity: 1 }, { quantity: 1 }],
false,
'a',
true,
@@ -50,30 +50,26 @@ describe('GameManager', () => {
});
describe('#joinGame', () => {
it('should mark the game as full when all players have been assigned', async () => {
it('should mark the game as startable when the number of players equals the game size', async () => {
await gameManager.joinGame(game, 'Jill', 'x');
expect(game.isFull).toEqual(true);
expect(game.isStartable).toEqual(true);
});
it('should create a spectator if the game is already full and broadcast it to the room', () => {
game.people.find(p => p.id === 'b').assigned = true;
game.isFull = true;
it('should create a spectator if the game is already startable and broadcast it to the room', async () => {
await gameManager.joinGame(game, 'Jill', 'x');
game.isStartable = true;
spyOn(gameManager.namespace.in(), 'emit');
gameManager.joinGame(game, 'Jane', 'x');
await gameManager.joinGame(game, 'Jane', 'x');
expect(game.isFull).toEqual(true);
expect(game.isStartable).toEqual(true);
expect(game.people.filter(p => p.userType === USER_TYPES.SPECTATOR).length).toEqual(1);
});
});
describe('#restartGame', () => {
let shuffleSpy;
beforeEach(() => {
shuffleSpy = spyOn(gameManager, 'shuffle').and.stub();
});
beforeEach(() => {});
it('should reset all relevant game parameters', async () => {
game.status = STATUS.ENDED;
@@ -85,11 +81,10 @@ describe('GameManager', () => {
await gameManager.restartGame(game, namespace);
expect(game.status).toEqual(STATUS.IN_PROGRESS);
expect(game.status).toEqual(STATUS.LOBBY);
expect(player.userType).toEqual(USER_TYPES.PLAYER);
expect(player.out).toBeFalse();
expect(player.killed).toBeFalse();
expect(shuffleSpy).toHaveBeenCalled();
expect(emitSpy).toHaveBeenCalledWith(globals.EVENT_IDS.RESTART_GAME);
});
@@ -100,16 +95,12 @@ describe('GameManager', () => {
game.status = STATUS.ENDED;
const threadKillSpy = spyOn(timerManager.timerThreads.ABCD, 'kill');
const runTimerSpy = spyOn(timerManager, 'runTimer').and.stub();
const emitSpy = spyOn(namespace.in(), 'emit');
await gameManager.restartGame(game, namespace);
expect(game.status).toEqual(STATUS.IN_PROGRESS);
expect(game.timerParams.paused).toBeTrue();
expect(game.status).toEqual(STATUS.LOBBY);
expect(threadKillSpy).toHaveBeenCalled();
expect(runTimerSpy).toHaveBeenCalled();
expect(shuffleSpy).toHaveBeenCalled();
expect(emitSpy).toHaveBeenCalledWith(globals.EVENT_IDS.RESTART_GAME);
});
@@ -123,10 +114,9 @@ describe('GameManager', () => {
await gameManager.restartGame(game, namespace);
expect(game.status).toEqual(STATUS.IN_PROGRESS);
expect(game.status).toEqual(STATUS.LOBBY);
expect(game.currentModeratorId).toEqual('b');
expect(game.people.find(p => p.id === 'b').userType).toEqual(USER_TYPES.TEMPORARY_MODERATOR);
expect(shuffleSpy).toHaveBeenCalled();
expect(emitSpy).toHaveBeenCalledWith(globals.EVENT_IDS.RESTART_GAME);
});
});