import { describe, it, expect, beforeEach, vi } from 'vitest'; import { screen, fireEvent, waitFor } from '@testing-library/react'; import { Routes, Route } from 'react-router-dom'; import { renderWithProviders } from '../test/utils'; vi.mock('../lib/api', () => ({ api: { get: vi.fn(), post: vi.fn(), patch: vi.fn(), put: vi.fn(), delete: vi.fn() }, ApiError: class extends Error {}, })); import { api } from '../lib/api'; import SecretaryDetailPage from './SecretaryDetailPage'; const get = api.get as ReturnType; const put = api.put as ReturnType; function mockSecretary(over: Record = {}) { get.mockResolvedValue({ success: true, data: { data: { uuid: 'rel-1', user_name: 'زهرا رضایی', mobile_number: '09120000000', doctor_name: 'دکتر تست', doctor_uuid: 'doc-1', is_active: true, permissions: {}, created_at: 1_700_000_000, online_share_enabled: false, online_share_percent: 0, earnings: { total_rials: 1_500_000, this_month_rials: 500_000, appointments_count: 3 }, ...over, } }, }); } beforeEach(() => { get.mockReset(); put.mockReset(); put.mockResolvedValue({ success: true, data: { data: {} } }); }); function renderDetail() { return renderWithProviders( } />, { route: '/admin/secretaries/rel-1' }, ); } describe('SecretaryDetailPage', () => { it('مشخصات منشی و خلاصهٔ درآمد را نشان می‌دهد', async () => { mockSecretary(); renderDetail(); expect(await screen.findByText('اطلاعات منشی')).toBeInTheDocument(); expect(screen.getByText('دکتر تست')).toBeInTheDocument(); expect(screen.getByText('سهم درآمد نوبت‌های آنلاین')).toBeInTheDocument(); expect(screen.getByText('خلاصه درآمد')).toBeInTheDocument(); }); it('سوییچ و درصد را از سرور پیش‌پر می‌کند و ذخیره می‌فرستد', async () => { mockSecretary({ online_share_enabled: true, online_share_percent: 5 }); renderDetail(); await waitFor(() => expect(screen.getByLabelText('درصد سهم منشی')).toHaveValue('5')); expect(screen.getByLabelText('محاسبه درآمد منشی از نوبت‌های آنلاین')).toBeChecked(); fireEvent.change(screen.getByLabelText('درصد سهم منشی'), { target: { value: '7' } }); fireEvent.click(screen.getByRole('button', { name: 'ذخیره' })); await waitFor(() => expect(put).toHaveBeenCalledWith('/api/v1/admin/secretary/rel-1/online-share', { enabled: true, percent: 7, })); }); it('درصد بیشتر از ۱۰۰ خطا می‌دهد و ذخیره غیرفعال می‌شود', async () => { mockSecretary({ online_share_enabled: true, online_share_percent: 5 }); renderDetail(); await waitFor(() => expect(screen.getByLabelText('درصد سهم منشی')).toHaveValue('5')); fireEvent.change(screen.getByLabelText('درصد سهم منشی'), { target: { value: '101' } }); expect(screen.getByText('درصد نمی‌تواند بیشتر از ۱۰۰ باشد')).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'ذخیره' })).toBeDisabled(); expect(put).not.toHaveBeenCalled(); }); it('فعال‌سازی با درصد صفر مجاز نیست', async () => { mockSecretary(); renderDetail(); await screen.findByText('اطلاعات منشی'); fireEvent.click(screen.getByLabelText('محاسبه درآمد منشی از نوبت‌های آنلاین')); expect(screen.getByText('برای فعال‌سازی، درصد باید بیشتر از صفر باشد')).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'ذخیره' })).toBeDisabled(); }); });