- Implement tests for Pagination, StatusBadge, ConfirmDialog, and MobileInput components. - Add tests for useSubscription, usePaymentConfig, and usePwaInstall hooks. - Create tests for API requests in the api module, including success and error handling. - Add utility function tests for formatting and validating Iranian mobile numbers. - Implement tests for BlogFormPage and BlogsPage to validate form submissions and data fetching. - Add tests for LoginPage to ensure proper validation and state management. - Create tests for authStore and uiStore to validate state management and functionality. - Set up Vitest configuration and testing utilities for consistent testing environment.
114 lines
4.9 KiB
TypeScript
114 lines
4.9 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest';
|
|
import { render, screen, fireEvent } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import Pagination from '@/components/ui/Pagination';
|
|
import StatusBadge, { ActiveBadge } from '@/components/ui/StatusBadge';
|
|
import ConfirmDialog from '@/components/ui/ConfirmDialog';
|
|
import MobileInput from '@/components/ui/MobileInput';
|
|
|
|
describe('Pagination', () => {
|
|
it('وقتی یک صفحه یا کمتر است چیزی رندر نمیکند', () => {
|
|
const { container } = render(
|
|
<Pagination page={1} total={5} limit={10} onPageChange={vi.fn()} />,
|
|
);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it('دکمه «قبلی» در صفحه اول غیرفعال است', () => {
|
|
render(<Pagination page={1} total={50} limit={10} onPageChange={vi.fn()} />);
|
|
const buttons = screen.getAllByRole('button');
|
|
expect(buttons[0]).toBeDisabled(); // prev
|
|
expect(buttons[buttons.length - 1]).not.toBeDisabled(); // next
|
|
});
|
|
|
|
it('کلیک «بعدی» صفحه page+1 را میفرستد', async () => {
|
|
const onPage = vi.fn();
|
|
render(<Pagination page={1} total={50} limit={10} onPageChange={onPage} />);
|
|
const buttons = screen.getAllByRole('button');
|
|
await userEvent.click(buttons[buttons.length - 1]);
|
|
expect(onPage).toHaveBeenCalledWith(2);
|
|
});
|
|
|
|
it('کلیک روی شماره صفحه همان شماره را میفرستد', async () => {
|
|
const onPage = vi.fn();
|
|
render(<Pagination page={1} total={50} limit={10} onPageChange={onPage} />);
|
|
await userEvent.click(screen.getByText('۳'));
|
|
expect(onPage).toHaveBeenCalledWith(3);
|
|
});
|
|
});
|
|
|
|
describe('StatusBadge', () => {
|
|
it.each([
|
|
['appointment', 'confirmed', 'تأیید شده'],
|
|
['appointment', 'no_show', 'غیبت'],
|
|
['payment', 'success', 'موفق'],
|
|
['sms', 'approved', 'تأیید شده'],
|
|
['settlement', 'rejected', 'رد شده'],
|
|
])('%s/%s → %s', (type, value, label) => {
|
|
render(<StatusBadge type={type as never} value={value} />);
|
|
expect(screen.getByText(label)).toBeInTheDocument();
|
|
});
|
|
|
|
it('مقدار ناشناخته → خود مقدار نمایش داده میشود', () => {
|
|
render(<StatusBadge type="appointment" value="zzz" />);
|
|
expect(screen.getByText('zzz')).toBeInTheDocument();
|
|
});
|
|
|
|
it('ActiveBadge فعال/غیرفعال', () => {
|
|
const { rerender } = render(<ActiveBadge active={true} />);
|
|
expect(screen.getByText('فعال')).toBeInTheDocument();
|
|
rerender(<ActiveBadge active={false} />);
|
|
expect(screen.getByText('غیرفعال')).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
describe('ConfirmDialog', () => {
|
|
it('وقتی open=false چیزی رندر نمیشود', () => {
|
|
const { container } = render(
|
|
<ConfirmDialog open={false} title="t" message="m" onConfirm={vi.fn()} onCancel={vi.fn()} />,
|
|
);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it('تأیید و لغو callbackهای درست را صدا میزنند', async () => {
|
|
const onConfirm = vi.fn();
|
|
const onCancel = vi.fn();
|
|
render(
|
|
<ConfirmDialog open title="حذف" message="مطمئنید؟" onConfirm={onConfirm} onCancel={onCancel} />,
|
|
);
|
|
await userEvent.click(screen.getByRole('button', { name: 'تأیید' }));
|
|
expect(onConfirm).toHaveBeenCalledTimes(1);
|
|
await userEvent.click(screen.getByRole('button', { name: 'لغو' }));
|
|
expect(onCancel).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('در حالت loading دکمهها غیرفعال و متن «در حال انجام...» است', () => {
|
|
render(
|
|
<ConfirmDialog open loading title="t" message="m" onConfirm={vi.fn()} onCancel={vi.fn()} />,
|
|
);
|
|
expect(screen.getByText('در حال انجام...')).toBeInTheDocument();
|
|
screen.getAllByRole('button').forEach((b) => {
|
|
if (b.textContent) expect(b).toBeDisabled();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('MobileInput', () => {
|
|
it('ارقام فارسی و جداکننده را قبل از onChange نرمال میکند', () => {
|
|
const onChange = vi.fn();
|
|
render(<MobileInput onChange={onChange} />);
|
|
const input = screen.getByRole('textbox');
|
|
fireEvent.change(input, { target: { value: '۰۹۱۲-۳۴۵ ۶۷۸۹' } });
|
|
expect(onChange).toHaveBeenCalled();
|
|
const evt = onChange.mock.calls[0][0];
|
|
expect(evt.target.value).toBe('09123456789');
|
|
});
|
|
|
|
it('placeholder پیشفرض و maxLength=11 دارد', () => {
|
|
render(<MobileInput />);
|
|
const input = screen.getByPlaceholderText('09xxxxxxxxx') as HTMLInputElement;
|
|
expect(input.maxLength).toBe(11);
|
|
expect(input.getAttribute('dir')).toBe('ltr');
|
|
});
|
|
});
|