import { describe, it, expect, vi, beforeEach } from 'vitest';
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { renderWithProviders } from '../test/utils';
vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }));
vi.mock('../hooks/usePermissions', () => ({ usePermissions: () => ({ can: () => true }) }));
const setOverride = { mutate: vi.fn(), isPending: false };
const removeOverride = { mutate: vi.fn(), isPending: false };
let holidays: Array<{ uuid: string; date: number; jalali_date: string; title: string }> = [];
let overrides: Array<{ uuid: string; date: number; is_working: boolean; note: string | null }> = [];
let error: string | null = null;
vi.mock('../hooks/useResourceCalendar', () => ({
useHolidays: () => ({ holidays, overrides, loading: false, error, setOverride, removeOverride }),
}));
import HolidaysSettingsPage from './HolidaysSettingsPage';
// ۱۴۰۵-۰۵-۱۳ ⇒ ۲۰۲۶-۰۸-۰۴
const MARTYRDOM = {
uuid: 'h-1',
date: Math.floor(new Date(2026, 7, 4).getTime() / 1000),
jalali_date: '1405-05-13',
title: 'شهادت',
};
describe('HolidaysSettingsPage', () => {
beforeEach(() => {
holidays = [MARTYRDOM];
overrides = [];
error = null;
vi.clearAllMocks();
});
/**
* پیشتر دو ستون تاریخ بود: «تاریخ» رشتهٔ خامِ `1405-05-13` و «میلادی» که با
* formatDate همان روز را **شمسی** میداد. یک تاریخ، دو بار، با برچسبی که دروغ میگفت.
*/
it('یک ستون تاریخ دارد و شمسی است، نه رشتهٔ خام', () => {
renderWithProviders();
expect(screen.getByText('۱۴۰۵/۰۵/۱۳')).toBeInTheDocument();
expect(screen.queryByText('1405-05-13')).not.toBeInTheDocument();
expect(screen.queryByText('میلادی')).not.toBeInTheDocument();
});
it('روز تعطیل را برای این محیط باز میکند', async () => {
const user = userEvent.setup();
renderWithProviders();
await user.click(screen.getByRole('button', { name: 'این روز باز است' }));
expect(setOverride.mutate).toHaveBeenCalledWith({ date: MARTYRDOM.date, is_working: true });
});
it('روزِ استثنا خورده را دوباره تعطیل میکند', async () => {
overrides = [{ uuid: 'o-1', date: MARTYRDOM.date, is_working: true, note: null }];
const user = userEvent.setup();
renderWithProviders();
expect(screen.getByText('باز است')).toBeInTheDocument();
await user.click(screen.getByRole('button', { name: 'تعطیل کن' }));
expect(removeOverride.mutate).toHaveBeenCalledWith('o-1');
});
/** بدون این، درخواستِ شکستخورده مثل «سالِ خالی» دیده میشد. */
it('خطای سرور را نشان میدهد، نه سالِ خالی', () => {
error = 'خطای داخلی سرور';
holidays = [];
renderWithProviders();
expect(screen.getByText('خطای داخلی سرور')).toBeInTheDocument();
});
it('سالِ خالی را با ارقام فارسی میگوید', () => {
holidays = [];
renderWithProviders(, { route: '/admin/holidays?year=1404' });
expect(screen.getByText('برای سال ۱۴۰۴ تعطیلی ثبت نشده است')).toBeInTheDocument();
});
/** انتخابگر سال و ورودی تاریخ هر دو باید نام دسترسپذیر داشته باشند. */
it('فیلدها نام دارند', () => {
renderWithProviders();
expect(screen.getByRole('button', { name: 'تاریخ تعطیلی' })).toBeInTheDocument();
expect(screen.getByLabelText('توضیح')).toBeInTheDocument();
});
/** ورودی نیتیو میلادی بود و در دارکمود سفید میماند؛ باید رفته باشد. */
it('ورودی تاریخ نیتیو ندارد', () => {
const { container } = renderWithProviders();
expect(container.querySelector('input[type="date"]')).toBeNull();
});
it('تعطیلی محیط را با تاریخ و توضیح ثبت میکند', async () => {
const user = userEvent.setup();
renderWithProviders();
// بدون تاریخ، ثبت ممکن نیست.
expect(screen.getByRole('button', { name: 'افزودن' })).toBeDisabled();
await user.type(screen.getByLabelText('توضیح'), 'تعطیلی داخلی');
expect(screen.getByRole('button', { name: 'افزودن' })).toBeDisabled();
});
});