Files
clinicpro/assets/admin/components/dashboard/TauriCharts.test.tsx
T

92 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import { TauriBarChart, TauriLineChart, type ChartPoint } from './TauriCharts';
const zero: ChartPoint[] = Array.from({ length: 7 }, (_, i) => ({ label: `روز ${i}`, value: 0 }));
const real: ChartPoint[] = [
{ label: '۷ خرداد', value: 15 },
{ label: '۸ خرداد', value: 40 },
{ label: '۹ خرداد', value: 48 },
];
const EMPTY = 'داده‌ای برای نمایش نیست';
describe('TauriBarChart', () => {
it('shows the empty state when every value is zero', () => {
render(<TauriBarChart data={zero} />);
expect(screen.getByText(EMPTY)).toBeInTheDocument();
});
it('shows the empty state when there is no data', () => {
render(<TauriBarChart data={[]} />);
expect(screen.getByText(EMPTY)).toBeInTheDocument();
});
it('renders the chart (x labels, no empty state) with real data', () => {
render(<TauriBarChart data={real} />);
expect(screen.queryByText(EMPTY)).not.toBeInTheDocument();
expect(screen.getByText('۸ خرداد')).toBeInTheDocument();
});
it('renders one bar per day of a full Jalali month', () => {
const month: ChartPoint[] = Array.from({ length: 31 }, (_, i) => ({ label: String(i + 1), value: i % 5 }));
const { container } = render(<TauriBarChart data={month} />);
expect(container.querySelectorAll('.bg-\\[\\#5559CE\\]')).toHaveLength(31);
});
/**
* A fixed-width bar makes its column's intrinsic min-width 24px, so a 31-day
* month sums past the plot width and the row overflows out of the card
* (bars land on the neighbouring chart). Columns must be shrinkable and the
* bar fluid-but-capped.
*/
it('keeps a dense month inside the card: shrinkable columns, fluid bars', () => {
const month: ChartPoint[] = Array.from({ length: 31 }, (_, i) => ({ label: String(i + 1), value: i % 5 }));
const { container } = render(<TauriBarChart data={month} />);
const bar = container.querySelector('.bg-\\[\\#5559CE\\]') as HTMLElement;
// کسری از ستون، نه تمام آن — وگرنه میله‌ها بدون فاصله به هم می‌چسبند
expect(bar.className).toMatch(/\bw-\[\d+%\]/);
expect(bar.className.split(/\s+/)).not.toContain('w-full');
expect(bar.className).toContain('max-w-[24px]');
// فقط سقف عرض، نه عرض ثابت (max-w-[24px] خودش شامل رشته‌ی w-[24px] است)
expect(bar.className.split(/\s+/)).not.toContain('w-[24px]');
const column = bar.parentElement as HTMLElement;
expect(column.className).toContain('min-w-0');
const plot = container.querySelector('.relative.flex-1') as HTMLElement;
expect(plot.className).toContain('overflow-hidden');
});
/**
* styles.css ships an unlayered legacy `.flex { align-items: center }` that
* beats Tailwind's `items-*` utilities and collapses the plot column to zero
* height. The frame must pin alignment inline, or the chart renders blank.
*/
it('pins flex alignment inline so the legacy global .flex cannot collapse it', () => {
const { container } = render(<TauriBarChart data={real} />);
const frame = container.querySelector('.h-\\[300px\\]') as HTMLElement;
expect(frame.style.alignItems).toBe('stretch');
expect((frame.firstElementChild as HTMLElement).style.alignItems).toBe('stretch');
});
});
describe('TauriLineChart', () => {
it('shows the empty state when every value is zero', () => {
render(<TauriLineChart data={zero} />);
expect(screen.getByText(EMPTY)).toBeInTheDocument();
});
it('shows the empty state with fewer than two points', () => {
render(<TauriLineChart data={[{ label: 'x', value: 5 }]} />);
expect(screen.getByText(EMPTY)).toBeInTheDocument();
});
it('renders the chart with real data', () => {
const { container } = render(<TauriLineChart data={real} />);
expect(screen.queryByText(EMPTY)).not.toBeInTheDocument();
expect(container.querySelector('svg path')).toBeTruthy();
});
});