import { describe, it, expect, beforeEach } from 'vitest' import { setActivePinia, createPinia } from 'pinia' import { useGameStore } from '../../src/stores/game' describe('stores/game (Pinia)', () => { beforeEach(() => { setActivePinia(createPinia()) }) it('a un état initial vide/par défaut', () => { const store = useGameStore() expect(store.playerName).toBe('') expect(store.players).toEqual([]) expect(store.currentTurn).toBe(0) expect(store.maxTurns).toBe(12) expect(store.phase).toBe('idle') expect(store.hand).toEqual([]) expect(store.myTeamIndex).toBe(0) expect(store.selectedCard).toBeNull() expect(store.myItems).toEqual([]) expect(store.pendingBuyItemId).toBeNull() expect(store.availableItems).toEqual([]) expect(store.firstPlayerName).toBeNull() expect(store.myBuildings).toEqual([]) expect(store.pendingBuyBuildingId).toBeNull() expect(store.availableBuildings).toEqual([]) expect(store.myEventHand).toEqual([]) expect(store.eventDeckSize).toBe(0) expect(store.hasPendingEventDraw).toBe(false) expect(store.pendingEventPlayId).toBeNull() expect(store.gameOverResults).toBeNull() }) it('setPlayer met à jour playerName', () => { const store = useGameStore() store.setPlayer('Alice') expect(store.playerName).toBe('Alice') }) describe('updateState', () => { it('met à jour tous les champs de base depuis un game-state serveur', () => { const store = useGameStore() store.updateState({ players: [{ name: 'Alice', score: 5 }], currentTurn: 3, maxTurns: 12, phase: 'selecting', hand: [{ id: 'queen' }], myTeamIndex: 1 }) expect(store.players).toEqual([{ name: 'Alice', score: 5 }]) expect(store.currentTurn).toBe(3) expect(store.maxTurns).toBe(12) expect(store.phase).toBe('selecting') expect(store.hand).toEqual([{ id: 'queen' }]) expect(store.myTeamIndex).toBe(1) }) it('retombe sur les valeurs par défaut si les champs sont absents (sauf hand/items qui restent inchangés)', () => { const store = useGameStore() store.updateState({}) expect(store.players).toEqual([]) expect(store.currentTurn).toBe(0) expect(store.maxTurns).toBe(12) expect(store.phase).toBe('idle') expect(store.myTeamIndex).toBe(0) }) it('ne touche PAS à hand si state.hand est undefined (évite d\'effacer la main en cours)', () => { const store = useGameStore() store.updateState({ hand: [{ id: 'prince' }] }) store.updateState({ phase: 'waiting' }) // pas de champ hand cette fois expect(store.hand).toEqual([{ id: 'prince' }]) }) it('met à jour les champs liés aux objets uniquement s\'ils sont fournis', () => { const store = useGameStore() store.updateState({ myItems: ['trebuchet'], pendingBuyItemId: 'plow', availableItems: ['medkit', 'royal_seal'], firstPlayerName: 'Bob' }) expect(store.myItems).toEqual(['trebuchet']) expect(store.pendingBuyItemId).toBe('plow') expect(store.availableItems).toEqual(['medkit', 'royal_seal']) expect(store.firstPlayerName).toBe('Bob') // Un second appel sans ces champs ne doit pas les réinitialiser store.updateState({ phase: 'resolve' }) expect(store.myItems).toEqual(['trebuchet']) expect(store.pendingBuyItemId).toBe('plow') }) it('accepte explicitement pendingBuyItemId=null (achat annulé/résolu) sans le confondre avec "absent"', () => { const store = useGameStore() store.updateState({ pendingBuyItemId: 'plow' }) store.updateState({ pendingBuyItemId: null }) expect(store.pendingBuyItemId).toBeNull() }) it('met à jour les champs liés aux bâtiments uniquement s\'ils sont fournis', () => { const store = useGameStore() store.updateState({ myBuildings: ['church'], pendingBuyBuildingId: 'castle', availableBuildings: ['castle'] }) expect(store.myBuildings).toEqual(['church']) expect(store.pendingBuyBuildingId).toBe('castle') expect(store.availableBuildings).toEqual(['castle']) // Un second appel sans ces champs ne doit pas les réinitialiser store.updateState({ phase: 'resolve' }) expect(store.myBuildings).toEqual(['church']) expect(store.pendingBuyBuildingId).toBe('castle') }) it('accepte explicitement pendingBuyBuildingId=null sans le confondre avec "absent"', () => { const store = useGameStore() store.updateState({ pendingBuyBuildingId: 'castle' }) store.updateState({ pendingBuyBuildingId: null }) expect(store.pendingBuyBuildingId).toBeNull() }) it('met à jour les champs liés aux cartes Événement uniquement s\'ils sont fournis', () => { const store = useGameStore() store.updateState({ myEventHand: ['bountiful_harvest', 'epidemic'], eventDeckSize: 15, hasPendingEventDraw: true, pendingEventPlayId: 'epidemic' }) expect(store.myEventHand).toEqual(['bountiful_harvest', 'epidemic']) expect(store.eventDeckSize).toBe(15) expect(store.hasPendingEventDraw).toBe(true) expect(store.pendingEventPlayId).toBe('epidemic') // Un second appel sans ces champs ne doit pas les réinitialiser store.updateState({ phase: 'resolve' }) expect(store.myEventHand).toEqual(['bountiful_harvest', 'epidemic']) expect(store.eventDeckSize).toBe(15) }) it('accepte explicitement pendingEventPlayId=null et hasPendingEventDraw=false sans les confondre avec "absent"', () => { const store = useGameStore() store.updateState({ pendingEventPlayId: 'epidemic', hasPendingEventDraw: true }) store.updateState({ pendingEventPlayId: null, hasPendingEventDraw: false }) expect(store.pendingEventPlayId).toBeNull() expect(store.hasPendingEventDraw).toBe(false) }) }) describe('selectCard / clearSelection', () => { it('selectCard définit la carte sélectionnée', () => { const store = useGameStore() const card = { id: 'knight', war: 5 } store.selectCard(card) expect(store.selectedCard).toEqual(card) }) it('clearSelection remet selectedCard à null', () => { const store = useGameStore() store.selectCard({ id: 'knight' }) store.clearSelection() expect(store.selectedCard).toBeNull() }) }) describe('setGameOver', () => { it('définit gameOverResults avec les résultats fournis', () => { const store = useGameStore() const results = [{ name: 'Alice', score: 42 }, { name: 'Bob', score: 30 }] store.setGameOver(results) expect(store.gameOverResults).toEqual(results) }) }) describe('reset', () => { it('remet tout l\'état à ses valeurs par défaut', () => { const store = useGameStore() store.setPlayer('Alice') store.updateState({ players: [{ name: 'Alice' }], currentTurn: 5, phase: 'resolve', hand: [{ id: 'queen' }], myTeamIndex: 2, myItems: ['trebuchet'], pendingBuyItemId: 'plow', availableItems: ['medkit'], firstPlayerName: 'Bob', myBuildings: ['church'], pendingBuyBuildingId: 'castle', availableBuildings: ['castle'], myEventHand: ['epidemic'], eventDeckSize: 10, hasPendingEventDraw: true, pendingEventPlayId: 'epidemic' }) store.selectCard({ id: 'queen' }) store.setGameOver([{ name: 'Alice', score: 10 }]) store.reset() expect(store.players).toEqual([]) expect(store.currentTurn).toBe(0) expect(store.maxTurns).toBe(12) expect(store.phase).toBe('idle') expect(store.hand).toEqual([]) expect(store.myTeamIndex).toBe(0) expect(store.selectedCard).toBeNull() expect(store.myItems).toEqual([]) expect(store.pendingBuyItemId).toBeNull() expect(store.availableItems).toEqual([]) expect(store.firstPlayerName).toBeNull() expect(store.myBuildings).toEqual([]) expect(store.pendingBuyBuildingId).toBeNull() expect(store.availableBuildings).toEqual([]) expect(store.myEventHand).toEqual([]) expect(store.eventDeckSize).toBe(0) expect(store.hasPendingEventDraw).toBe(false) expect(store.pendingEventPlayId).toBeNull() expect(store.gameOverResults).toBeNull() // playerName n'est PAS réinitialisé par reset() (comportement existant : // le nom du joueur est conservé pour rejouer une partie sans le re-saisir) expect(store.playerName).toBe('Alice') }) }) })