This commit is contained in:
2025-12-13 18:39:20 +01:00
parent bb0497f429
commit e53af6a0e7
20 changed files with 762 additions and 503 deletions

View File

@@ -285,10 +285,31 @@ describe('ImportRaceResultsUseCase', () => {
const presenter = new FakeImportRaceResultsPresenter();
const driverRepository = {
findById: async (): Promise<Driver | null> => null,
findByIRacingId: async (iracingId: string): Promise<Driver | null> => {
// Mock finding driver by iracingId
if (iracingId === 'driver-1') {
return Driver.create({ id: 'driver-1', iracingId: 'driver-1', name: 'Driver One', country: 'US' });
}
if (iracingId === 'driver-2') {
return Driver.create({ id: 'driver-2', iracingId: 'driver-2', name: 'Driver Two', country: 'GB' });
}
return null;
},
findAll: async (): Promise<Driver[]> => [],
create: async (): Promise<Driver> => { throw new Error('Not implemented'); },
update: async (): Promise<Driver> => { throw new Error('Not implemented'); },
delete: async (): Promise<void> => { throw new Error('Not implemented'); },
exists: async (): Promise<boolean> => false,
existsByIRacingId: async (): Promise<boolean> => false,
};
const useCase = new ImportRaceResultsUseCase(
raceRepository,
leagueRepository,
resultRepository,
driverRepository,
standingRepository,
presenter,
);

View File

@@ -0,0 +1,123 @@
import { describe, it, expect, vi } from 'vitest';
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
// Mock() Button component
vi.mock('../../../apps/website/components/ui/Button', () => ({
default: ({ onClick, children, className, title, variant }: any) => (
<button
onClick={onClick}
className={className}
title={title}
data-variant={variant}
data-testid="penalty-button"
>
{children}
</button>
),
}));
import InlinePenaltyButton from '../../../apps/website/components/races/InlinePenaltyButton';
describe('InlinePenaltyButton', () => {
const mockDriver = { id: 'driver-1', name: 'Test Driver' };
const mockOnPenaltyClick = vi.fn();
it('should not render when user is not admin', () => {
render(
<InlinePenaltyButton
driver={mockDriver}
onPenaltyClick={mockOnPenaltyClick}
isAdmin={false}
/>
);
const button = screen.queryByTestId('penalty-button');
expect(button).not.toBeInTheDocument();
});
it('should render when user is admin', () => {
render(
<InlinePenaltyButton
driver={mockDriver}
onPenaltyClick={mockOnPenaltyClick}
isAdmin={true}
/>
);
const button = screen.getByTestId('penalty-button');
expect(button).toBeInTheDocument();
expect(button).toHaveAttribute('title', 'Issue penalty to Test Driver');
expect(button).toHaveAttribute('data-variant', 'danger');
});
it('should call onPenaltyClick when button is clicked', () => {
render(
<InlinePenaltyButton
driver={mockDriver}
onPenaltyClick={mockOnPenaltyClick}
isAdmin={true}
/>
);
const button = screen.getByTestId('penalty-button');
fireEvent.click(button);
expect(mockOnPenaltyClick).toHaveBeenCalledTimes(1);
expect(mockOnPenaltyClick).toHaveBeenCalledWith(mockDriver);
});
it('should not crash when onPenaltyClick is not provided', () => {
render(
<InlinePenaltyButton
driver={mockDriver}
isAdmin={true}
/>
);
const button = screen.getByTestId('penalty-button');
// Should not crash when clicked without onPenaltyClick
expect(() => fireEvent.click(button)).not.toThrow();
});
it('should have proper button styling for spacing', () => {
render(
<InlinePenaltyButton
driver={mockDriver}
onPenaltyClick={mockOnPenaltyClick}
isAdmin={true}
/>
);
const button = screen.getByTestId('penalty-button');
// Check that button has proper spacing classes
expect(button).toHaveClass('p-1.5');
expect(button).toHaveClass('min-h-[32px]');
expect(button).toHaveClass('w-8');
expect(button).toHaveClass('h-8');
expect(button).toHaveClass('rounded-full');
expect(button).toHaveClass('flex');
expect(button).toHaveClass('items-center');
expect(button).toHaveClass('justify-center');
});
it('should render AlertTriangle icon with proper sizing', () => {
render(
<InlinePenaltyButton
driver={mockDriver}
onPenaltyClick={mockOnPenaltyClick}
isAdmin={true}
/>
);
const button = screen.getByTestId('penalty-button');
const icon = button.querySelector('svg');
expect(icon).toBeInTheDocument();
expect(icon).toHaveClass('w-4');
expect(icon).toHaveClass('h-4');
expect(icon).toHaveClass('flex-shrink-0');
});
});