214 lines
5.9 KiB
TypeScript
214 lines
5.9 KiB
TypeScript
import { render, screen } from '@testing-library/react';
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { AchievementCard } from './AchievementCard';
|
|
|
|
// Mock the DateDisplay module
|
|
vi.mock('@/lib/display-objects/DateDisplay', () => ({
|
|
DateDisplay: {
|
|
formatShort: vi.fn((date) => `Formatted: ${date}`),
|
|
},
|
|
}));
|
|
|
|
describe('AchievementCard', () => {
|
|
const mockProps = {
|
|
title: 'First Victory',
|
|
description: 'Win your first race',
|
|
icon: '🏆',
|
|
unlockedAt: '2024-01-15T10:30:00Z',
|
|
rarity: 'common' as const,
|
|
};
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('Rendering', () => {
|
|
it('renders all achievement information correctly', () => {
|
|
render(<AchievementCard {...mockProps} />);
|
|
|
|
expect(screen.getByText('🏆')).toBeDefined();
|
|
expect(screen.getByText('First Victory')).toBeDefined();
|
|
expect(screen.getByText('Win your first race')).toBeDefined();
|
|
expect(screen.getByText('Formatted: 2024-01-15T10:30:00Z')).toBeDefined();
|
|
});
|
|
|
|
it('renders with different rarity variants', () => {
|
|
const rarities = ['common', 'rare', 'epic', 'legendary'] as const;
|
|
|
|
rarities.forEach((rarity) => {
|
|
const { container } = render(
|
|
<AchievementCard {...mockProps} rarity={rarity} />
|
|
);
|
|
|
|
// The Card component should receive the correct variant
|
|
expect(container.firstChild).toBeDefined();
|
|
});
|
|
});
|
|
|
|
it('renders with different icons', () => {
|
|
const icons = ['🏆', '🥇', '⭐', '💎', '🎯'];
|
|
|
|
icons.forEach((icon) => {
|
|
render(<AchievementCard {...mockProps} icon={icon} />);
|
|
expect(screen.getByText(icon)).toBeDefined();
|
|
});
|
|
});
|
|
|
|
it('renders with long description', () => {
|
|
const longDescription = 'This is a very long description that spans multiple lines and contains detailed information about the achievement and its requirements';
|
|
|
|
render(
|
|
<AchievementCard
|
|
{...mockProps}
|
|
description={longDescription}
|
|
/>
|
|
);
|
|
|
|
expect(screen.getByText(longDescription)).toBeDefined();
|
|
});
|
|
|
|
it('renders with special characters in title', () => {
|
|
const specialTitle = 'Champion\'s Trophy #1!';
|
|
|
|
render(
|
|
<AchievementCard
|
|
{...mockProps}
|
|
title={specialTitle}
|
|
/>
|
|
);
|
|
|
|
expect(screen.getByText(specialTitle)).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('Date formatting', () => {
|
|
it('calls DateDisplay.formatShort with the correct date', () => {
|
|
const { DateDisplay } = require('@/lib/display-objects/DateDisplay');
|
|
|
|
render(<AchievementCard {...mockProps} />);
|
|
|
|
expect(DateDisplay.formatShort).toHaveBeenCalledWith('2024-01-15T10:30:00Z');
|
|
});
|
|
|
|
it('handles different date formats', () => {
|
|
const { DateDisplay } = require('@/lib/display-objects/DateDisplay');
|
|
|
|
const differentDates = [
|
|
'2024-01-15T10:30:00Z',
|
|
'2024-12-31T23:59:59Z',
|
|
'2023-06-15T08:00:00Z',
|
|
];
|
|
|
|
differentDates.forEach((date) => {
|
|
render(<AchievementCard {...mockProps} unlockedAt={date} />);
|
|
expect(DateDisplay.formatShort).toHaveBeenCalledWith(date);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Rarity styling', () => {
|
|
it('applies correct variant for common rarity', () => {
|
|
const { container } = render(
|
|
<AchievementCard {...mockProps} rarity="common" />
|
|
);
|
|
|
|
// The Card component should receive variant="rarity-common"
|
|
expect(container.firstChild).toBeDefined();
|
|
});
|
|
|
|
it('applies correct variant for rare rarity', () => {
|
|
const { container } = render(
|
|
<AchievementCard {...mockProps} rarity="rare" />
|
|
);
|
|
|
|
// The Card component should receive variant="rarity-rare"
|
|
expect(container.firstChild).toBeDefined();
|
|
});
|
|
|
|
it('applies correct variant for epic rarity', () => {
|
|
const { container } = render(
|
|
<AchievementCard {...mockProps} rarity="epic" />
|
|
);
|
|
|
|
// The Card component should receive variant="rarity-epic"
|
|
expect(container.firstChild).toBeDefined();
|
|
});
|
|
|
|
it('applies correct variant for legendary rarity', () => {
|
|
const { container } = render(
|
|
<AchievementCard {...mockProps} rarity="legendary" />
|
|
);
|
|
|
|
// The Card component should receive variant="rarity-legendary"
|
|
expect(container.firstChild).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('Empty states', () => {
|
|
it('renders with empty description', () => {
|
|
render(
|
|
<AchievementCard
|
|
{...mockProps}
|
|
description=""
|
|
/>
|
|
);
|
|
|
|
expect(screen.getByText('First Victory')).toBeDefined();
|
|
expect(screen.getByText('Formatted: 2024-01-15T10:30:00Z')).toBeDefined();
|
|
});
|
|
|
|
it('renders with empty icon', () => {
|
|
render(
|
|
<AchievementCard
|
|
{...mockProps}
|
|
icon=""
|
|
/>
|
|
);
|
|
|
|
expect(screen.getByText('First Victory')).toBeDefined();
|
|
expect(screen.getByText('Win your first race')).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('Edge cases', () => {
|
|
it('handles very long title', () => {
|
|
const longTitle = 'This is an extremely long achievement title that should still be displayed correctly without breaking the layout';
|
|
|
|
render(
|
|
<AchievementCard
|
|
{...mockProps}
|
|
title={longTitle}
|
|
/>
|
|
);
|
|
|
|
expect(screen.getByText(longTitle)).toBeDefined();
|
|
});
|
|
|
|
it('handles unicode characters in icon', () => {
|
|
const unicodeIcon = '🌟';
|
|
|
|
render(
|
|
<AchievementCard
|
|
{...mockProps}
|
|
icon={unicodeIcon}
|
|
/>
|
|
);
|
|
|
|
expect(screen.getByText(unicodeIcon)).toBeDefined();
|
|
});
|
|
|
|
it('handles emoji in icon', () => {
|
|
const emojiIcon = '🎮';
|
|
|
|
render(
|
|
<AchievementCard
|
|
{...mockProps}
|
|
icon={emojiIcon}
|
|
/>
|
|
);
|
|
|
|
expect(screen.getByText(emojiIcon)).toBeDefined();
|
|
});
|
|
});
|
|
});
|