import { describe, it, expect, beforeEach, vi } from 'vitest'; import { screen, waitFor } from '@testing-library/react'; 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 {}, })); vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } })); import { Routes, Route } from 'react-router-dom'; import { api } from '../lib/api'; import PolicySimulationPage from './PolicySimulationPage'; const get = api.get as ReturnType; const policy = { uuid: 'p1', category: 'pricing', name: 'تخفیف وفاداری', condition: {}, effects: [{ type: 'discount_percent', value: 25 }], priority: 0, version: 2, active: false, valid_from: null, valid_to: null, address_uuid: null, service_uuid: null, catalog_category_uuid: null, specificity: 0, }; function run(version: number, severity: string) { return { uuid: 'r1', policy_uuid: 'p1', policy_version: version, sample_size: 4, affected_count: 3, affected_percent: 75, severity, created_at: 1_700_000_000, warning: null, rows: [ { appointment_uuid: 'a1', patient_name: 'ز. احمدی', slot_start: 1_700_000_000, before: '2,000,000 ریال', after: '1,500,000 ریال', reason: '500,000 ریال تخفیف', }, ], }; } function mockApi(runs: unknown[]) { get.mockImplementation((path: string) => { if (path === '/api/v1/policy/p1') return Promise.resolve({ success: true, data: policy }); if (path === '/api/v1/policy/p1/simulations') return Promise.resolve({ success: true, data: runs }); return Promise.resolve({ success: true, data: null }); }); } function renderPage() { return renderWithProviders( } /> , { route: '/admin/policies/p1/simulate' }, ); } describe('PolicySimulationPage', () => { beforeEach(() => vi.clearAllMocks()); it('shows the before/after change of each affected appointment', async () => { mockApi([run(2, 'high')]); renderPage(); await waitFor(() => expect(screen.getByText('ز. احمدی')).toBeInTheDocument()); expect(screen.getByText('2,000,000 ریال')).toBeInTheDocument(); expect(screen.getByText('1,500,000 ریال')).toBeInTheDocument(); expect(screen.getByText(/تحت تأثیر: 3 نوبت/)).toBeInTheDocument(); }); /** گزارشِ نسخهٔ قبلی نباید دکمهٔ فعال‌سازی را باز کند — همان قاعدهٔ بک‌اند. */ it('disables activation when the report belongs to an older version', async () => { mockApi([run(1, 'low')]); renderPage(); await waitFor(() => expect(screen.getByText(/فعال‌سازی قانون/)).toBeDisabled()); expect(screen.getByText(/دوباره آزمایش کنید/)).toBeInTheDocument(); }); it('enables activation when the report matches the current version', async () => { mockApi([run(2, 'low')]); renderPage(); await waitFor(() => expect(screen.getByText(/فعال‌سازی قانون/)).toBeEnabled()); }); });