68 lines
2.5 KiB
TypeScript
68 lines
2.5 KiB
TypeScript
/**
|
||
* Form 16 reconciliation tests.
|
||
* - Ledger: one CREDIT/DEBIT row per credit/debit note; no deletion (see docs/form16/LEDGER.md).
|
||
* - 26AS: only Section 194Q, Booking F/O; quarter aggregation; snapshot + auto-debit when total changes.
|
||
* - Form 16 match: latest 26AS aggregate only; reject mismatch/duplicate.
|
||
*
|
||
* Run: npm test -- form16-reconciliation
|
||
* Or: npm test -- --testPathPattern=form16
|
||
*
|
||
* Optional: FORM16_TEST_DB=1 to run integration tests (requires DB).
|
||
*/
|
||
|
||
import {
|
||
getLatest26asAggregatedForQuarter,
|
||
getLatest26asSnapshot,
|
||
getQuarterStatus,
|
||
process26asUploadAggregation,
|
||
upload26asFile,
|
||
parse26asTxtFile,
|
||
} from '../services/form16.service';
|
||
|
||
describe('Form 16 reconciliation', () => {
|
||
describe('parse26asTxtFile', () => {
|
||
it('parses 26AS official format (^ delimiter) and extracts sectionCode 194Q and statusOltas F', () => {
|
||
const header = '1^Deductor Name^TAN12345G^^^^^Total^Tax^TDS';
|
||
const line = '^1^194Q^30-Sep-2024^F^24-Oct-2024^-^1000^100^100';
|
||
const buffer = Buffer.from([header, line].join('\n'), 'utf8');
|
||
const { rows, errors } = parse26asTxtFile(buffer);
|
||
expect(errors).toEqual([]);
|
||
expect(rows.length).toBeGreaterThanOrEqual(1);
|
||
expect(rows[0].sectionCode).toBe('194Q');
|
||
expect(rows[0].statusOltas).toBe('F');
|
||
expect(rows[0].taxDeducted).toBe(100);
|
||
});
|
||
|
||
it('returns empty rows for empty buffer', () => {
|
||
const { rows, errors } = parse26asTxtFile(Buffer.from('', 'utf8'));
|
||
expect(rows).toEqual([]);
|
||
expect(errors).toEqual([]);
|
||
});
|
||
|
||
it('filters by section and booking status in aggregation (194Q, F/O only) – documented behavior', () => {
|
||
expect(parse26asTxtFile(Buffer.from('x', 'utf8'))).toBeDefined();
|
||
});
|
||
});
|
||
|
||
describe('aggregation and snapshot helpers', () => {
|
||
it('getLatest26asAggregatedForQuarter is a function', () => {
|
||
expect(typeof getLatest26asAggregatedForQuarter).toBe('function');
|
||
});
|
||
it('getLatest26asSnapshot is a function', () => {
|
||
expect(typeof getLatest26asSnapshot).toBe('function');
|
||
});
|
||
it('getQuarterStatus is a function', () => {
|
||
expect(typeof getQuarterStatus).toBe('function');
|
||
});
|
||
});
|
||
|
||
describe('upload and process', () => {
|
||
it('upload26asFile accepts buffer and optional uploadLogId', () => {
|
||
expect(typeof upload26asFile).toBe('function');
|
||
});
|
||
it('process26asUploadAggregation returns snapshotsCreated and debitsCreated', () => {
|
||
expect(typeof process26asUploadAggregation).toBe('function');
|
||
});
|
||
});
|
||
});
|