| name | masoi-e2e-testing |
| description | Create and maintain automated tests for Ma Sói game engine, night/vote resolution, Socket.IO event contracts, race conditions, and role-specific edge cases. Use when adding test coverage, debugging flaky behavior, verifying concurrent action handling, or setting up CI testing. |
Ma Sói E2E Testing
Workflow
- Identify the component to test:
server/gameEngine.js → pure function unit tests.
server/index.js resolution logic → integration tests with mock socket/redis.
- Socket contract → client-server event flow tests.
- Write tests following patterns in
references/test-patterns.md.
- Run tests:
cd server && npm test (if test script configured).
node --check server/index.js (syntax baseline).
- For race condition tests, simulate concurrent socket events and verify single resolution.
Test Categories
Unit Tests (Pure Functions)
calcWolfCount(n) for various player counts.
getRoleConfig(n, customRoles) produces valid role lists.
sanitizeCustomRoles(roles, n) enforces wolf count limits.
assignRoles(players, customRoles) returns exactly n assignments.
checkWinCondition(players) for all win/draw states.
generateRoomCode() produces valid 6-character codes.
Integration Tests (Game Flow)
- Night resolution: wolf kill, doctor save, witch save, witch poison, combinations.
- Vote resolution: majority vote, tie, idiot reveal, wolf king drag, hunter shoot.
- Phase transitions: night → discuss → vote → night cycle.
- Game end: village win (all wolves dead), wolf win (wolves >= others).
- Timer-driven resolution: night timeout forces skip, vote timeout forces resolve.
Contract Tests (Socket Events)
- Every client emit has a matching server handler.
- Every server emit used by gameplay has a matching client listener.
- Payload shapes match between server emit and client handler.
- Reconnect emits restore full game state.
Race Condition Tests
- Two wolves choosing different targets simultaneously.
- All players voting at the same time.
- Night resolve and timer-forced resolve firing concurrently.
- Vote resolve and timer-forced resolve firing concurrently.
- Disconnect and reconnect during night resolution.
Edge Case Tests
- Doctor saves wolf target, then witch also saves same target.
- Witch poisons the same player wolves attacked (double kill?).
- Hunter dies from poison, shoots another player who triggers chain effects.
- Wolf King hanged, drags Hunter, Hunter shoots → chain resolution.
- Idiot hanged twice — second time should kill.
- Only 1 wolf vs 1 villager — wolf wins immediately.
- All special roles dead — game still resolves correctly.
Test Infrastructure
Recommended Setup
- Test runner: Node.js built-in test runner (
node --test) or Jest/Vitest.
- Mock Redis: In-memory Map-based mock for
server/db/redis.js.
- Mock PostgreSQL: No-op mock for
server/db/postgres.js (game logic doesn't depend on DB reads).
- Mock Socket.IO: Track emitted events and payloads for assertion.
Test File Structure
server/
__tests__/
gameEngine.test.js # Unit tests for pure functions
nightResolve.test.js # Integration tests for night resolution
voteResolve.test.js # Integration tests for vote resolution
socketContract.test.js # Contract verification
raceCondition.test.js # Concurrent action tests
References
Load references/test-patterns.md when writing or reviewing automated tests.