Files
clinicpro/assets/admin/components/layout/ProfileMenu.test.tsx
T
hamedandClaude Opus 4.8 1aa6794786 feat: port tauri header top-menu to admin topbar
Rebuild admin Topbar to match clinic-pro-tauri header:
- Icon order: theme -> settings -> bell (was theme -> bell -> settings)
- Settings gear now navigates to the role-based settings page
  instead of opening the personalization panel
- Search placeholder changed to «جستجو», dropped the ⌘K hint
- Add ProfileMenu: avatar + user name + context/role subtitle + caret,
  with a dropdown (profile / payments / settings / personalization / logout).
  Links are role-aware; personalization keeps the existing settings panel.

Frontend-only, no API changes. Adds ProfileMenu.test + Topbar.test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:44:47 +03:30

125 lines
4.9 KiB
TypeScript

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-dom', async () => {
const actual = await vi.importActual<typeof import('react-router-dom')>('react-router-dom');
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<string, unknown>) {
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(<ProfileMenu />);
expect(screen.getByText('دکتر رضایی')).toBeInTheDocument();
expect(screen.getByText('کلینیک نور')).toBeInTheDocument();
});
it('وقتی context نیست، برچسب نقش را جایگزین می‌کند', () => {
setAuth({ context: null });
renderWithProviders(<ProfileMenu />);
expect(screen.getByText('پزشک')).toBeInTheDocument();
});
it('حالت خالی: نام پیش‌فرض «کاربر» و حرف اول «ک»', () => {
setAuth({ userName: null, context: null, primaryRole: null });
renderWithProviders(<ProfileMenu />);
expect(screen.getByText('کاربر')).toBeInTheDocument();
// حرف اولِ آواتار
expect(screen.getByTitle('کاربر').textContent).toContain('ک');
});
});
describe('ProfileMenu — باز/بستن و آیتم‌ها', () => {
it('منو ابتدا بسته است و با کلیک باز می‌شود', () => {
renderWithProviders(<ProfileMenu />);
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(<ProfileMenu />);
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(<ProfileMenu />);
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(<ProfileMenu />);
fireEvent.click(screen.getByTitle('دکتر رضایی'));
fireEvent.click(screen.getByText('شخصی‌سازی'));
expect(togglePanelMock).toHaveBeenCalledTimes(1);
});
it('خروج، logout را صدا می‌زند و به صفحه ورود می‌رود', () => {
renderWithProviders(<ProfileMenu />);
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');
});
});