121 lines
3.2 KiB
TypeScript
121 lines
3.2 KiB
TypeScript
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/mediaService
|
|
const mockFindById = vi.fn<[], Promise<DriverDTO | null>>();
|
|
const mockGetDriverAvatar = vi.fn<(driverId: string) => string>();
|
|
|
|
vi.mock('@/lib/services/ServiceProvider', () => {
|
|
return {
|
|
useServices: () => ({
|
|
driverService: {
|
|
findById: mockFindById,
|
|
},
|
|
mediaService: {
|
|
getDriverAvatar: mockGetDriverAvatar,
|
|
},
|
|
}),
|
|
};
|
|
});
|
|
|
|
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();
|
|
mockGetDriverAvatar.mockReset();
|
|
});
|
|
|
|
it('renders auth links when there is no session', () => {
|
|
mockedAuthValue = { session: null };
|
|
|
|
const { container } = render(<UserPill />);
|
|
|
|
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(<UserPill />);
|
|
|
|
await waitFor(() => {
|
|
// component should render nothing in this state
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
expect(mockFindById).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('loads driver via driverService and uses mediaService avatar', async () => {
|
|
const driver: DriverDTO = {
|
|
id: 'driver-1',
|
|
iracingId: 'ir-123',
|
|
name: 'Test Driver',
|
|
country: 'DE',
|
|
};
|
|
|
|
mockedAuthValue = { session: { user: { id: 'user-1' } } };
|
|
mockedDriverId = driver.id;
|
|
|
|
mockFindById.mockResolvedValue(driver);
|
|
mockGetDriverAvatar.mockImplementation((driverId: string) => `/api/media/avatar/${driverId}`);
|
|
|
|
render(<UserPill />);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Test Driver')).toBeInTheDocument();
|
|
});
|
|
|
|
expect(mockFindById).toHaveBeenCalledWith('driver-1');
|
|
expect(mockGetDriverAvatar).toHaveBeenCalledWith('driver-1');
|
|
});
|
|
});
|