mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
implement test coverage for game layer
This commit is contained in:
parent
74803442d2
commit
367852866f
12 changed files with 2721 additions and 24 deletions
200
webclient/src/websocket/commands/game/gameCommands.spec.ts
Normal file
200
webclient/src/websocket/commands/game/gameCommands.spec.ts
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
import { BackendService } from '../../services/BackendService';
|
||||
import { attachCard } from './attachCard';
|
||||
import { changeZoneProperties } from './changeZoneProperties';
|
||||
import { concede } from './concede';
|
||||
import { createArrow } from './createArrow';
|
||||
import { createCounter } from './createCounter';
|
||||
import { createToken } from './createToken';
|
||||
import { deckSelect } from './deckSelect';
|
||||
import { delCounter } from './delCounter';
|
||||
import { deleteArrow } from './deleteArrow';
|
||||
import { drawCards } from './drawCards';
|
||||
import { dumpZone } from './dumpZone';
|
||||
import { flipCard } from './flipCard';
|
||||
import { gameSay } from './gameSay';
|
||||
import { incCardCounter } from './incCardCounter';
|
||||
import { incCounter } from './incCounter';
|
||||
import { kickFromGame } from './kickFromGame';
|
||||
import { leaveGame } from './leaveGame';
|
||||
import { moveCard } from './moveCard';
|
||||
import { mulligan } from './mulligan';
|
||||
import { nextTurn } from './nextTurn';
|
||||
import { readyStart } from './readyStart';
|
||||
import { revealCards } from './revealCards';
|
||||
import { reverseTurn } from './reverseTurn';
|
||||
import { setActivePhase } from './setActivePhase';
|
||||
import { setCardAttr } from './setCardAttr';
|
||||
import { setCardCounter } from './setCardCounter';
|
||||
import { setCounter } from './setCounter';
|
||||
import { setSideboardLock } from './setSideboardLock';
|
||||
import { setSideboardPlan } from './setSideboardPlan';
|
||||
import { shuffle } from './shuffle';
|
||||
import { undoDraw } from './undoDraw';
|
||||
|
||||
jest.mock('../../services/BackendService', () => ({
|
||||
BackendService: { sendGameCommand: jest.fn() },
|
||||
}));
|
||||
|
||||
const gameId = 1;
|
||||
const params = {} as any;
|
||||
|
||||
beforeEach(() => {
|
||||
(BackendService.sendGameCommand as jest.Mock).mockClear();
|
||||
});
|
||||
|
||||
describe('Game commands — delegate to BackendService.sendGameCommand', () => {
|
||||
it('attachCard sends Command_AttachCard', () => {
|
||||
attachCard(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_AttachCard', params);
|
||||
});
|
||||
|
||||
it('changeZoneProperties sends Command_ChangeZoneProperties', () => {
|
||||
changeZoneProperties(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_ChangeZoneProperties', params);
|
||||
});
|
||||
|
||||
it('concede sends Command_Concede with empty object', () => {
|
||||
concede(gameId);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_Concede', {});
|
||||
});
|
||||
|
||||
it('createArrow sends Command_CreateArrow', () => {
|
||||
createArrow(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_CreateArrow', params);
|
||||
});
|
||||
|
||||
it('createCounter sends Command_CreateCounter', () => {
|
||||
createCounter(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_CreateCounter', params);
|
||||
});
|
||||
|
||||
it('createToken sends Command_CreateToken', () => {
|
||||
createToken(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_CreateToken', params);
|
||||
});
|
||||
|
||||
it('deckSelect sends Command_DeckSelect', () => {
|
||||
deckSelect(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_DeckSelect', params);
|
||||
});
|
||||
|
||||
it('delCounter sends Command_DelCounter', () => {
|
||||
delCounter(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_DelCounter', params);
|
||||
});
|
||||
|
||||
it('deleteArrow sends Command_DeleteArrow', () => {
|
||||
deleteArrow(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_DeleteArrow', params);
|
||||
});
|
||||
|
||||
it('drawCards sends Command_DrawCards', () => {
|
||||
drawCards(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_DrawCards', params);
|
||||
});
|
||||
|
||||
it('dumpZone sends Command_DumpZone', () => {
|
||||
dumpZone(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_DumpZone', params);
|
||||
});
|
||||
|
||||
it('flipCard sends Command_FlipCard', () => {
|
||||
flipCard(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_FlipCard', params);
|
||||
});
|
||||
|
||||
it('gameSay sends Command_GameSay', () => {
|
||||
gameSay(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_GameSay', params);
|
||||
});
|
||||
|
||||
it('incCardCounter sends Command_IncCardCounter', () => {
|
||||
incCardCounter(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_IncCardCounter', params);
|
||||
});
|
||||
|
||||
it('incCounter sends Command_IncCounter', () => {
|
||||
incCounter(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_IncCounter', params);
|
||||
});
|
||||
|
||||
it('kickFromGame sends Command_KickFromGame', () => {
|
||||
kickFromGame(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_KickFromGame', params);
|
||||
});
|
||||
|
||||
it('leaveGame sends Command_LeaveGame with empty object', () => {
|
||||
leaveGame(gameId);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_LeaveGame', {});
|
||||
});
|
||||
|
||||
it('moveCard sends Command_MoveCard', () => {
|
||||
moveCard(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_MoveCard', params);
|
||||
});
|
||||
|
||||
it('mulligan sends Command_Mulligan', () => {
|
||||
mulligan(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_Mulligan', params);
|
||||
});
|
||||
|
||||
it('nextTurn sends Command_NextTurn with empty object', () => {
|
||||
nextTurn(gameId);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_NextTurn', {});
|
||||
});
|
||||
|
||||
it('readyStart sends Command_ReadyStart', () => {
|
||||
readyStart(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_ReadyStart', params);
|
||||
});
|
||||
|
||||
it('revealCards sends Command_RevealCards', () => {
|
||||
revealCards(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_RevealCards', params);
|
||||
});
|
||||
|
||||
it('reverseTurn sends Command_ReverseTurn with empty object', () => {
|
||||
reverseTurn(gameId);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_ReverseTurn', {});
|
||||
});
|
||||
|
||||
it('setActivePhase sends Command_SetActivePhase', () => {
|
||||
setActivePhase(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_SetActivePhase', params);
|
||||
});
|
||||
|
||||
it('setCardAttr sends Command_SetCardAttr', () => {
|
||||
setCardAttr(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_SetCardAttr', params);
|
||||
});
|
||||
|
||||
it('setCardCounter sends Command_SetCardCounter', () => {
|
||||
setCardCounter(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_SetCardCounter', params);
|
||||
});
|
||||
|
||||
it('setCounter sends Command_SetCounter', () => {
|
||||
setCounter(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_SetCounter', params);
|
||||
});
|
||||
|
||||
it('setSideboardLock sends Command_SetSideboardLock', () => {
|
||||
setSideboardLock(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_SetSideboardLock', params);
|
||||
});
|
||||
|
||||
it('setSideboardPlan sends Command_SetSideboardPlan', () => {
|
||||
setSideboardPlan(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_SetSideboardPlan', params);
|
||||
});
|
||||
|
||||
it('shuffle sends Command_Shuffle', () => {
|
||||
shuffle(gameId, params);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_Shuffle', params);
|
||||
});
|
||||
|
||||
it('undoDraw sends Command_UndoDraw with empty object', () => {
|
||||
undoDraw(gameId);
|
||||
expect(BackendService.sendGameCommand).toHaveBeenCalledWith(gameId, 'Command_UndoDraw', {});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,19 +1,7 @@
|
|||
jest.mock('../../persistence', () => ({
|
||||
SessionPersistence: {
|
||||
playerPropertiesChanged: jest.fn(),
|
||||
},
|
||||
}));
|
||||
import { CommonEvents } from './index';
|
||||
|
||||
import { SessionPersistence } from '../../persistence';
|
||||
|
||||
beforeEach(() => jest.clearAllMocks());
|
||||
|
||||
describe('playerPropertiesChanged', () => {
|
||||
const { playerPropertiesChanged } = jest.requireActual('./playerPropertiesChanged');
|
||||
|
||||
it('delegates to SessionPersistence.playerPropertiesChanged', () => {
|
||||
const payload = { gameId: 1, player: { playerId: 2 } } as any;
|
||||
playerPropertiesChanged(payload);
|
||||
expect(SessionPersistence.playerPropertiesChanged).toHaveBeenCalledWith(payload);
|
||||
describe('CommonEvents', () => {
|
||||
it('is an empty event map (all common events were moved to game/session events)', () => {
|
||||
expect(CommonEvents).toEqual({});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,21 +1,76 @@
|
|||
jest.mock('../../persistence', () => ({
|
||||
GamePersistence: {
|
||||
gameStateChanged: jest.fn(),
|
||||
playerJoined: jest.fn(),
|
||||
playerLeft: jest.fn(),
|
||||
playerPropertiesChanged: jest.fn(),
|
||||
gameClosed: jest.fn(),
|
||||
gameHostChanged: jest.fn(),
|
||||
kicked: jest.fn(),
|
||||
gameSay: jest.fn(),
|
||||
cardMoved: jest.fn(),
|
||||
cardFlipped: jest.fn(),
|
||||
cardDestroyed: jest.fn(),
|
||||
cardAttached: jest.fn(),
|
||||
tokenCreated: jest.fn(),
|
||||
cardAttrChanged: jest.fn(),
|
||||
cardCounterChanged: jest.fn(),
|
||||
arrowCreated: jest.fn(),
|
||||
arrowDeleted: jest.fn(),
|
||||
counterCreated: jest.fn(),
|
||||
counterSet: jest.fn(),
|
||||
counterDeleted: jest.fn(),
|
||||
cardsDrawn: jest.fn(),
|
||||
cardsRevealed: jest.fn(),
|
||||
zoneShuffled: jest.fn(),
|
||||
dieRolled: jest.fn(),
|
||||
activePlayerSet: jest.fn(),
|
||||
activePhaseSet: jest.fn(),
|
||||
turnReversed: jest.fn(),
|
||||
zoneDumped: jest.fn(),
|
||||
zonePropertiesChanged: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
import { GamePersistence } from '../../persistence';
|
||||
import { attachCard } from './attachCard';
|
||||
import { changeZoneProperties } from './changeZoneProperties';
|
||||
import { createArrow } from './createArrow';
|
||||
import { createCounter } from './createCounter';
|
||||
import { createToken } from './createToken';
|
||||
import { delCounter } from './delCounter';
|
||||
import { deleteArrow } from './deleteArrow';
|
||||
import { destroyCard } from './destroyCard';
|
||||
import { drawCards } from './drawCards';
|
||||
import { dumpZone } from './dumpZone';
|
||||
import { flipCard } from './flipCard';
|
||||
import { gameClosed } from './gameClosed';
|
||||
import { gameHostChanged } from './gameHostChanged';
|
||||
import { gameSay } from './gameSay';
|
||||
import { gameStateChanged } from './gameStateChanged';
|
||||
import { joinGame } from './joinGame';
|
||||
import { kicked } from './kicked';
|
||||
import { leaveGame } from './leaveGame';
|
||||
import { moveCard } from './moveCard';
|
||||
import { playerPropertiesChanged } from './playerPropertiesChanged';
|
||||
import { revealCards } from './revealCards';
|
||||
import { reverseTurn } from './reverseTurn';
|
||||
import { rollDie } from './rollDie';
|
||||
import { setActivePhase } from './setActivePhase';
|
||||
import { setActivePlayer } from './setActivePlayer';
|
||||
import { setCardAttr } from './setCardAttr';
|
||||
import { setCardCounter } from './setCardCounter';
|
||||
import { setCounter } from './setCounter';
|
||||
import { shuffle } from './shuffle';
|
||||
|
||||
beforeEach(() => jest.clearAllMocks());
|
||||
|
||||
const meta = { gameId: 5, playerId: 2, context: null, secondsElapsed: 0, forcedByJudge: 0 };
|
||||
|
||||
describe('joinGame event', () => {
|
||||
it('delegates to GamePersistence.playerJoined with gameId from meta', () => {
|
||||
const playerProperties = { playerId: 1 };
|
||||
const data = { playerProperties } as any;
|
||||
const meta = { gameId: 5, playerId: 1, context: null, secondsElapsed: 0, forcedByJudge: 0 };
|
||||
joinGame(data, meta);
|
||||
expect(GamePersistence.playerJoined).toHaveBeenCalledWith(5, playerProperties);
|
||||
});
|
||||
|
|
@ -24,8 +79,221 @@ describe('joinGame event', () => {
|
|||
describe('leaveGame event', () => {
|
||||
it('delegates to GamePersistence.playerLeft with gameId/playerId from meta', () => {
|
||||
const data = { reason: 3 };
|
||||
const meta = { gameId: 5, playerId: 2, context: null, secondsElapsed: 0, forcedByJudge: 0 };
|
||||
leaveGame(data, meta);
|
||||
expect(GamePersistence.playerLeft).toHaveBeenCalledWith(5, 2, 3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gameClosed event', () => {
|
||||
it('delegates to GamePersistence.gameClosed with gameId', () => {
|
||||
gameClosed({}, meta);
|
||||
expect(GamePersistence.gameClosed).toHaveBeenCalledWith(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gameHostChanged event', () => {
|
||||
it('delegates to GamePersistence.gameHostChanged using meta.playerId as hostId', () => {
|
||||
gameHostChanged({}, meta);
|
||||
expect(GamePersistence.gameHostChanged).toHaveBeenCalledWith(5, 2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('kicked event', () => {
|
||||
it('delegates to GamePersistence.kicked with gameId', () => {
|
||||
kicked({}, meta);
|
||||
expect(GamePersistence.kicked).toHaveBeenCalledWith(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gameStateChanged event', () => {
|
||||
it('delegates to GamePersistence.gameStateChanged with gameId and full data', () => {
|
||||
const data = { playerList: [] } as any;
|
||||
gameStateChanged(data, meta);
|
||||
expect(GamePersistence.gameStateChanged).toHaveBeenCalledWith(5, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('playerPropertiesChanged event', () => {
|
||||
it('delegates to GamePersistence.playerPropertiesChanged with gameId, playerId, properties', () => {
|
||||
const playerProperties = { playerId: 2 } as any;
|
||||
const data = { playerProperties } as any;
|
||||
playerPropertiesChanged(data, meta);
|
||||
expect(GamePersistence.playerPropertiesChanged).toHaveBeenCalledWith(5, 2, playerProperties);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gameSay event', () => {
|
||||
it('delegates to GamePersistence.gameSay with gameId, playerId, message', () => {
|
||||
const data = { message: 'gg' } as any;
|
||||
gameSay(data, meta);
|
||||
expect(GamePersistence.gameSay).toHaveBeenCalledWith(5, 2, 'gg');
|
||||
});
|
||||
});
|
||||
|
||||
describe('moveCard event', () => {
|
||||
it('delegates to GamePersistence.cardMoved with gameId, playerId and data', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
moveCard(data, meta);
|
||||
expect(GamePersistence.cardMoved).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flipCard event', () => {
|
||||
it('delegates to GamePersistence.cardFlipped with gameId, playerId and data', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
flipCard(data, meta);
|
||||
expect(GamePersistence.cardFlipped).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('destroyCard event', () => {
|
||||
it('delegates to GamePersistence.cardDestroyed with gameId, playerId and data', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
destroyCard(data, meta);
|
||||
expect(GamePersistence.cardDestroyed).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('attachCard event', () => {
|
||||
it('delegates to GamePersistence.cardAttached with gameId, playerId and data', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
attachCard(data, meta);
|
||||
expect(GamePersistence.cardAttached).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createToken event', () => {
|
||||
it('delegates to GamePersistence.tokenCreated with gameId, playerId and data', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
createToken(data, meta);
|
||||
expect(GamePersistence.tokenCreated).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setCardAttr event', () => {
|
||||
it('delegates to GamePersistence.cardAttrChanged with gameId, playerId and data', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
setCardAttr(data, meta);
|
||||
expect(GamePersistence.cardAttrChanged).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setCardCounter event', () => {
|
||||
it('delegates to GamePersistence.cardCounterChanged with gameId, playerId and data', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
setCardCounter(data, meta);
|
||||
expect(GamePersistence.cardCounterChanged).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createArrow event', () => {
|
||||
it('delegates to GamePersistence.arrowCreated with gameId, playerId and data', () => {
|
||||
const data = { arrowInfo: {} } as any;
|
||||
createArrow(data, meta);
|
||||
expect(GamePersistence.arrowCreated).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteArrow event', () => {
|
||||
it('delegates to GamePersistence.arrowDeleted with gameId, playerId and data', () => {
|
||||
const data = { arrowId: 9 } as any;
|
||||
deleteArrow(data, meta);
|
||||
expect(GamePersistence.arrowDeleted).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createCounter event', () => {
|
||||
it('delegates to GamePersistence.counterCreated with gameId, playerId and data', () => {
|
||||
const data = { counterInfo: {} } as any;
|
||||
createCounter(data, meta);
|
||||
expect(GamePersistence.counterCreated).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setCounter event', () => {
|
||||
it('delegates to GamePersistence.counterSet with gameId, playerId and data', () => {
|
||||
const data = { counterId: 1, value: 20 } as any;
|
||||
setCounter(data, meta);
|
||||
expect(GamePersistence.counterSet).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('delCounter event', () => {
|
||||
it('delegates to GamePersistence.counterDeleted with gameId, playerId and data', () => {
|
||||
const data = { counterId: 1 } as any;
|
||||
delCounter(data, meta);
|
||||
expect(GamePersistence.counterDeleted).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('drawCards event', () => {
|
||||
it('delegates to GamePersistence.cardsDrawn with gameId, playerId and data', () => {
|
||||
const data = { number: 2, cards: [] } as any;
|
||||
drawCards(data, meta);
|
||||
expect(GamePersistence.cardsDrawn).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('revealCards event', () => {
|
||||
it('delegates to GamePersistence.cardsRevealed with gameId, playerId and data', () => {
|
||||
const data = { zoneName: 'hand', cards: [] } as any;
|
||||
revealCards(data, meta);
|
||||
expect(GamePersistence.cardsRevealed).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('shuffle event', () => {
|
||||
it('delegates to GamePersistence.zoneShuffled with gameId, playerId and data', () => {
|
||||
const data = { zoneName: 'deck' } as any;
|
||||
shuffle(data, meta);
|
||||
expect(GamePersistence.zoneShuffled).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('rollDie event', () => {
|
||||
it('delegates to GamePersistence.dieRolled with gameId, playerId and data', () => {
|
||||
const data = { die: 6, result: 4 } as any;
|
||||
rollDie(data, meta);
|
||||
expect(GamePersistence.dieRolled).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setActivePlayer event', () => {
|
||||
it('delegates to GamePersistence.activePlayerSet with gameId and activePlayerId', () => {
|
||||
const data = { activePlayerId: 3 } as any;
|
||||
setActivePlayer(data, meta);
|
||||
expect(GamePersistence.activePlayerSet).toHaveBeenCalledWith(5, 3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setActivePhase event', () => {
|
||||
it('delegates to GamePersistence.activePhaseSet with gameId and phase', () => {
|
||||
const data = { phase: 4 } as any;
|
||||
setActivePhase(data, meta);
|
||||
expect(GamePersistence.activePhaseSet).toHaveBeenCalledWith(5, 4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('reverseTurn event', () => {
|
||||
it('delegates to GamePersistence.turnReversed with gameId and reversed', () => {
|
||||
const data = { reversed: true } as any;
|
||||
reverseTurn(data, meta);
|
||||
expect(GamePersistence.turnReversed).toHaveBeenCalledWith(5, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dumpZone event', () => {
|
||||
it('delegates to GamePersistence.zoneDumped with gameId, playerId and data', () => {
|
||||
const data = { zoneName: 'hand' } as any;
|
||||
dumpZone(data, meta);
|
||||
expect(GamePersistence.zoneDumped).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('changeZoneProperties event', () => {
|
||||
it('delegates to GamePersistence.zonePropertiesChanged with gameId, playerId and data', () => {
|
||||
const data = { zoneName: 'hand', alwaysRevealTopCard: true } as any;
|
||||
changeZoneProperties(data, meta);
|
||||
expect(GamePersistence.zonePropertiesChanged).toHaveBeenCalledWith(5, 2, data);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,8 +2,35 @@ import { GamePersistence } from './GamePersistence';
|
|||
|
||||
jest.mock('store', () => ({
|
||||
GameDispatch: {
|
||||
gameStateChanged: jest.fn(),
|
||||
playerJoined: jest.fn(),
|
||||
playerLeft: jest.fn(),
|
||||
playerPropertiesChanged: jest.fn(),
|
||||
gameClosed: jest.fn(),
|
||||
gameHostChanged: jest.fn(),
|
||||
kicked: jest.fn(),
|
||||
gameSay: jest.fn(),
|
||||
cardMoved: jest.fn(),
|
||||
cardFlipped: jest.fn(),
|
||||
cardDestroyed: jest.fn(),
|
||||
cardAttached: jest.fn(),
|
||||
tokenCreated: jest.fn(),
|
||||
cardAttrChanged: jest.fn(),
|
||||
cardCounterChanged: jest.fn(),
|
||||
arrowCreated: jest.fn(),
|
||||
arrowDeleted: jest.fn(),
|
||||
counterCreated: jest.fn(),
|
||||
counterSet: jest.fn(),
|
||||
counterDeleted: jest.fn(),
|
||||
cardsDrawn: jest.fn(),
|
||||
cardsRevealed: jest.fn(),
|
||||
zoneShuffled: jest.fn(),
|
||||
dieRolled: jest.fn(),
|
||||
activePlayerSet: jest.fn(),
|
||||
activePhaseSet: jest.fn(),
|
||||
turnReversed: jest.fn(),
|
||||
zoneDumped: jest.fn(),
|
||||
zonePropertiesChanged: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
|
|
@ -12,6 +39,12 @@ import { GameDispatch } from 'store';
|
|||
beforeEach(() => jest.clearAllMocks());
|
||||
|
||||
describe('GamePersistence', () => {
|
||||
it('gameStateChanged dispatches via GameDispatch', () => {
|
||||
const data = { playerList: [] } as any;
|
||||
GamePersistence.gameStateChanged(5, data);
|
||||
expect(GameDispatch.gameStateChanged).toHaveBeenCalledWith(5, data);
|
||||
});
|
||||
|
||||
it('playerJoined dispatches via GameDispatch', () => {
|
||||
const data = { playerId: 1 } as any;
|
||||
GamePersistence.playerJoined(5, data);
|
||||
|
|
@ -22,4 +55,153 @@ describe('GamePersistence', () => {
|
|||
GamePersistence.playerLeft(5, 1, 3);
|
||||
expect(GameDispatch.playerLeft).toHaveBeenCalledWith(5, 1, 3);
|
||||
});
|
||||
|
||||
it('playerPropertiesChanged dispatches via GameDispatch', () => {
|
||||
const props = { playerId: 2 } as any;
|
||||
GamePersistence.playerPropertiesChanged(5, 2, props);
|
||||
expect(GameDispatch.playerPropertiesChanged).toHaveBeenCalledWith(5, 2, props);
|
||||
});
|
||||
|
||||
it('gameClosed dispatches via GameDispatch', () => {
|
||||
GamePersistence.gameClosed(5);
|
||||
expect(GameDispatch.gameClosed).toHaveBeenCalledWith(5);
|
||||
});
|
||||
|
||||
it('gameHostChanged dispatches via GameDispatch', () => {
|
||||
GamePersistence.gameHostChanged(5, 7);
|
||||
expect(GameDispatch.gameHostChanged).toHaveBeenCalledWith(5, 7);
|
||||
});
|
||||
|
||||
it('kicked dispatches via GameDispatch', () => {
|
||||
GamePersistence.kicked(5);
|
||||
expect(GameDispatch.kicked).toHaveBeenCalledWith(5);
|
||||
});
|
||||
|
||||
it('gameSay dispatches via GameDispatch', () => {
|
||||
GamePersistence.gameSay(5, 1, 'hello');
|
||||
expect(GameDispatch.gameSay).toHaveBeenCalledWith(5, 1, 'hello');
|
||||
});
|
||||
|
||||
it('cardMoved dispatches via GameDispatch', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
GamePersistence.cardMoved(5, 1, data);
|
||||
expect(GameDispatch.cardMoved).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('cardFlipped dispatches via GameDispatch', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
GamePersistence.cardFlipped(5, 1, data);
|
||||
expect(GameDispatch.cardFlipped).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('cardDestroyed dispatches via GameDispatch', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
GamePersistence.cardDestroyed(5, 1, data);
|
||||
expect(GameDispatch.cardDestroyed).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('cardAttached dispatches via GameDispatch', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
GamePersistence.cardAttached(5, 1, data);
|
||||
expect(GameDispatch.cardAttached).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('tokenCreated dispatches via GameDispatch', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
GamePersistence.tokenCreated(5, 1, data);
|
||||
expect(GameDispatch.tokenCreated).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('cardAttrChanged dispatches via GameDispatch', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
GamePersistence.cardAttrChanged(5, 1, data);
|
||||
expect(GameDispatch.cardAttrChanged).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('cardCounterChanged dispatches via GameDispatch', () => {
|
||||
const data = { cardId: 3 } as any;
|
||||
GamePersistence.cardCounterChanged(5, 1, data);
|
||||
expect(GameDispatch.cardCounterChanged).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('arrowCreated dispatches via GameDispatch', () => {
|
||||
const data = { arrowInfo: {} } as any;
|
||||
GamePersistence.arrowCreated(5, 1, data);
|
||||
expect(GameDispatch.arrowCreated).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('arrowDeleted dispatches via GameDispatch', () => {
|
||||
const data = { arrowId: 9 };
|
||||
GamePersistence.arrowDeleted(5, 1, data);
|
||||
expect(GameDispatch.arrowDeleted).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('counterCreated dispatches via GameDispatch', () => {
|
||||
const data = { counterInfo: {} } as any;
|
||||
GamePersistence.counterCreated(5, 1, data);
|
||||
expect(GameDispatch.counterCreated).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('counterSet dispatches via GameDispatch', () => {
|
||||
const data = { counterId: 1, value: 20 };
|
||||
GamePersistence.counterSet(5, 1, data);
|
||||
expect(GameDispatch.counterSet).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('counterDeleted dispatches via GameDispatch', () => {
|
||||
const data = { counterId: 1 };
|
||||
GamePersistence.counterDeleted(5, 1, data);
|
||||
expect(GameDispatch.counterDeleted).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('cardsDrawn dispatches via GameDispatch', () => {
|
||||
const data = { number: 2, cards: [] } as any;
|
||||
GamePersistence.cardsDrawn(5, 1, data);
|
||||
expect(GameDispatch.cardsDrawn).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('cardsRevealed dispatches via GameDispatch', () => {
|
||||
const data = { zoneName: 'hand', cards: [] } as any;
|
||||
GamePersistence.cardsRevealed(5, 1, data);
|
||||
expect(GameDispatch.cardsRevealed).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('zoneShuffled dispatches via GameDispatch', () => {
|
||||
const data = { zoneName: 'deck' } as any;
|
||||
GamePersistence.zoneShuffled(5, 1, data);
|
||||
expect(GameDispatch.zoneShuffled).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('dieRolled dispatches via GameDispatch', () => {
|
||||
const data = { die: 6, result: 4 } as any;
|
||||
GamePersistence.dieRolled(5, 1, data);
|
||||
expect(GameDispatch.dieRolled).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('activePlayerSet dispatches via GameDispatch', () => {
|
||||
GamePersistence.activePlayerSet(5, 2);
|
||||
expect(GameDispatch.activePlayerSet).toHaveBeenCalledWith(5, 2);
|
||||
});
|
||||
|
||||
it('activePhaseSet dispatches via GameDispatch', () => {
|
||||
GamePersistence.activePhaseSet(5, 3);
|
||||
expect(GameDispatch.activePhaseSet).toHaveBeenCalledWith(5, 3);
|
||||
});
|
||||
|
||||
it('turnReversed dispatches via GameDispatch', () => {
|
||||
GamePersistence.turnReversed(5, true);
|
||||
expect(GameDispatch.turnReversed).toHaveBeenCalledWith(5, true);
|
||||
});
|
||||
|
||||
it('zoneDumped dispatches via GameDispatch', () => {
|
||||
const data = { zoneName: 'hand' } as any;
|
||||
GamePersistence.zoneDumped(5, 1, data);
|
||||
expect(GameDispatch.zoneDumped).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
|
||||
it('zonePropertiesChanged dispatches via GameDispatch', () => {
|
||||
const data = { zoneName: 'hand', alwaysRevealTopCard: true } as any;
|
||||
GamePersistence.zonePropertiesChanged(5, 1, data);
|
||||
expect(GameDispatch.zonePropertiesChanged).toHaveBeenCalledWith(5, 1, data);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -309,11 +309,10 @@ describe('SessionPersistence', () => {
|
|||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it('gameJoined logs to console', () => {
|
||||
const spy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
SessionPersistence.gameJoined({ gameInfo: {} } as any);
|
||||
expect(spy).toHaveBeenCalled();
|
||||
spy.mockRestore();
|
||||
it('gameJoined dispatches via GameDispatch.gameJoined', () => {
|
||||
const gameInfo = { gameId: 10, roomId: 2, description: 'test', started: false };
|
||||
SessionPersistence.gameJoined({ gameInfo, hostId: 3, playerId: 4, spectator: false, judge: false } as any);
|
||||
expect(GameDispatch.gameJoined).toHaveBeenCalledWith(10, expect.objectContaining({ gameId: 10, hostId: 3, localPlayerId: 4 }));
|
||||
});
|
||||
|
||||
it('notifyUser passes notification', () => {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ jest.mock('./ProtoController', () => ({
|
|||
|
||||
jest.mock('../WebClient', () => {
|
||||
const mockProtobuf = {
|
||||
sendGameCommand: jest.fn(),
|
||||
sendSessionCommand: jest.fn(),
|
||||
sendRoomCommand: jest.fn(),
|
||||
sendModeratorCommand: jest.fn(),
|
||||
|
|
@ -21,6 +22,8 @@ import webClient from '../WebClient';
|
|||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
ProtoController.root = makeMockProtoRoot();
|
||||
ProtoController.root.GameCommand = { create: jest.fn(args => ({ ...args })) };
|
||||
ProtoController.root['Command_Game'] = { create: jest.fn(p => ({ ...p })) };
|
||||
ProtoController.root['Command_Test'] = { create: jest.fn(p => ({ ...p })) };
|
||||
ProtoController.root['Command_Room'] = { create: jest.fn(p => ({ ...p })) };
|
||||
ProtoController.root['Command_Mod'] = { create: jest.fn(p => ({ ...p })) };
|
||||
|
|
@ -35,6 +38,7 @@ function captureCallback(sendFn: jest.Mock) {
|
|||
describe('BackendService', () => {
|
||||
describe('send commands', () => {
|
||||
it.each([
|
||||
['sendGameCommand', () => BackendService.sendGameCommand(7, 'Command_Game', { g: 1 })],
|
||||
['sendSessionCommand', () => BackendService.sendSessionCommand('Command_Test', { x: 1 }, {})],
|
||||
['sendRoomCommand', () => BackendService.sendRoomCommand(5, 'Command_Room', { y: 2 }, {})],
|
||||
['sendModeratorCommand', () => BackendService.sendModeratorCommand('Command_Mod', { z: 3 }, {})],
|
||||
|
|
@ -46,6 +50,14 @@ describe('BackendService', () => {
|
|||
});
|
||||
|
||||
describe('handleResponse via non-session command callbacks', () => {
|
||||
it('sendGameCommand callback invokes handleResponse', () => {
|
||||
const onSuccess = jest.fn();
|
||||
BackendService.sendGameCommand(7, 'Command_Game', {}, { onSuccess });
|
||||
const cb = (webClient.protobuf as any).sendGameCommand.mock.calls[0][2];
|
||||
cb({ responseCode: 0 });
|
||||
expect(onSuccess).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('sendRoomCommand callback invokes handleResponse', () => {
|
||||
const onSuccess = jest.fn();
|
||||
BackendService.sendRoomCommand(5, 'Command_Room', {}, { onSuccess });
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ jest.mock('../commands/session', () => ({
|
|||
}));
|
||||
|
||||
jest.mock('../events', () => ({
|
||||
CommonEvents: {},
|
||||
CommonEvents: { '.Event_Common.ext': jest.fn() },
|
||||
GameEvents: { '.Event_Game.ext': jest.fn() },
|
||||
RoomEvents: { '.Event_Room.ext': jest.fn() },
|
||||
SessionEvents: { '.Event_Session.ext': jest.fn() },
|
||||
|
|
@ -21,6 +21,7 @@ jest.mock('../WebClient');
|
|||
import { ProtobufService } from './ProtobufService';
|
||||
import { ProtoController } from './ProtoController';
|
||||
import { ping as sessionPing } from '../commands/session';
|
||||
import { GameEvents, CommonEvents } from '../events';
|
||||
|
||||
let mockSocket: any;
|
||||
let mockWebClient: any;
|
||||
|
|
@ -143,6 +144,35 @@ describe('ProtobufService', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('sendGameCommand', () => {
|
||||
it('creates a CommandContainer with gameId and gameCommand', () => {
|
||||
const service = new ProtobufService(mockWebClient);
|
||||
service.sendGameCommand(7, { gameCmdType: 'test' }, jest.fn());
|
||||
expect(ProtoController.root.CommandContainer.create).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ gameId: 7, gameCommand: expect.anything() })
|
||||
);
|
||||
});
|
||||
|
||||
it('invokes callback with raw response when the pending command is triggered', () => {
|
||||
const service = new ProtobufService(mockWebClient);
|
||||
const cb = jest.fn();
|
||||
service.sendGameCommand(7, { gameCmdType: 'test' }, cb);
|
||||
|
||||
const storedCb = (service as any).pendingCommands[1];
|
||||
storedCb({ responseData: true });
|
||||
|
||||
expect(cb).toHaveBeenCalledWith({ responseData: true });
|
||||
});
|
||||
|
||||
it('does not throw when no callback is provided and pending command is triggered', () => {
|
||||
const service = new ProtobufService(mockWebClient);
|
||||
service.sendGameCommand(7, { gameCmdType: 'test' });
|
||||
|
||||
const storedCb = (service as any).pendingCommands[1];
|
||||
expect(() => storedCb({ responseData: true })).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('sendModeratorCommand', () => {
|
||||
it('creates a CommandContainer with moderatorCommand', () => {
|
||||
const service = new ProtobufService(mockWebClient);
|
||||
|
|
@ -291,6 +321,54 @@ describe('ProtobufService', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('processCommonEvent', () => {
|
||||
it('delegates to processEvent with CommonEvents', () => {
|
||||
const service = new ProtobufService(mockWebClient);
|
||||
const processEvent = jest.spyOn(service as any, 'processEvent');
|
||||
const response = { '.Event_Common.ext': { data: 1 } };
|
||||
const raw = { extra: true };
|
||||
(service as any).processCommonEvent(response, raw);
|
||||
expect(processEvent).toHaveBeenCalledWith(response, CommonEvents, raw);
|
||||
});
|
||||
});
|
||||
|
||||
describe('processGameEvent', () => {
|
||||
it('returns early when container has no eventList', () => {
|
||||
const service = new ProtobufService(mockWebClient);
|
||||
const gameEventHandler = (GameEvents as any)['.Event_Game.ext'] as jest.Mock;
|
||||
(service as any).processGameEvent(null, {});
|
||||
expect(gameEventHandler).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('dispatches to a GameEvents handler when event key matches', () => {
|
||||
const service = new ProtobufService(mockWebClient);
|
||||
const gameEventHandler = (GameEvents as any)['.Event_Game.ext'] as jest.Mock;
|
||||
const payload = { someData: 1 };
|
||||
(service as any).processGameEvent({
|
||||
gameId: 42,
|
||||
context: null,
|
||||
secondsElapsed: 10,
|
||||
forcedByJudge: 0,
|
||||
eventList: [{ '.Event_Game.ext': payload, playerId: 5 }],
|
||||
}, {});
|
||||
expect(gameEventHandler).toHaveBeenCalledWith(payload, expect.objectContaining({ gameId: 42, playerId: 5 }));
|
||||
});
|
||||
|
||||
it('falls back to CommonEvents handler when no GameEvents key matches', () => {
|
||||
const service = new ProtobufService(mockWebClient);
|
||||
const commonEventHandler = (CommonEvents as any)['.Event_Common.ext'] as jest.Mock;
|
||||
const payload = { commonData: 2 };
|
||||
(service as any).processGameEvent({
|
||||
gameId: 7,
|
||||
context: null,
|
||||
secondsElapsed: 0,
|
||||
forcedByJudge: 0,
|
||||
eventList: [{ '.Event_Common.ext': payload, playerId: 3 }],
|
||||
}, {});
|
||||
expect(commonEventHandler).toHaveBeenCalledWith(payload, expect.objectContaining({ gameId: 7, playerId: 3 }));
|
||||
});
|
||||
});
|
||||
|
||||
describe('processEvent', () => {
|
||||
it('calls matching event handler with payload and raw', () => {
|
||||
const service = new ProtobufService(mockWebClient);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue