/** * The receipt, and the two things it has to get right. * * A receipt exists because the ingest service's batch id is the only credential * for reading a result back, it is handed out once, and an unreviewed drop is * deleted after seven days. So the tests that matter are about not losing that * window, and about the label their admin reads when deciding whether to * approve the file. */ import assert from 'node:assert/strict'; import { test } from 'node:test'; import { buildSender, daysUntilExpiry, DROP_RETENTION_DAYS, type UploadReceipt } from './uploads'; function receipt(overrides: Partial = {}): UploadReceipt { return { uploadid: 1, tenantid: 1141, locationid: 1180, categoryid: 2, batchid: '49a82536866a483a9189954d3c749243', runid: '', filename: 'kmart-opening.xlsx', sender: 'Kmart · Peelamedu · abhishek', uploadedby: 1475, uploadedname: 'abhishek', rowcount: 20, laststatus: 'pending', inserted: 0, backfilled: 0, skipped: 0, rejected: 0, shelvedcount: 0, skippedcount: 0, shelvedat: null, created: new Date().toISOString(), updated: new Date().toISOString(), ...overrides, }; } const daysAgo = (n: number) => new Date(Date.now() - n * 86_400_000).toISOString(); test('a drop uploaded today has the full window left', () => { assert.equal(daysUntilExpiry(receipt()), DROP_RETENTION_DAYS); }); test('the window closes as the drop sits unreviewed', () => { assert.equal(daysUntilExpiry(receipt({ created: daysAgo(5) })), 2); }); // Never negative. A drop past the deadline is gone, and "-3 days left" would // read as a countdown that is still running. test('an expired drop reports zero, not a negative', () => { assert.equal(daysUntilExpiry(receipt({ created: daysAgo(30) })), 0); }); /* Retention applies to a drop nobody acted on. Once an admin releases it the run is the record and the drop's own expiry is irrelevant — showing a countdown on a released upload would push someone to chase a deadline that has already been met. */ test('a released drop has no expiry to report', () => { assert.equal(daysUntilExpiry(receipt({ runid: '8dcef8a2ad94', laststatus: 'retired' })), null); assert.equal(daysUntilExpiry(receipt({ laststatus: 'done' })), null); }); test('a receipt with an unreadable date reports nothing rather than guessing', () => { assert.equal(daysUntilExpiry(receipt({ created: 'not a date' })), null); }); /* The sender label. Free text on their side, capped at 60 characters, and shown to the admin who decides whether to run the file — so it has to identify the shop, not the console. */ test('the sender names the merchant, the branch and the person', () => { assert.equal( buildSender({ tenantname: 'Kmart', locationname: 'Peelamedu', username: 'abhishek' }), 'Kmart · Peelamedu · abhishek', ); }); // The tenant name is truncated, not the whole label. Cutting the tail would // drop the branch and the person — the two parts that say WHICH shelf and WHO — // and leave only a long restaurant name that identifies neither. test('a long merchant name is trimmed so the branch and person survive', () => { const sender = buildSender({ tenantname: 'Ninhao The New Age Chinese Restaurant', locationname: 'Race Course', username: 'abhishek', }); assert.ok(sender.length <= 60, `sender was ${sender.length} chars: ${sender}`); assert.ok(sender.includes('Race Course'), sender); assert.ok(sender.includes('abhishek'), sender); }); test('a sender with nothing to say still labels the console', () => { assert.equal(buildSender({}), 'nearle-console'); });