Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions __tests__/BatchInvoiceForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,32 @@ GTEST123,1000.00,USDC,3.50,2024-12-31`;
// Should show total amount in summary
expect(screen.getByText('Total Amount')).toBeInTheDocument();
});

it('rejects/truncates 51-row CSV client-side with clear message matching 50-row contract limit', async () => {
render(<BatchInvoiceForm onSuccess={mockOnSuccess} />);

// Build a CSV with 51 rows
const header = 'payer,amount,token,discount_rate,due_date';
const rows = Array.from({ length: 51 }, (_, i) =>
`GTEST${i}EXAMPLE456DEF789GHI012JKL345MNO678PQR901STU234VWX567YZ,1000.00,USDC,3.50,2024-12-31`
);
const csvContent = [header, ...rows].join('\n');

const file = new File([csvContent], 'test_51.csv', { type: 'text/csv' });
const input = screen.getByLabelText('Click to upload CSV file').querySelector('input');

if (input) {
fireEvent.change(input, { target: { files: [file] } });
}

await waitFor(() => {
expect(mockAddToast).toHaveBeenCalledWith(
expect.objectContaining({
type: 'warning',
title: 'Rows Truncated',
message: 'Only the first 50 rows were loaded.',
})
);
});
});
});
1 change: 1 addition & 0 deletions src/components/BatchInvoiceForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { submitInvoicesBatch } from '@/utils/soroban';
import TokenSelector from './TokenSelector';

// Enforces maximum 50 rows per batch, matching the contract's submit_invoices_batch() instruction (source of truth)
const MAX_BATCH_SIZE = 50;

export interface BatchInvoiceRow extends InvoiceFormValues {
Expand Down
22 changes: 22 additions & 0 deletions src/components/__tests__/BatchInvoiceForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,26 @@ describe('BatchInvoiceForm', () => {
render(<BatchInvoiceForm onSuccess={vi.fn()} />);
expect(screen.queryByText(/batch/i)).toBeInTheDocument();
});

it('rejects 51-row CSV file exceeding contract batch limit with a clear notification', async () => {
render(<BatchInvoiceForm onSuccess={vi.fn()} />);
const header = 'payer,amount,token,discount_rate,due_date';
const rows = Array.from({ length: 51 }, (_, i) =>
`GCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC${i % 10},100.00,USDC,3.00,2025-12-31`
);
const file = new File([[header, ...rows].join('\n')], 'over_limit.csv', { type: 'text/csv' });
const input = document.getElementById('csv-upload') as HTMLInputElement | null;
if (input) {
fireEvent.change(input, { target: { files: [file] } });
await waitFor(() => {
expect(addToast).toHaveBeenCalledWith(
expect.objectContaining({
type: 'warning',
title: 'Rows Truncated',
message: 'Only the first 50 rows were loaded.',
})
);
});
}
});
});
Loading