- Add RecordNumberSettingsController for managing patient record number patterns. - Create RecordNumberPattern entity to represent the pattern configuration. - Implement RecordNumberPatternRepository for database interactions. - Develop RecordNumberGenerator service for generating and validating record numbers. - Add tests for record number generation, backfilling, and API interactions. - Ensure proper access control for viewing and updating patterns based on user roles.
92 lines
4.6 KiB
TypeScript
92 lines
4.6 KiB
TypeScript
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
import { screen, fireEvent, 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 {},
|
|
}));
|
|
|
|
import { api } from '../lib/api';
|
|
import PatientRecordFormPage from './PatientRecordFormPage';
|
|
|
|
const get = api.get as ReturnType<typeof vi.fn>;
|
|
const post = api.post as ReturnType<typeof vi.fn>;
|
|
|
|
/** الگوی شمارهٔ پرونده؛ `enabled=false` یعنی رفتار قدیمیِ ورود دستی. */
|
|
function mockPattern(settings: Record<string, unknown>) {
|
|
get.mockImplementation((url: string) =>
|
|
url.includes('patient-record-number-settings')
|
|
? Promise.resolve({ success: true, data: { pattern: '{YY}-{SEQ:4}', reset_policy: 'none', counter: 0, next_preview: '05-0001', ...settings } })
|
|
: Promise.resolve({ success: true, data: [] }),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* پرکردن فیلدهای الزامیِ دیگر تا فقط شمارهٔ پرونده متغیر بماند.
|
|
*
|
|
* اول منتظر رسیدن تنظیمات میماند: رندرِ بعد از پاسخ، منوی باز react-select را
|
|
* میبندد و انتخاب جنسیت را میخورد.
|
|
*/
|
|
async function fillRequiredFields() {
|
|
await waitFor(() => expect(get).toHaveBeenCalledWith(expect.stringContaining('patient-record-number-settings')));
|
|
await waitFor(() => expect(screen.getByRole('button', { name: /ثبت|ذخیره/ })).toBeEnabled());
|
|
|
|
fireEvent.change(await screen.findByPlaceholderText('نام و نام خانوادگی را وارد نمایید'), { target: { value: 'علی محمدی' } });
|
|
fireEvent.change(screen.getByPlaceholderText('کد ملی را وارد نمایید'), { target: { value: '0012345675' } });
|
|
fireEvent.change(screen.getByPlaceholderText('شماره تماس را وارد نمایید'), { target: { value: '09121234567' } });
|
|
const gender = document.getElementById('patient-gender-select') as HTMLInputElement;
|
|
fireEvent.focus(gender);
|
|
fireEvent.keyDown(gender, { key: 'ArrowDown' });
|
|
fireEvent.click(await screen.findByText('مرد'));
|
|
}
|
|
|
|
beforeEach(() => {
|
|
get.mockReset();
|
|
post.mockReset();
|
|
post.mockResolvedValue({ success: true, data: { uuid: 'rec-new' } });
|
|
(api.patch as ReturnType<typeof vi.fn>).mockResolvedValue({ success: true, data: {} });
|
|
});
|
|
|
|
describe('PatientRecordFormPage — شمارهٔ پرونده', () => {
|
|
/** ⚠️ مرزی: بدون الگو، فیلد الزامی میماند (رفتار امروز). */
|
|
it('بدون الگو شماره پرونده الزامی است', async () => {
|
|
mockPattern({ enabled: false, can_edit: true });
|
|
renderWithProviders(<PatientRecordFormPage />, { route: '/admin/patients/new' });
|
|
|
|
await fillRequiredFields();
|
|
fireEvent.click(screen.getByText('ثبت اطلاعات') ?? screen.getByRole('button', { name: /ثبت|ذخیره/ }));
|
|
|
|
expect(await screen.findByText('شماره پرونده الزامی است')).toBeInTheDocument();
|
|
expect(post).not.toHaveBeenCalled();
|
|
});
|
|
|
|
/** ✅ موفق: با الگوی فعال و بدون اجازهٔ دستی، فیلد read-only است و ارسال نمیشود. */
|
|
it('با الگوی فعال و بدون can_edit، شماره فرستاده نمیشود', async () => {
|
|
mockPattern({ enabled: true, can_edit: false });
|
|
renderWithProviders(<PatientRecordFormPage />, { route: '/admin/patients/new' });
|
|
|
|
expect(await screen.findByText('شماره از الگوی مجموعه ساخته میشود')).toBeInTheDocument();
|
|
|
|
await fillRequiredFields();
|
|
fireEvent.click(screen.getByRole('button', { name: /ثبت|ذخیره/ }));
|
|
|
|
await waitFor(() => expect(post).toHaveBeenCalled());
|
|
expect(post.mock.calls[0][1]).not.toHaveProperty('record_number');
|
|
});
|
|
|
|
/** ✅ موفق: صاحب مجموعه میتواند خالی بگذارد تا سرور بسازد. */
|
|
it('صاحب مجموعه میتواند شماره را خالی بگذارد', async () => {
|
|
mockPattern({ enabled: true, can_edit: true });
|
|
renderWithProviders(<PatientRecordFormPage />, { route: '/admin/patients/new' });
|
|
|
|
expect(await screen.findByText(/خالی بماند تا از الگو ساخته شود/)).toBeInTheDocument();
|
|
|
|
await fillRequiredFields();
|
|
fireEvent.click(screen.getByRole('button', { name: /ثبت|ذخیره/ }));
|
|
|
|
await waitFor(() => expect(post).toHaveBeenCalled());
|
|
expect(post.mock.calls[0][1].record_number).toBe('');
|
|
});
|
|
});
|