140 lines
4.2 KiB
TypeScript
140 lines
4.2 KiB
TypeScript
// @ts-nocheck
|
|
/**
|
|
* Unit tests for CheckoutConfirmationDialog component.
|
|
* Tests the UI rendering and IPC communication for checkout confirmation.
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { describe, it, expect, vi, beforeEach, beforeAll } from 'vitest';
|
|
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
import { act } from 'react';
|
|
|
|
import { CheckoutConfirmationDialog } from '../../../apps/companion/renderer/components/CheckoutConfirmationDialog';
|
|
|
|
// Mock window.electronAPI
|
|
const mockConfirmCheckout = vi.fn();
|
|
|
|
describe('CheckoutConfirmationDialog', () => {
|
|
beforeAll(() => {
|
|
// Set up window.electronAPI mock for all tests
|
|
Object.defineProperty(window, 'electronAPI', {
|
|
writable: true,
|
|
value: {
|
|
confirmCheckout: mockConfirmCheckout,
|
|
},
|
|
});
|
|
});
|
|
|
|
const mockRequest = {
|
|
price: '$0.50',
|
|
state: 'ready' as const,
|
|
sessionMetadata: {
|
|
sessionName: 'Test Race',
|
|
trackId: 'spa',
|
|
carIds: ['porsche_911_gt3_r'],
|
|
},
|
|
timeoutMs: 60000,
|
|
};
|
|
|
|
beforeEach(() => {
|
|
mockConfirmCheckout.mockClear();
|
|
});
|
|
|
|
describe('Rendering', () => {
|
|
it('should render dialog with price and session info', () => {
|
|
render(<CheckoutConfirmationDialog request={mockRequest} />);
|
|
|
|
expect(screen.getByText(/Confirm Checkout/i)).toBeInTheDocument();
|
|
expect(screen.getByText(/\$0\.50/)).toBeInTheDocument();
|
|
expect(screen.getByText(/Test Race/)).toBeInTheDocument();
|
|
});
|
|
|
|
it('should render confirm and cancel buttons', () => {
|
|
render(<CheckoutConfirmationDialog request={mockRequest} />);
|
|
|
|
expect(screen.getByRole('button', { name: /confirm/i })).toBeInTheDocument();
|
|
expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument();
|
|
});
|
|
|
|
it('should display track and car information', () => {
|
|
render(<CheckoutConfirmationDialog request={mockRequest} />);
|
|
|
|
expect(screen.getByText(/spa/i)).toBeInTheDocument();
|
|
expect(screen.getByText(/porsche/i)).toBeInTheDocument();
|
|
});
|
|
|
|
it('should show warning when state is insufficient funds', () => {
|
|
const insufficientFundsRequest = {
|
|
...mockRequest,
|
|
state: 'insufficient_funds' as const,
|
|
};
|
|
|
|
render(<CheckoutConfirmationDialog request={insufficientFundsRequest} />);
|
|
|
|
expect(screen.getByText(/insufficient/i)).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
describe('IPC Communication', () => {
|
|
it('should emit checkout:confirm with "confirmed" when confirm button clicked', () => {
|
|
render(<CheckoutConfirmationDialog request={mockRequest} />);
|
|
|
|
const confirmButton = screen.getByRole('button', { name: /confirm/i });
|
|
fireEvent.click(confirmButton);
|
|
|
|
expect(mockConfirmCheckout).toHaveBeenCalledWith('confirmed');
|
|
});
|
|
|
|
it('should emit checkout:confirm with "cancelled" when cancel button clicked', () => {
|
|
render(<CheckoutConfirmationDialog request={mockRequest} />);
|
|
|
|
const cancelButton = screen.getByRole('button', { name: /cancel/i });
|
|
fireEvent.click(cancelButton);
|
|
|
|
expect(mockConfirmCheckout).toHaveBeenCalledWith('cancelled');
|
|
});
|
|
|
|
it('should emit checkout:confirm with "timeout" when timeout expires', async () => {
|
|
vi.useFakeTimers();
|
|
|
|
const shortTimeoutRequest = {
|
|
...mockRequest,
|
|
timeoutMs: 1000,
|
|
};
|
|
|
|
render(<CheckoutConfirmationDialog request={shortTimeoutRequest} />);
|
|
|
|
// Fast-forward time past timeout
|
|
vi.advanceTimersByTime(1100);
|
|
|
|
expect(mockConfirmCheckout).toHaveBeenCalledWith('timeout');
|
|
|
|
vi.useRealTimers();
|
|
});
|
|
});
|
|
|
|
describe('Countdown Timer', () => {
|
|
it('should display countdown timer', () => {
|
|
render(<CheckoutConfirmationDialog request={mockRequest} />);
|
|
|
|
expect(screen.getByText(/60/)).toBeInTheDocument();
|
|
});
|
|
|
|
it('should update countdown every second', async () => {
|
|
vi.useFakeTimers();
|
|
|
|
render(<CheckoutConfirmationDialog request={mockRequest} />);
|
|
|
|
expect(screen.getByText(/60/)).toBeInTheDocument();
|
|
|
|
await act(async () => {
|
|
vi.advanceTimersByTime(1000);
|
|
await Promise.resolve();
|
|
});
|
|
|
|
expect(screen.getByText(/59/)).toBeInTheDocument();
|
|
|
|
vi.useRealTimers();
|
|
});
|
|
});
|
|
}); |