Files
salona/tests/EditInformation.test.tsx
farnoosh-krm 76998f5585 (fix) - new tests added
- edit information
- sms settings
2026-04-18 12:25:27 +03:30

321 lines
9.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { useUpdateUser } from '@/apps/new-ui/services/User';
import { useGetAllSpecialties } from '@/apps/new-ui/services/Specialty';
import toast from 'react-hot-toast';
import EditInformation from '@/apps/new-ui/pages/Profile/+components/EditInformation';
// Mock کردن ماژول‌ها
jest.mock('@/apps/new-ui/services/User');
jest.mock('@/apps/new-ui/services/Specialty');
jest.mock('react-hot-toast');
jest.mock("react-dom", () => ({
...jest.requireActual("react-dom"),
createPortal: (node: any) => node,
}));
jest.mock("@/utils/axios-interceptor", () => ({
appointmentClient: {
get: jest.fn(),
post: jest.fn(),
put: jest.fn(),
delete: jest.fn(),
},
}));
jest.mock("../src/apps/new-ui/Utils/env.ts", () => ({
ENV: {
API_URL: "https://api.test",
},
}));
jest.mock('@/apps/new-ui/components/MobilePicker/MobileScrollDatePicker', () => ({
__esModule: true,
default: ({ value, onChange }: any) => (
<div data-testid="date-picker">
<input
type="date"
value={value}
onChange={(e) => onChange(e.target.value)}
data-testid="date-input"
/>
</div>
),
}));
jest.mock('@/apps/new-ui/components/Inputs/NumericInput', () => ({
__esModule: true,
default: ({ value, onChange, placeholder, className, ...props }: any) => (
<input
type="text"
value={value}
onChange={(e) => onChange(e.target.value)}
placeholder={placeholder}
className={className}
data-testid="numeric-input"
{...props}
/>
),
}));
jest.mock('@/apps/new-ui/components/CustomeComponents/MapPicker', () => ({
__esModule: true,
default: ({ latitude, longitude, onChange }: any) => (
<div data-testid="map-picker">
<button
data-testid="map-click"
onClick={() => onChange(35.7000, 51.4000)}
>
Change Location
</button>
<span>Lat: {latitude}, Lng: {longitude}</span>
</div>
),
}));
// مسیرهای اصلاح شده
jest.mock('@/apps/new-ui/pages/Profile/+components/EditPhoto', () => ({
__esModule: true,
default: ({ onClose }: any) => (
<div data-testid="edit-photo-modal">
<button onClick={onClose} data-testid="close-photo-modal">Close</button>
</div>
),
}));
jest.mock('@/apps/new-ui/pages/Profile/+components/SelectSpecialization', () => ({
__esModule: true,
default: ({ selectedSpecialization, onSpecializationChange, specializations }: any) => (
<div data-testid="specialization-select">
<select
value={selectedSpecialization}
onChange={(e) => onSpecializationChange(e.target.value)}
data-testid="specialization-dropdown"
>
<option value="">انتخاب تخصص</option>
{specializations?.map((spec: any) => (
<option key={spec.id} value={spec.name}>{spec.name}</option>
))}
</select>
</div>
),
}));
jest.mock('@/apps/new-ui/pages/Profile/+components/SelectProvinceCity', () => ({
__esModule: true,
default: ({ selectedProvince, selectedCity, onProvinceChange, onCityChange }: any) => (
<div data-testid="province-city-select">
<input
data-testid="province-input"
value={selectedProvince}
onChange={(e) => onProvinceChange(e.target.value)}
placeholder="استان"
/>
<input
data-testid="city-input"
value={selectedCity}
onChange={(e) => onCityChange(e.target.value)}
placeholder="شهر"
/>
</div>
),
}));
// Mock createPortal
jest.mock('react-dom', () => ({
...jest.requireActual('react-dom'),
createPortal: (node: React.ReactNode) => node,
}));
describe('EditInformation', () => {
const mockOnClick = jest.fn();
const mockUpdateUser = jest.fn();
const mockUserInfo = {
name: 'علی رضایی',
phone_number: '09123456789',
profile_picture: 'profile.jpg',
city: 'تهران',
date_of_birth: '1990-01-01',
province: 'تهران',
specialty: 'قلب',
address: 'خیابان ولیعصر، پلاک ۱۲۳',
latitude: 35.6892,
longitude: 51.3890,
};
const mockSpecialties = {
specialties: [
{ id: 1, name: 'قلب' },
{ id: 2, name: 'مغز و اعصاب' },
{ id: 3, name: 'ارتوپدی' },
],
};
beforeEach(() => {
jest.clearAllMocks();
(useUpdateUser as jest.Mock).mockReturnValue({
mutate: mockUpdateUser,
isPending: false
});
(useGetAllSpecialties as jest.Mock).mockReturnValue({
data: mockSpecialties
});
(toast.error as jest.Mock).mockImplementation(() => {});
});
const renderComponent = (props = {}) => {
return render(
<EditInformation
onclick={mockOnClick}
userInfo={mockUserInfo}
{...props}
/>
);
};
it('should render correctly with user info', () => {
renderComponent();
expect(screen.getByText('ویرایش اطلاعات')).toBeInTheDocument();
expect(screen.getByDisplayValue('علی رضایی')).toBeInTheDocument();
expect(screen.getByDisplayValue('09123456789')).toBeInTheDocument();
});
it('should render with default values when no userInfo provided', () => {
render(<EditInformation onclick={mockOnClick} />);
const nameInput = screen.getByPlaceholderText('نام و نام خانوادگی');
expect(nameInput).toHaveValue('');
const phoneInput = screen.getByPlaceholderText('شماره موبایل');
expect(phoneInput).toHaveValue('');
});
it('should update name input value', async () => {
renderComponent();
const nameInput = screen.getByDisplayValue('علی رضایی');
fireEvent.change(nameInput, { target: { value: 'احمد محمدی' } });
expect(nameInput).toHaveValue('احمد محمدی');
});
it('should update phone number', async () => {
renderComponent();
const phoneInput = screen.getByDisplayValue('09123456789');
fireEvent.change(phoneInput, { target: { value: '09987654321' } });
expect(phoneInput).toHaveValue('09987654321');
});
it('should call updateUser with correct data on save', async () => {
mockUpdateUser.mockImplementation((_data: any, { onSuccess }: any) => {
onSuccess();
});
renderComponent();
const saveButton = screen.getByText('ذخیره');
fireEvent.click(saveButton);
await waitFor(() => {
expect(mockUpdateUser).toHaveBeenCalledWith(
expect.objectContaining({
name: 'علی رضایی',
phone_number: '09123456789',
specialty: 'قلب',
province: 'تهران',
city: 'تهران',
}),
expect.any(Object)
);
});
});
it('should show error toast on update failure', async () => {
mockUpdateUser.mockImplementation((_data: any, { onError }: any) => {
onError(new Error('Update failed'));
});
renderComponent();
const saveButton = screen.getByText('ذخیره');
fireEvent.click(saveButton);
await waitFor(() => {
expect(toast.error).toHaveBeenCalledWith('خطا در به روز رسانی اطلاعات');
});
});
it('should call onclick after successful save', async () => {
mockUpdateUser.mockImplementation((_data: any, { onSuccess }: any) => {
onSuccess();
});
renderComponent();
const saveButton = screen.getByText('ذخیره');
fireEvent.click(saveButton);
await waitFor(() => {
expect(mockOnClick).toHaveBeenCalled();
});
});
it('should open and close edit photo modal', async () => {
renderComponent();
const profilePhoto = screen.getByAltText('profile');
fireEvent.click(profilePhoto);
expect(screen.getByTestId('edit-photo-modal')).toBeInTheDocument();
const closeButton = screen.getByTestId('close-photo-modal');
fireEvent.click(closeButton);
await waitFor(() => {
expect(screen.queryByTestId('edit-photo-modal')).not.toBeInTheDocument();
});
});
it('should show hover effect on profile photo', async () => {
renderComponent();
const profileDiv = screen.getByAltText('profile').parentElement!;
fireEvent.mouseEnter(profileDiv);
expect(screen.getByAltText('editIcon')).toBeInTheDocument();
fireEvent.mouseLeave(profileDiv);
await waitFor(() => {
expect(screen.queryByAltText('editIcon')).not.toBeInTheDocument();
});
});
it('should disable save button while updating', async () => {
(useUpdateUser as jest.Mock).mockReturnValue({
mutate: mockUpdateUser,
isPending: true
});
renderComponent();
const saveButton = screen.getByText('در حال ذخیره...');
expect(saveButton).toBeDisabled();
});
it('should call onCancel when cancel button is clicked', () => {
renderComponent();
const cancelButton = screen.getByText('انصراف');
fireEvent.click(cancelButton);
expect(mockOnClick).toHaveBeenCalled();
});
it('should enforce maxLength on name input', () => {
renderComponent();
const nameInput = screen.getByDisplayValue('علی رضایی');
expect(nameInput).toHaveAttribute('maxLength', '30');
});
});