import { describe, it, expect, beforeEach, vi } from 'vitest'; import { screen, fireEvent } from '@testing-library/react'; import { renderWithProviders } from '../../test/utils'; const navigateMock = vi.fn(); vi.mock('react-router', async () => { const actual = await vi.importActual('react-router'); return { ...actual, useNavigate: () => navigateMock }; }); import ProfileMenu, { settingsPath } from './ProfileMenu'; import { useAuthStore } from '../../stores/authStore'; import { useUiStore } from '../../stores/uiStore'; const logoutMock = vi.fn(); const togglePanelMock = vi.fn(); function setAuth(partial: Record) { useAuthStore.setState({ userName: 'دکتر رضایی', primaryRole: 'doctor', context: { name: 'کلینیک نور' }, logout: logoutMock, ...partial, } as any); } beforeEach(() => { navigateMock.mockClear(); logoutMock.mockClear(); togglePanelMock.mockClear(); useUiStore.setState({ toggleSettingsPanel: togglePanelMock } as any); setAuth({}); }); describe('ProfileMenu — نمایش نام و تخصص', () => { it('نام کاربر و نام محیط کاری (context) را نشان می‌دهد', () => { renderWithProviders(); expect(screen.getByText('دکتر رضایی')).toBeInTheDocument(); expect(screen.getByText('کلینیک نور')).toBeInTheDocument(); }); it('وقتی context نیست، برچسب نقش را جایگزین می‌کند', () => { setAuth({ context: null }); renderWithProviders(); expect(screen.getByText('پزشک')).toBeInTheDocument(); }); it('حالت خالی: نام پیش‌فرض «کاربر» و حرف اول «ک»', () => { setAuth({ userName: null, context: null, primaryRole: null }); renderWithProviders(); expect(screen.getByText('کاربر')).toBeInTheDocument(); // حرف اولِ آواتار expect(screen.getByTitle('کاربر').textContent).toContain('ک'); }); }); describe('ProfileMenu — باز/بستن و آیتم‌ها', () => { it('منو ابتدا بسته است و با کلیک باز می‌شود', () => { renderWithProviders(); expect(screen.queryByText('خروج')).toBeNull(); fireEvent.click(screen.getByTitle('دکتر رضایی')); ['پروفایل من', 'پرداخت‌ها', 'تنظیمات', 'شخصی‌سازی', 'خروج'].forEach((label) => { expect(screen.getByText(label)).toBeInTheDocument(); }); }); }); describe('ProfileMenu — لینک‌های نقش‌محور', () => { it('پزشک: پروفایل → /admin/profile، پرداخت‌ها → /admin/my-payments', () => { setAuth({ primaryRole: 'doctor' }); renderWithProviders(); fireEvent.click(screen.getByTitle('دکتر رضایی')); fireEvent.click(screen.getByText('پرداخت‌ها')); expect(navigateMock).toHaveBeenCalledWith('/admin/my-payments'); fireEvent.click(screen.getByTitle('دکتر رضایی')); fireEvent.click(screen.getByText('پروفایل من')); expect(navigateMock).toHaveBeenCalledWith('/admin/profile'); }); it('مدیر: پرداخت‌ها → /admin/payments، تنظیمات → /admin/settings', () => { setAuth({ primaryRole: 'admin', userName: 'ادمین' }); renderWithProviders(); fireEvent.click(screen.getByTitle('ادمین')); fireEvent.click(screen.getByText('پرداخت‌ها')); expect(navigateMock).toHaveBeenCalledWith('/admin/payments'); fireEvent.click(screen.getByTitle('ادمین')); fireEvent.click(screen.getByText('تنظیمات')); expect(navigateMock).toHaveBeenCalledWith('/admin/settings'); }); }); describe('ProfileMenu — اکشن‌ها', () => { it('شخصی‌سازی پنل تنظیمات را باز می‌کند', () => { renderWithProviders(); fireEvent.click(screen.getByTitle('دکتر رضایی')); fireEvent.click(screen.getByText('شخصی‌سازی')); expect(togglePanelMock).toHaveBeenCalledTimes(1); }); it('خروج، logout را صدا می‌زند و به صفحه ورود می‌رود', () => { renderWithProviders(); fireEvent.click(screen.getByTitle('دکتر رضایی')); fireEvent.click(screen.getByText('خروج')); expect(logoutMock).toHaveBeenCalledTimes(1); expect(navigateMock).toHaveBeenCalledWith('/admin/login'); }); }); describe('settingsPath — نگاشت نقش', () => { it('نقش‌ها را به مسیر درست نگاشت می‌کند', () => { expect(settingsPath('admin')).toBe('/admin/settings'); expect(settingsPath('doctor')).toBe('/admin/settings-menu'); expect(settingsPath('clinic')).toBe('/admin/settings-menu'); expect(settingsPath('secretary')).toBe('/admin/account-settings'); expect(settingsPath(null)).toBe('/admin/account-settings'); }); });