lotr-sut/sut/frontend/test/components/QuestCompletionModal.test.tsx
Fellowship Scholar f6a5823439 init commit
2026-03-29 20:07:56 +00:00

108 lines
3.2 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { QuestCompletionModal } from '../../src/components/minigames/QuestCompletionModal';
vi.mock('../../src/components/minigames/TriviaGame', () => ({
TriviaGame: ({ onSuccess, onFail }: { onSuccess: () => void; onFail: () => void }) => (
<div>
<h3>Mock Trivia</h3>
<button onClick={onSuccess}>Win Mini-game</button>
<button onClick={onFail}>Lose Mini-game</button>
</div>
),
}));
vi.mock('../../src/components/minigames/MemoryGame', () => ({
MemoryGame: ({ onSuccess, onFail }: { onSuccess: () => void; onFail: () => void }) => (
<div>
<h3>Mock Memory</h3>
<button onClick={onSuccess}>Win Mini-game</button>
<button onClick={onFail}>Lose Mini-game</button>
</div>
),
}));
vi.mock('../../src/components/minigames/ReactionGame', () => ({
ReactionGame: ({ onSuccess, onFail }: { onSuccess: () => void; onFail: () => void }) => (
<div>
<h3>Mock Reaction</h3>
<button onClick={onSuccess}>Win Mini-game</button>
<button onClick={onFail}>Lose Mini-game</button>
</div>
),
}));
vi.mock('../../src/components/minigames/FindTheRingGame', () => ({
FindTheRingGame: ({ onSuccess, onFail }: { onSuccess: () => void; onFail: () => void }) => (
<div>
<h3>Mock Find Ring</h3>
<button onClick={onSuccess}>Win Mini-game</button>
<button onClick={onFail}>Lose Mini-game</button>
</div>
),
}));
describe('QuestCompletionModal integration', () => {
beforeEach(() => {
vi.useRealTimers();
vi.spyOn(Math, 'random').mockReturnValue(0);
});
afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();
});
it('completes a quest only after winning and claiming reward', async () => {
const onClose = vi.fn();
const onComplete = vi.fn().mockResolvedValue(undefined);
render(
<QuestCompletionModal
isOpen={true}
onClose={onClose}
onComplete={onComplete}
questId={42}
questTitle="Destroy the One Ring"
/>
);
expect(await screen.findByText('Mock Trivia')).toBeTruthy();
fireEvent.click(screen.getByRole('button', { name: 'Win Mini-game' }));
fireEvent.click(await screen.findByRole('button', { name: /Claim Reward/i }));
await waitFor(() => {
expect(onComplete).toHaveBeenCalledWith(42);
expect(onClose).toHaveBeenCalled();
});
});
it('keeps modal open and does not complete on mini-game failure', async () => {
const onClose = vi.fn();
const onComplete = vi.fn().mockResolvedValue(undefined);
render(
<QuestCompletionModal
isOpen={true}
onClose={onClose}
onComplete={onComplete}
questId={99}
questTitle="Guard the Shire"
/>
);
expect(await screen.findByText('Mock Trivia')).toBeTruthy();
fireEvent.click(screen.getByRole('button', { name: 'Lose Mini-game' }));
expect(screen.getByText(/Resetting challenge/i)).toBeTruthy();
await waitFor(() => {
expect(screen.getByText('Mock Trivia')).toBeTruthy();
}, { timeout: 1500 });
expect(onComplete).not.toHaveBeenCalled();
expect(onClose).not.toHaveBeenCalled();
});
});