174 lines
6.3 KiB
JavaScript
174 lines
6.3 KiB
JavaScript
const { EcastShardClient } = require('../../backend/utils/ecast-shard-client');
|
|
|
|
describe('EcastShardClient', () => {
|
|
describe('parsePlayersFromHere', () => {
|
|
test('counts only player roles, excludes host and shard', () => {
|
|
const here = {
|
|
'1': { id: 1, roles: { host: {} } },
|
|
'2': { id: 2, roles: { player: { name: 'Alice' } } },
|
|
'3': { id: 3, roles: { player: { name: 'Bob' } } },
|
|
'5': { id: 5, roles: { shard: {} } },
|
|
};
|
|
const result = EcastShardClient.parsePlayersFromHere(here);
|
|
expect(result.playerCount).toBe(2);
|
|
expect(result.playerNames).toEqual(['Alice', 'Bob']);
|
|
});
|
|
|
|
test('returns zero for empty here or host-only', () => {
|
|
const here = { '1': { id: 1, roles: { host: {} } } };
|
|
const result = EcastShardClient.parsePlayersFromHere(here);
|
|
expect(result.playerCount).toBe(0);
|
|
expect(result.playerNames).toEqual([]);
|
|
});
|
|
|
|
test('handles null or undefined here', () => {
|
|
expect(EcastShardClient.parsePlayersFromHere(null).playerCount).toBe(0);
|
|
expect(EcastShardClient.parsePlayersFromHere(undefined).playerCount).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('parseRoomEntity', () => {
|
|
test('extracts lobby state from room entity val', () => {
|
|
const roomVal = {
|
|
state: 'Lobby',
|
|
lobbyState: 'CanStart',
|
|
gameCanStart: true,
|
|
gameIsStarting: false,
|
|
gameFinished: false,
|
|
};
|
|
const result = EcastShardClient.parseRoomEntity(roomVal);
|
|
expect(result.gameState).toBe('Lobby');
|
|
expect(result.lobbyState).toBe('CanStart');
|
|
expect(result.gameCanStart).toBe(true);
|
|
expect(result.gameStarted).toBe(false);
|
|
expect(result.gameFinished).toBe(false);
|
|
});
|
|
|
|
test('detects game started from Gameplay state', () => {
|
|
const roomVal = { state: 'Gameplay', lobbyState: 'Countdown', gameCanStart: true, gameIsStarting: false, gameFinished: false };
|
|
const result = EcastShardClient.parseRoomEntity(roomVal);
|
|
expect(result.gameStarted).toBe(true);
|
|
});
|
|
|
|
test('detects game finished', () => {
|
|
const roomVal = { state: 'Gameplay', lobbyState: '', gameCanStart: true, gameIsStarting: false, gameFinished: true };
|
|
const result = EcastShardClient.parseRoomEntity(roomVal);
|
|
expect(result.gameFinished).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('parsePlayerJoinFromTextDescriptions', () => {
|
|
test('extracts player name from join description', () => {
|
|
const val = {
|
|
latestDescriptions: [
|
|
{ category: 'TEXT_DESCRIPTION_PLAYER_JOINED', text: 'Charlie joined.' }
|
|
]
|
|
};
|
|
const result = EcastShardClient.parsePlayerJoinFromTextDescriptions(val);
|
|
expect(result).toEqual([{ name: 'Charlie', isVIP: false }]);
|
|
});
|
|
|
|
test('extracts VIP join', () => {
|
|
const val = {
|
|
latestDescriptions: [
|
|
{ category: 'TEXT_DESCRIPTION_PLAYER_JOINED_VIP', text: 'Alice joined and is the VIP.' }
|
|
]
|
|
};
|
|
const result = EcastShardClient.parsePlayerJoinFromTextDescriptions(val);
|
|
expect(result).toEqual([{ name: 'Alice', isVIP: true }]);
|
|
});
|
|
|
|
test('returns empty array for no joins', () => {
|
|
const val = { latestDescriptions: [] };
|
|
expect(EcastShardClient.parsePlayerJoinFromTextDescriptions(val)).toEqual([]);
|
|
});
|
|
|
|
test('handles null/undefined val', () => {
|
|
expect(EcastShardClient.parsePlayerJoinFromTextDescriptions(null)).toEqual([]);
|
|
expect(EcastShardClient.parsePlayerJoinFromTextDescriptions(undefined)).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('constructor', () => {
|
|
test('initializes with correct defaults', () => {
|
|
const client = new EcastShardClient({
|
|
sessionId: 1, gameId: 5, roomCode: 'TEST', maxPlayers: 8, onEvent: () => {}
|
|
});
|
|
expect(client.sessionId).toBe(1);
|
|
expect(client.gameId).toBe(5);
|
|
expect(client.roomCode).toBe('TEST');
|
|
expect(client.maxPlayers).toBe(8);
|
|
expect(client.playerCount).toBe(0);
|
|
expect(client.playerNames).toEqual([]);
|
|
expect(client.gameStarted).toBe(false);
|
|
expect(client.gameFinished).toBe(false);
|
|
expect(client.ws).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('handleWelcome', () => {
|
|
test('parses welcome message and sets internal state', () => {
|
|
const client = new EcastShardClient({
|
|
sessionId: 1, gameId: 5, roomCode: 'TEST', maxPlayers: 8, onEvent: () => {}
|
|
});
|
|
|
|
client.handleWelcome({
|
|
id: 7,
|
|
secret: 'abc-123',
|
|
reconnect: false,
|
|
entities: {
|
|
room: ['object', { key: 'room', val: { state: 'Lobby', lobbyState: 'CanStart', gameCanStart: true, gameIsStarting: false, gameFinished: false }, version: 0, from: 1 }, { locked: false }]
|
|
},
|
|
here: {
|
|
'1': { id: 1, roles: { host: {} } },
|
|
'2': { id: 2, roles: { player: { name: 'Alice' } } },
|
|
'3': { id: 3, roles: { player: { name: 'Bob' } } },
|
|
}
|
|
});
|
|
|
|
expect(client.shardId).toBe(7);
|
|
expect(client.secret).toBe('abc-123');
|
|
expect(client.playerCount).toBe(2);
|
|
expect(client.playerNames).toEqual(['Alice', 'Bob']);
|
|
expect(client.gameState).toBe('Lobby');
|
|
expect(client.lobbyState).toBe('CanStart');
|
|
expect(client.gameStarted).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('handleEntityUpdate', () => {
|
|
test('updates room state on room entity update', () => {
|
|
const client = new EcastShardClient({
|
|
sessionId: 1, gameId: 5, roomCode: 'TEST', maxPlayers: 8, onEvent: () => {}
|
|
});
|
|
client.gameState = 'Lobby';
|
|
client.lobbyState = 'WaitingForMore';
|
|
|
|
client.handleEntityUpdate({
|
|
key: 'room',
|
|
val: { state: 'Gameplay', lobbyState: 'Countdown', gameCanStart: true, gameIsStarting: true, gameFinished: false },
|
|
version: 5,
|
|
from: 1
|
|
});
|
|
|
|
expect(client.gameState).toBe('Gameplay');
|
|
expect(client.gameStarted).toBe(true);
|
|
});
|
|
|
|
test('handles bc:room key as room update', () => {
|
|
const client = new EcastShardClient({
|
|
sessionId: 1, gameId: 5, roomCode: 'TEST', maxPlayers: 8, onEvent: () => {}
|
|
});
|
|
|
|
client.handleEntityUpdate({
|
|
key: 'bc:room',
|
|
val: { state: 'Lobby', lobbyState: 'CanStart', gameCanStart: true, gameIsStarting: false, gameFinished: false },
|
|
version: 1,
|
|
from: 1
|
|
});
|
|
|
|
expect(client.lobbyState).toBe('CanStart');
|
|
});
|
|
});
|
|
});
|