import React from 'react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import { render, screen, waitFor } from '@testing-library/react'; import UserPill from './UserPill'; import type { DriverDTO } from '@/lib/types/generated/DriverDTO'; // Mock useAuth to control session state vi.mock('@/lib/auth/AuthContext', () => { return { useAuth: () => mockedAuthValue, }; }); // Mock effective driver id hook vi.mock('@/hooks/useEffectiveDriverId', () => { return { useEffectiveDriverId: () => mockedDriverId, }; }); // Mock services hook to inject stub driverService const mockFindById = vi.fn(); vi.mock('@/lib/services/ServiceProvider', () => { return { useServices: () => ({ driverService: { findById: mockFindById, }, mediaService: { getDriverAvatar: vi.fn(), }, }), }; }); interface MockSessionUser { id: string; } interface MockSession { user: MockSessionUser | null; } let mockedAuthValue: { session: MockSession | null } = { session: null }; let mockedDriverId: string | null = null; // Provide global stats helpers used by UserPill's rating/rank computation // They are UI-level helpers, so a minimal stub is sufficient for these tests. (globalThis as any).getDriverStats = (driverId: string) => ({ driverId, rating: 2000, overallRank: 10, wins: 5, }); (globalThis as any).getAllDriverRankings = () => [ { driverId: 'driver-1', rating: 2100 }, { driverId: 'driver-2', rating: 2000 }, ]; describe('UserPill', () => { beforeEach(() => { mockedAuthValue = { session: null }; mockedDriverId = null; mockFindById.mockReset(); }); it('renders auth links when there is no session', () => { mockedAuthValue = { session: null }; const { container } = render(); expect(screen.getByText('Sign In')).toBeInTheDocument(); expect(screen.getByText('Get Started')).toBeInTheDocument(); expect(mockFindById).not.toHaveBeenCalled(); expect(container).toMatchSnapshot(); }); it('does not load driver when there is no primary driver id', async () => { mockedAuthValue = { session: { user: { id: 'user-1' } } }; mockedDriverId = null; const { container } = render(); // Component should still render user pill with session user info await waitFor(() => { expect(screen.getByText('User')).toBeInTheDocument(); }); expect(mockFindById).not.toHaveBeenCalled(); }); it('loads driver via driverService and uses driver avatarUrl', async () => { const driver: DriverDTO = { id: 'driver-1', iracingId: 'ir-123', name: 'Test Driver', country: 'DE', avatarUrl: '/api/media/avatar/driver-1', }; mockedAuthValue = { session: { user: { id: 'user-1' } } }; mockedDriverId = driver.id; mockFindById.mockResolvedValue(driver); render(); await waitFor(() => { expect(screen.getByText('Test Driver')).toBeInTheDocument(); }); expect(mockFindById).toHaveBeenCalledWith('driver-1'); }); });