import { render, screen } from '@testing-library/react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import { AchievementGrid } from './AchievementGrid'; // Mock the AchievementDisplay module vi.mock('@/lib/display-objects/AchievementDisplay', () => ({ AchievementDisplay: { getRarityVariant: vi.fn((rarity) => { const rarityMap = { common: { text: 'low', surface: 'rarity-common', iconIntent: 'low' }, rare: { text: 'primary', surface: 'rarity-rare', iconIntent: 'primary' }, epic: { text: 'primary', surface: 'rarity-epic', iconIntent: 'primary' }, legendary: { text: 'warning', surface: 'rarity-legendary', iconIntent: 'warning' }, }; return rarityMap[rarity as keyof typeof rarityMap] || rarityMap.common; }), }, })); describe('AchievementGrid', () => { const mockAchievements = [ { id: '1', title: 'First Victory', description: 'Win your first race', icon: 'trophy', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }, { id: '2', title: 'Speed Demon', description: 'Reach 200 mph', icon: 'zap', rarity: 'rare', earnedAtLabel: 'Feb 20, 2024', }, { id: '3', title: 'Champion', description: 'Win 10 races', icon: 'crown', rarity: 'epic', earnedAtLabel: 'Mar 10, 2024', }, { id: '4', title: 'Legend', description: 'Win 100 races', icon: 'star', rarity: 'legendary', earnedAtLabel: 'Apr 5, 2024', }, ]; beforeEach(() => { vi.clearAllMocks(); }); describe('Rendering', () => { it('renders the header with correct title', () => { render(); expect(screen.getByText('Achievements')).toBeDefined(); }); it('renders the correct count of achievements', () => { render(); expect(screen.getByText('4 earned')).toBeDefined(); }); it('renders all achievement items', () => { render(); mockAchievements.forEach((achievement) => { expect(screen.getByText(achievement.title)).toBeDefined(); expect(screen.getByText(achievement.description)).toBeDefined(); expect(screen.getByText(achievement.earnedAtLabel)).toBeDefined(); }); }); it('renders achievement icons correctly', () => { render(); // Check that the icon mapping works expect(screen.getByText('First Victory')).toBeDefined(); expect(screen.getByText('Speed Demon')).toBeDefined(); expect(screen.getByText('Champion')).toBeDefined(); expect(screen.getByText('Legend')).toBeDefined(); }); it('renders achievement rarities correctly', () => { render(); expect(screen.getByText('common')).toBeDefined(); expect(screen.getByText('rare')).toBeDefined(); expect(screen.getByText('epic')).toBeDefined(); expect(screen.getByText('legendary')).toBeDefined(); }); }); describe('Empty states', () => { it('renders with empty achievements array', () => { render(); expect(screen.getByText('Achievements')).toBeDefined(); expect(screen.getByText('0 earned')).toBeDefined(); }); it('renders with single achievement', () => { const singleAchievement = [mockAchievements[0]]; render(); expect(screen.getByText('Achievements')).toBeDefined(); expect(screen.getByText('1 earned')).toBeDefined(); expect(screen.getByText('First Victory')).toBeDefined(); }); }); describe('Icon mapping', () => { it('maps trophy icon correctly', () => { const trophyAchievement = { id: '1', title: 'Trophy Achievement', description: 'Test description', icon: 'trophy', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('Trophy Achievement')).toBeDefined(); }); it('maps medal icon correctly', () => { const medalAchievement = { id: '2', title: 'Medal Achievement', description: 'Test description', icon: 'medal', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('Medal Achievement')).toBeDefined(); }); it('maps star icon correctly', () => { const starAchievement = { id: '3', title: 'Star Achievement', description: 'Test description', icon: 'star', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('Star Achievement')).toBeDefined(); }); it('maps crown icon correctly', () => { const crownAchievement = { id: '4', title: 'Crown Achievement', description: 'Test description', icon: 'crown', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('Crown Achievement')).toBeDefined(); }); it('maps target icon correctly', () => { const targetAchievement = { id: '5', title: 'Target Achievement', description: 'Test description', icon: 'target', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('Target Achievement')).toBeDefined(); }); it('maps zap icon correctly', () => { const zapAchievement = { id: '6', title: 'Zap Achievement', description: 'Test description', icon: 'zap', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('Zap Achievement')).toBeDefined(); }); it('defaults to award icon for unknown icon', () => { const unknownIconAchievement = { id: '7', title: 'Unknown Icon Achievement', description: 'Test description', icon: 'unknown', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('Unknown Icon Achievement')).toBeDefined(); }); }); describe('Rarity display', () => { it('applies correct rarity variant for common', () => { const commonAchievement = { id: '1', title: 'Common Achievement', description: 'Test description', icon: 'trophy', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('common')).toBeDefined(); }); it('applies correct rarity variant for rare', () => { const rareAchievement = { id: '2', title: 'Rare Achievement', description: 'Test description', icon: 'trophy', rarity: 'rare', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('rare')).toBeDefined(); }); it('applies correct rarity variant for epic', () => { const epicAchievement = { id: '3', title: 'Epic Achievement', description: 'Test description', icon: 'trophy', rarity: 'epic', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('epic')).toBeDefined(); }); it('applies correct rarity variant for legendary', () => { const legendaryAchievement = { id: '4', title: 'Legendary Achievement', description: 'Test description', icon: 'trophy', rarity: 'legendary', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('legendary')).toBeDefined(); }); it('handles unknown rarity gracefully', () => { const unknownRarityAchievement = { id: '5', title: 'Unknown Rarity Achievement', description: 'Test description', icon: 'trophy', rarity: 'unknown', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('unknown')).toBeDefined(); }); }); describe('Multiple achievements', () => { it('renders multiple achievements with different rarities', () => { render(); // Check all titles are rendered mockAchievements.forEach((achievement) => { expect(screen.getByText(achievement.title)).toBeDefined(); }); // Check all descriptions are rendered mockAchievements.forEach((achievement) => { expect(screen.getByText(achievement.description)).toBeDefined(); }); // Check all earned labels are rendered mockAchievements.forEach((achievement) => { expect(screen.getByText(achievement.earnedAtLabel)).toBeDefined(); }); }); it('renders achievements in order', () => { render(); // The component should render achievements in the order they are provided const titles = screen.getAllByText(/Achievement|Victory|Demon|Champion|Legend/); expect(titles.length).toBe(4); }); }); describe('Edge cases', () => { it('handles achievements with long titles', () => { const longTitleAchievement = { id: '1', title: 'This is an extremely long achievement title that should still be displayed correctly without breaking the layout', description: 'Test description', icon: 'trophy', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText(longTitleAchievement.title)).toBeDefined(); }); it('handles achievements with long descriptions', () => { const longDescriptionAchievement = { id: '1', title: 'Achievement', description: 'This is a very long description that spans multiple lines and contains detailed information about the achievement and its requirements', icon: 'trophy', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText(longDescriptionAchievement.description)).toBeDefined(); }); it('handles achievements with special characters in title', () => { const specialTitleAchievement = { id: '1', title: 'Champion\'s Trophy #1!', description: 'Test description', icon: 'trophy', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText(specialTitleAchievement.title)).toBeDefined(); }); it('handles achievements with unicode characters in icon', () => { const unicodeIconAchievement = { id: '1', title: 'Unicode Achievement', description: 'Test description', icon: '🌟', rarity: 'common', earnedAtLabel: 'Jan 15, 2024', }; render(); expect(screen.getByText('Unicode Achievement')).toBeDefined(); }); }); });