UNPKG

@accounter/scraper-app

Version:
161 lines (143 loc) 5.25 kB
import { describe, expect, it, vi } from 'vitest'; import { PayloadValidationError } from '../../validate-payload.js'; import { scrapeDiscount } from '../discount.js'; const CREDS = { id: 'src-1', ID: '123456789', password: 'pass' }; const DATE_FROM = new Date('2024-01-01'); const DATE_TO = new Date('2024-01-31'); const noop = () => {}; const VALID_MONTH_RESULT = { success: true, accountNumber: 'ACC-001', balance: 5000, transactions: [ { OperationDate: '20240101', ValueDate: '20240101', OperationCode: '1', OperationDescription: 'Credit', OperationAmount: 1000, BalanceAfterOperation: 5000, OperationNumber: 1, OperationDescription2: '', OperationDescription3: '', OperationBranch: 1, OperationBank: 1, Channel: 'web', ChannelName: 'Web', InstituteCode: '1', BranchTreasuryNumber: '1', Urn: 'urn-1', OperationDetailsServiceName: '', CommissionChannelCode: '', CommissionChannelName: '', CommissionTypeName: '', BusinessDayDate: '20240101', EventName: '', CategoryCode: 1, CategoryDescCode: 1, CategoryDescription: '', OperationDescriptionToDisplay: 'Credit', OperationOrder: 1, IsLastSeen: false, }, ], }; vi.mock('@accounter/modern-poalim-scraper', () => ({ init: vi.fn(), })); async function getInitMock() { const mod = await import('@accounter/modern-poalim-scraper'); return mod.init as ReturnType<typeof vi.fn>; } describe('scrapeDiscount — happy path', () => { it('resolves with a validated DiscountPayload containing one entry per month', async () => { const initMock = await getInitMock(); initMock.mockResolvedValue({ discount: vi.fn().mockResolvedValue({ getMonthTransactions: vi.fn().mockResolvedValue(VALID_MONTH_RESULT), }), close: vi.fn().mockResolvedValue(undefined), }); const result = await scrapeDiscount(CREDS, DATE_FROM, DATE_TO, noop); expect(Array.isArray(result)).toBe(true); expect(result).toHaveLength(1); expect(result[0]).toMatchObject({ accountNumber: 'ACC-001', month: '2024-01', balance: 5000, }); expect(result[0]!.transactions).toHaveLength(1); }); it('fetches one month per month in the date range', async () => { const getMonthTransactions = vi.fn().mockResolvedValue(VALID_MONTH_RESULT); const initMock = await getInitMock(); initMock.mockResolvedValue({ discount: vi.fn().mockResolvedValue({ getMonthTransactions }), close: vi.fn().mockResolvedValue(undefined), }); const threeMonthsFrom = new Date('2024-01-01'); const threeMonthsTo = new Date('2024-03-31'); const result = await scrapeDiscount(CREDS, threeMonthsFrom, threeMonthsTo, noop); expect(getMonthTransactions).toHaveBeenCalledTimes(3); expect(result).toHaveLength(3); expect(result.map(r => r.month)).toEqual(['2024-01', '2024-02', '2024-03']); }); it('passes the correct month Date to getMonthTransactions', async () => { const getMonthTransactions = vi.fn().mockResolvedValue(VALID_MONTH_RESULT); const initMock = await getInitMock(); initMock.mockResolvedValue({ discount: vi.fn().mockResolvedValue({ getMonthTransactions }), close: vi.fn().mockResolvedValue(undefined), }); await scrapeDiscount(CREDS, DATE_FROM, DATE_TO, noop); expect(getMonthTransactions).toHaveBeenCalledWith(expect.any(Date)); }); it('calls close() even on success', async () => { const close = vi.fn().mockResolvedValue(undefined); const initMock = await getInitMock(); initMock.mockResolvedValue({ discount: vi.fn().mockResolvedValue({ getMonthTransactions: vi.fn().mockResolvedValue(VALID_MONTH_RESULT), }), close, }); await scrapeDiscount(CREDS, DATE_FROM, DATE_TO, noop); expect(close).toHaveBeenCalledOnce(); }); }); describe('scrapeDiscount — invalid payload', () => { it('throws PayloadValidationError when data fails schema validation', async () => { const initMock = await getInitMock(); initMock.mockResolvedValue({ discount: vi.fn().mockResolvedValue({ getMonthTransactions: vi.fn().mockResolvedValue({ success: true, accountNumber: 'ACC-001', balance: 0, transactions: [{ OperationDate: 'bad' }], // missing required fields }), }), close: vi.fn().mockResolvedValue(undefined), }); await expect(scrapeDiscount(CREDS, DATE_FROM, DATE_TO, noop)).rejects.toBeInstanceOf( PayloadValidationError, ); }); it('calls close() even on validation error', async () => { const close = vi.fn().mockResolvedValue(undefined); const initMock = await getInitMock(); initMock.mockResolvedValue({ discount: vi.fn().mockResolvedValue({ getMonthTransactions: vi.fn().mockResolvedValue({ success: true, accountNumber: 'ACC-001', balance: 0, transactions: [{ OperationDate: 'bad' }], }), }), close, }); await expect(scrapeDiscount(CREDS, DATE_FROM, DATE_TO, noop)).rejects.toThrow(); expect(close).toHaveBeenCalledOnce(); }); });