71 lines
2.1 KiB
TypeScript
71 lines
2.1 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
import { act, fireEvent, render, screen } from '@testing-library/react';
|
|
import { REACTION_SUCCESS_THRESHOLD_MS, ReactionGame } from '../../src/components/minigames/ReactionGame';
|
|
|
|
describe('ReactionGame', () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(new Date('2026-03-18T12:00:00Z'));
|
|
vi.spyOn(Math, 'random').mockReturnValue(0);
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it('fails on an early click before GO appears', () => {
|
|
const onFail = vi.fn();
|
|
render(<ReactionGame onSuccess={vi.fn()} onFail={onFail} />);
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: /Wait for GO!/i }));
|
|
act(() => {
|
|
vi.advanceTimersByTime(1000);
|
|
});
|
|
|
|
expect(onFail).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('shows the cue after the randomized delay', () => {
|
|
render(<ReactionGame onSuccess={vi.fn()} onFail={vi.fn()} />);
|
|
|
|
act(() => {
|
|
vi.advanceTimersByTime(1000);
|
|
});
|
|
expect(screen.getByText('GO!')).toBeTruthy();
|
|
});
|
|
|
|
it('succeeds when reaction time is 500ms or faster', () => {
|
|
const onSuccess = vi.fn();
|
|
render(<ReactionGame onSuccess={onSuccess} onFail={vi.fn()} />);
|
|
|
|
act(() => {
|
|
vi.advanceTimersByTime(1000);
|
|
});
|
|
vi.setSystemTime(new Date('2026-03-18T12:00:01.350Z'));
|
|
fireEvent.click(screen.getByRole('button', { name: /CLICK!/i }));
|
|
act(() => {
|
|
vi.advanceTimersByTime(1000);
|
|
});
|
|
|
|
expect(screen.getByText(/350/)).toBeTruthy();
|
|
expect(onSuccess).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('fails when reaction time is slower than the threshold', () => {
|
|
const onFail = vi.fn();
|
|
render(<ReactionGame onSuccess={vi.fn()} onFail={onFail} />);
|
|
|
|
act(() => {
|
|
vi.advanceTimersByTime(1000);
|
|
});
|
|
vi.setSystemTime(new Date(`2026-03-18T12:00:01.${REACTION_SUCCESS_THRESHOLD_MS + 150}Z`));
|
|
fireEvent.click(screen.getByRole('button', { name: /CLICK!/i }));
|
|
act(() => {
|
|
vi.advanceTimersByTime(1000);
|
|
});
|
|
|
|
expect(onFail).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|