initial commit
This commit is contained in:
100
src/api/uploads.test.ts
Normal file
100
src/api/uploads.test.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* 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> = {}): 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');
|
||||
});
|
||||
Reference in New Issue
Block a user