import React from 'react'; import { describe, expect, it, vi } from 'vitest'; import { render, screen } from '@testing-library/react'; vi.mock('@tamagui/stacks', () => ({ YStack: ({ children }: { children: React.ReactNode }) =>
{children}
, XStack: ({ children }: { children: React.ReactNode }) =>
{children}
, })); vi.mock('@tamagui/text', () => ({ SizableText: ({ children }: { children: React.ReactNode }) => {children}, })); vi.mock('@tamagui/button', () => ({ Button: ({ children, onPress, ...rest }: { children: React.ReactNode; onPress?: () => void }) => ( ), })); vi.mock('../components/AppShell', () => ({ default: ({ children }: { children: React.ReactNode }) =>
{children}
, })); vi.mock('@/guest/components/PullToRefresh', () => ({ default: ({ children }: { children: React.ReactNode }) =>
{children}
, })); vi.mock('../context/EventDataContext', () => ({ useEventData: () => ({ token: 'demo', tasksEnabled: true }), })); vi.mock('../context/GuestIdentityContext', () => ({ useOptionalGuestIdentity: () => ({ name: 'Alex' }), })); vi.mock('@/guest/i18n/useTranslation', () => ({ useTranslation: () => ({ t: (key: string, options?: unknown, fallback?: string) => { if (typeof fallback === 'string') return fallback; if (typeof options === 'string') return options; return key; }, }), })); vi.mock('@/guest/i18n/LocaleContext', () => ({ useLocale: () => ({ locale: 'de' }), })); vi.mock('../lib/guestTheme', () => ({ useGuestThemeVariant: () => ({ isDark: false }), })); vi.mock('../lib/bento', () => ({ getBentoSurfaceTokens: () => ({ borderColor: '#eee', borderBottomColor: '#ddd', backgroundColor: '#fff', shadow: 'none', }), })); vi.mock('../lib/routes', () => ({ buildEventPath: (_token: string, path: string) => `/e/demo${path}`, })); vi.mock('react-router-dom', () => ({ useNavigate: () => vi.fn(), })); vi.mock('@/guest/lib/localizeTaskLabel', () => ({ localizeTaskLabel: (value: string | null) => value, })); vi.mock('../services/achievementsApi', () => ({ fetchAchievements: vi.fn().mockResolvedValue({ summary: { totalPhotos: 12, uniqueGuests: 4, tasksSolved: 2, likesTotal: 30 }, personal: { guestName: 'Alex', photos: 3, tasks: 1, likes: 5, badges: [ { id: 'b1', title: 'First upload', description: 'Upload one photo', earned: true, progress: 1, target: 1 }, ], }, leaderboards: { uploads: [{ guest: 'Sam', photos: 6, likes: 10 }], likes: [{ guest: 'Kai', photos: 2, likes: 12 }], }, highlights: { topPhoto: { photoId: 1, guest: 'Sam', likes: 10, task: 'Smile', createdAt: new Date().toISOString(), thumbnail: null, }, trendingEmotion: { emotionId: 1, name: 'Joy', count: 8 }, timeline: [{ date: '2025-01-01', photos: 4, guests: 2 }], }, feed: [ { photoId: 9, guest: 'Mia', task: 'Dance', likes: 3, createdAt: new Date().toISOString(), thumbnail: null, }, ], }), })); import AchievementsScreen from '../screens/AchievementsScreen'; describe('AchievementsScreen', () => { it('renders personal achievements content', async () => { render(); expect(await screen.findByText('Badges')).toBeInTheDocument(); expect(screen.getByText('First upload')).toBeInTheDocument(); expect(screen.getByText('Upload photo')).toBeInTheDocument(); }); });