import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { act, fireEvent, render, screen } from '@testing-library/react'; import { FIND_THE_RING_MAX_WRONG_ATTEMPTS, FindTheRingGame } from '../../src/components/minigames/FindTheRingGame'; describe('FindTheRingGame', () => { beforeEach(() => { vi.useFakeTimers(); vi.spyOn(Math, 'random').mockReturnValue(0); }); afterEach(() => { vi.useRealTimers(); vi.restoreAllMocks(); }); it('shows start flow and reveals cups after shuffling', async () => { render(); fireEvent.click(screen.getByRole('button', { name: /Start Shuffling/i })); await act(async () => { vi.advanceTimersByTime(1300); }); expect(screen.getAllByRole('button').length).toBe(3); expect(screen.getByText(new RegExp(`Wrong guesses: 0/${FIND_THE_RING_MAX_WRONG_ATTEMPTS}`))).toBeTruthy(); }); it('fails on the third wrong guess', async () => { const onFail = vi.fn(); render(); fireEvent.click(screen.getByRole('button', { name: /Start Shuffling/i })); await act(async () => { vi.advanceTimersByTime(1300); }); const clickWrongCup = async (name: string) => { fireEvent.click(screen.getByRole('button', { name })); await act(async () => { vi.advanceTimersByTime(850); }); }; await clickWrongCup('Cup 2'); await clickWrongCup('Cup 3'); await clickWrongCup('Cup 2'); await act(async () => { vi.runOnlyPendingTimers(); }); expect(onFail).toHaveBeenCalledTimes(1); }); it('succeeds when the player picks the correct cup', async () => { const onSuccess = vi.fn(); render(); fireEvent.click(screen.getByRole('button', { name: /Start Shuffling/i })); await act(async () => { vi.advanceTimersByTime(1300); }); fireEvent.click(screen.getByRole('button', { name: 'Cup 1' })); await act(async () => { vi.runOnlyPendingTimers(); }); expect(onSuccess).toHaveBeenCalledTimes(1); }); });