import { render, screen, fireEvent } from '@testing-library/react'; import { ThemeProvider } from '../../theme'; import type { NursePayoutHistoryItem, PayoutStatus } from '@/services/payouts/types'; jest.mock('next-intl', () => ({ useTranslations: () => (key: string) => key, useLocale: () => 'en', })); import PayoutHistoryRow from './PayoutHistoryRow'; function makeItem(status: PayoutStatus, overrides: Partial = {}): NursePayoutHistoryItem { return { id: 9001, batchId: 7001, status, grossEarningsIrr: '4250000', clawbackAppliedIrr: '0', netAmountIrr: '4250000', maskedIban: 'IR••••4821', transferReference: status === 'paid' ? 'PAYA-1' : null, paidAt: status === 'paid' ? '2026-06-10T00:00:00Z' : null, periodStart: '2026-06-01', periodEnd: '2026-06-07', failureReason: status === 'failed' ? 'invalid_sheba' : null, ...overrides, }; } function renderRow(item: NursePayoutHistoryItem, onOpen = jest.fn()) { const utils = render( , ); return { ...utils, onOpen }; } const STATUS_KIND: Array<{ status: PayoutStatus; kind: string }> = [ { status: 'pending', kind: 'pending' }, { status: 'submitted', kind: 'info' }, { status: 'paid', kind: 'verified' }, { status: 'failed', kind: 'rejected' }, ]; describe(' component', () => { it.each(STATUS_KIND)('maps the $status payout status to the $kind chip kind', ({ status, kind }) => { const { container } = renderRow(makeItem(status)); expect(container.querySelector(`[data-payout-status="${status}"]`)).toBeInTheDocument(); expect(container.querySelector(`[data-status="${kind}"]`)).toBeInTheDocument(); }); it('renders the net amount transferred in Toman and the masked IBAN', () => { renderRow(makeItem('paid')); expect(screen.getByText(/425,000/)).toBeInTheDocument(); // 4,250,000 ÷ 10 expect(screen.getByText('IR••••4821')).toBeInTheDocument(); }); it('surfaces a mapped failure label as the headline and the raw code as a secondary LTR caption', () => { renderRow(makeItem('failed')); expect(screen.getByText('failure_title')).toBeInTheDocument(); // The headline is the mapped Persian/English label (never the raw vendor string). expect(screen.getByText('failure_code_invalid_sheba')).toBeInTheDocument(); // The raw code still appears, demoted to a secondary dir="ltr" caption. expect(screen.getByText('invalid_sheba')).toHaveAttribute('dir', 'ltr'); // No retry affordance for the nurse — only the "view detail" link exists. expect(screen.queryByText('retry')).not.toBeInTheDocument(); }); it('opens the payout detail on click', () => { const onOpen = jest.fn(); renderRow(makeItem('paid', { id: 9002 }), onOpen); fireEvent.click(screen.getByText('view_payout_detail')); expect(onOpen).toHaveBeenCalledWith(9002); }); });