- apps/web: test updates (Vitest/setup), playbackAnalyticsService, TrackGrid, serviceErrorHandler - veza-common: logging, metrics, traits, validation, random - veza-stream-server: audio pipeline, codecs, cache, monitoring, routes - apps/web/dist_verification: refresh build assets (content-hashed filenames) Co-authored-by: Cursor <cursoragent@cursor.com>
175 lines
5.2 KiB
TypeScript
175 lines
5.2 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { render, screen, fireEvent } from '@testing-library/react';
|
|
import { BrowserRouter } from 'react-router-dom';
|
|
// import { useTranslation } from '@/hooks/useTranslation'
|
|
import { Button } from '@/components/ui/button';
|
|
import { Input } from '@/components/ui/input';
|
|
import { FocusTrap } from '@/components/ui/focus-trap';
|
|
|
|
// Mock useTranslation
|
|
vi.mock('@/hooks/useTranslation', () => ({
|
|
useTranslation: vi.fn(() => ({
|
|
t: (key: string) => key,
|
|
i18n: { changeLanguage: vi.fn() },
|
|
language: 'en',
|
|
changeLanguage: vi.fn(),
|
|
isReady: true,
|
|
})),
|
|
}));
|
|
|
|
// Mock i18n
|
|
vi.mock('@/lib/i18n', () => ({
|
|
default: {
|
|
changeLanguage: vi.fn(),
|
|
isInitialized: true,
|
|
},
|
|
}));
|
|
|
|
const TestWrapper = ({ children }: { children: React.ReactNode }) => (
|
|
<BrowserRouter>{children}</BrowserRouter>
|
|
);
|
|
|
|
describe('UI Components', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('Button', () => {
|
|
it('should render with default props', () => {
|
|
render(<Button>Test Button</Button>);
|
|
expect(
|
|
screen.getByRole('button', { name: 'Test Button' }),
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it('should render with different variants', () => {
|
|
render(<Button variant="destructive">Delete</Button>);
|
|
const button = screen.getByRole('button', { name: 'Delete' });
|
|
expect(button).toBeInTheDocument();
|
|
// Destructive variant uses bg-destructive/10 with text-destructive
|
|
expect(button).toHaveClass('text-destructive');
|
|
});
|
|
|
|
it('should handle click events', () => {
|
|
const handleClick = vi.fn();
|
|
render(<Button onClick={handleClick}>Click me</Button>);
|
|
|
|
fireEvent.click(screen.getByRole('button'));
|
|
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('should be disabled when disabled prop is true', () => {
|
|
render(<Button disabled>Disabled Button</Button>);
|
|
const button = screen.getByRole('button', { name: 'Disabled Button' });
|
|
expect(button).toBeDisabled();
|
|
});
|
|
|
|
it('should render as child when asChild is true', () => {
|
|
render(
|
|
<Button asChild>
|
|
<a href="/test">Link Button</a>
|
|
</Button>,
|
|
);
|
|
expect(
|
|
screen.getByRole('link', { name: 'Link Button' }),
|
|
).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
describe('Input', () => {
|
|
it('should render with default props', () => {
|
|
render(<Input placeholder="Enter text" />);
|
|
expect(screen.getByPlaceholderText('Enter text')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should handle value changes', () => {
|
|
const handleChange = vi.fn();
|
|
render(<Input onChange={handleChange} />);
|
|
|
|
const input = screen.getByRole('textbox');
|
|
fireEvent.change(input, { target: { value: 'test input' } });
|
|
|
|
expect(handleChange).toHaveBeenCalled();
|
|
expect(input).toHaveValue('test input');
|
|
});
|
|
|
|
it('should support different input types', () => {
|
|
render(<Input type="email" placeholder="Enter email" />);
|
|
const input = screen.getByPlaceholderText('Enter email');
|
|
expect(input).toHaveAttribute('type', 'email');
|
|
});
|
|
|
|
it('should be disabled when disabled prop is true', () => {
|
|
render(<Input disabled placeholder="Disabled input" />);
|
|
const input = screen.getByPlaceholderText('Disabled input');
|
|
expect(input).toBeDisabled();
|
|
});
|
|
});
|
|
|
|
describe('FocusTrap', () => {
|
|
it('should render children when active', () => {
|
|
render(
|
|
<FocusTrap active={true}>
|
|
<div>Test content</div>
|
|
</FocusTrap>,
|
|
);
|
|
expect(screen.getByText('Test content')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should not render children when inactive', () => {
|
|
render(
|
|
<FocusTrap active={false}>
|
|
<div>Test content</div>
|
|
</FocusTrap>,
|
|
);
|
|
expect(screen.getByText('Test content')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should call onEscape when Escape key is pressed', () => {
|
|
const onEscape = vi.fn();
|
|
render(
|
|
<FocusTrap active={true} onEscape={onEscape}>
|
|
<div>Test content</div>
|
|
</FocusTrap>,
|
|
);
|
|
|
|
fireEvent.keyDown(document, { key: 'Escape' });
|
|
expect(onEscape).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Integration Tests', () => {
|
|
it('should work with React Router', () => {
|
|
render(
|
|
<TestWrapper>
|
|
<Button asChild>
|
|
<a href="/dashboard">Go to Dashboard</a>
|
|
</Button>
|
|
</TestWrapper>,
|
|
);
|
|
|
|
const link = screen.getByRole('link', { name: 'Go to Dashboard' });
|
|
expect(link).toBeInTheDocument();
|
|
expect(link).toHaveAttribute('href', '/dashboard');
|
|
});
|
|
|
|
it('should handle form interactions', async () => {
|
|
const handleSubmit = vi.fn((e) => e.preventDefault());
|
|
|
|
render(
|
|
<form onSubmit={handleSubmit}>
|
|
<Input name="username" placeholder="Username" />
|
|
<Button type="submit">Submit</Button>
|
|
</form>,
|
|
);
|
|
|
|
const input = screen.getByPlaceholderText('Username');
|
|
const button = screen.getByRole('button', { name: 'Submit' });
|
|
|
|
fireEvent.change(input, { target: { value: 'testuser' } });
|
|
fireEvent.click(button);
|
|
|
|
expect(handleSubmit).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|