Replace the flat gateway-payment list on the patient detail «پرداختها» tab with the session-grouped accordion design ported from clinic-pro-tauri PaymentsSection: - New SessionPaymentAccordion mirrors the tauri accordion: header (service, date, final price, پرداخت شده/تسویه نشده badge) + a settlement line (date, amount, method, personnel=doctor) or the «هیچ پرداختی ثبت نشده است.» empty message. - New PaymentsTab reuses the already-fetched sessions query (real model = one payment_method per session) — no extra request, no backend change, no new API. - Add FilesServicePaymentsCheck icon (verbatim from tauri). - Remove the now-unused paymentsQ (gateway list), PAYMENT_STATUS map and the dead TabList helper (both its callers replaced by the ported card/accordion tabs). - Tests: SessionPaymentAccordion (paid/unpaid/collapsed/toggle) + updated the page payments-tab test to assert session accordions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
2.2 KiB
TypeScript
44 lines
2.2 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest';
|
|
import { render, screen } from '@testing-library/react';
|
|
import SessionPaymentAccordion, { type SessionPaymentData } from './SessionPaymentAccordion';
|
|
|
|
const paid: SessionPaymentData = {
|
|
uuid: 's1', services: [{ service_name: 'روکش' }], final_price_rials: 2500000,
|
|
doctor_name: 'دکتر فتحی', payment_method: 'cash', is_paid: true,
|
|
created_at: 1700000000, updated_at: 1700003600,
|
|
};
|
|
const unpaid: SessionPaymentData = {
|
|
uuid: 's2', services: [{ service_name: 'اسکیلینگ' }], final_price_rials: 1800000,
|
|
doctor_name: 'دکتر راد', payment_method: 'pending', is_paid: false, created_at: 1700000000,
|
|
};
|
|
|
|
describe('SessionPaymentAccordion', () => {
|
|
it('shows the settled badge + settlement line (method/personnel) when expanded', () => {
|
|
render(<SessionPaymentAccordion session={paid} expanded onToggle={() => {}} />);
|
|
expect(screen.getByText('روکش')).toBeInTheDocument();
|
|
expect(screen.getByText('پرداخت شده')).toBeInTheDocument();
|
|
expect(screen.getByText('نحوه پرداخت:')).toBeInTheDocument();
|
|
expect(screen.getByText('نقدی')).toBeInTheDocument(); // cash → نقدی
|
|
expect(screen.getByText('دکتر فتحی')).toBeInTheDocument(); // personnel = doctor
|
|
});
|
|
|
|
it('shows the unsettled badge + empty message for an unpaid session', () => {
|
|
render(<SessionPaymentAccordion session={unpaid} expanded onToggle={() => {}} />);
|
|
expect(screen.getByText('تسویه نشده')).toBeInTheDocument();
|
|
expect(screen.getByText('هیچ پرداختی ثبت نشده است.')).toBeInTheDocument();
|
|
});
|
|
|
|
it('hides the details when collapsed', () => {
|
|
render(<SessionPaymentAccordion session={paid} expanded={false} onToggle={() => {}} />);
|
|
expect(screen.getByText('پرداخت شده')).toBeInTheDocument(); // header still visible
|
|
expect(screen.queryByText('نحوه پرداخت:')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('calls onToggle when the summary is clicked', () => {
|
|
const onToggle = vi.fn();
|
|
render(<SessionPaymentAccordion session={paid} expanded={false} onToggle={onToggle} />);
|
|
screen.getByRole('button').click();
|
|
expect(onToggle).toHaveBeenCalledOnce();
|
|
});
|
|
});
|