import { describe, it, expect, beforeAll, afterAll, afterEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import { server } from '../__mocks__/handlers';
import { Sidebar } from '../components/layout/Sidebar';
import { Alert } from '../components/common/Alert';
import { Skeleton } from '../components/common/Skeleton';
import { DataQualityPanel } from '../components/quality/DataQualityPanel';
import type { DataQualityReport } from '../types';
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
describe('Sidebar', () => {
it('renders navigation items', () => {
render(
{}} />
,
);
expect(screen.getByText('Dashboard')).toBeInTheDocument();
expect(screen.getByText('Upload Data')).toBeInTheDocument();
expect(screen.getByText('Data Quality')).toBeInTheDocument();
expect(screen.getByText('Compare')).toBeInTheDocument();
});
it('renders theme toggle button', () => {
render(
{}} />
,
);
expect(screen.getByText('Light Mode')).toBeInTheDocument();
});
it('shows dark mode text when theme is light', () => {
render(
{}} />
,
);
expect(screen.getByText('Dark Mode')).toBeInTheDocument();
});
});
describe('Alert', () => {
it('renders danger alert', () => {
render();
expect(screen.getByText('Something went wrong')).toBeInTheDocument();
});
it('renders success alert', () => {
render();
expect(screen.getByText('Operation completed')).toBeInTheDocument();
});
it('calls onDismiss when close button clicked', async () => {
const onDismiss = vi.fn();
render();
const dismissBtn = screen.getByLabelText('Dismiss');
dismissBtn.click();
expect(onDismiss).toHaveBeenCalledOnce();
});
});
describe('Skeleton', () => {
it('renders loading skeleton', () => {
render();
const skeletons = screen.getAllByRole('status');
expect(skeletons).toHaveLength(3);
});
});
describe('DataQualityPanel', () => {
const mockReport: DataQualityReport = {
total_entries: 100,
low_confidence_count: 5,
low_confidence_entries: ['1', '2', '3', '4', '5'],
mixed_language_count: 3,
mixed_language_entries: ['6', '7', '8'],
duplicate_count: 2,
duplicate_entries: ['9', '10'],
avg_confidence: 0.85,
language_distribution: { en: 80, es: 12, fr: 8 },
};
it('renders quality stats', () => {
render();
expect(screen.getByText('5')).toBeInTheDocument();
expect(screen.getByText('3')).toBeInTheDocument();
expect(screen.getByText('2')).toBeInTheDocument();
});
it('shows health score', () => {
render();
expect(screen.getByText('Data Health Score')).toBeInTheDocument();
});
it('displays language distribution', () => {
render();
expect(screen.getByText('en: 80')).toBeInTheDocument();
expect(screen.getByText('es: 12')).toBeInTheDocument();
});
it('shows warning when issues exist', () => {
render();
expect(screen.getByText(/data quality issue/i)).toBeInTheDocument();
});
});