diff --git a/backend/test/api.test.js b/backend/test/api.test.js index e55d0cb..44bfcfe 100644 --- a/backend/test/api.test.js +++ b/backend/test/api.test.js @@ -390,6 +390,76 @@ describe('Provenance', () => { // Body is HTML, not JSON — the request helper returns it as a string assert.ok(typeof res.body === 'string', 'should return HTML string'); }); + + test('GET /provenance/:lotId/data includes payment_summary', async () => { + const res = await get(`/provenance/${lotId}/data`); + assert.equal(res.status, 200); + assert.ok(res.body.payment_summary, 'should include payment_summary'); + assert.equal(typeof res.body.payment_summary.worker_count, 'number'); + }); + + test('GET /provenance/:lotId/data workers array has expected fields', async () => { + const res = await get(`/provenance/${lotId}/data`); + assert.equal(res.status, 200); + assert.ok(res.body.workers.length >= 1, 'should have at least one worker'); + const worker = res.body.workers[0]; + assert.ok('name' in worker, 'worker should have name'); + assert.ok('checked_in_at' in worker, 'worker should have checked_in_at'); + }); + + test('GET /provenance/:lotId/data lot has farm_id and shift_id', async () => { + const res = await get(`/provenance/${lotId}/data`); + assert.equal(res.status, 200); + assert.ok(res.body.lot.farm_id, 'lot should have farm_id'); + assert.ok(res.body.lot.shift_id, 'lot should have shift_id'); + }); + + test('GET /provenance/:lotId/data transfers have parsed metadata', async () => { + const res = await get(`/provenance/${lotId}/data`); + assert.equal(res.status, 200); + for (const t of res.body.transfers) { + if (t.metadata !== null) { + assert.equal(typeof t.metadata, 'object', 'metadata should be parsed JSON'); + } + } + }); + + test('GET /provenance/:lotId/qr returns SVG for valid lot', async () => { + const res = await new Promise((resolve, reject) => { + const url = new URL(`/provenance/${lotId}/qr`, baseUrl); + const req = http.request({ + hostname: url.hostname, port: url.port, + path: url.pathname, method: 'GET', + }, (response) => { + let data = ''; + response.on('data', chunk => { data += chunk; }); + response.on('end', () => resolve({ status: response.statusCode, headers: response.headers, body: data })); + }); + req.on('error', reject); + req.end(); + }); + assert.equal(res.status, 200); + assert.ok(res.headers['content-type'].includes('image/svg+xml')); + assert.ok(res.body.includes(' { + const res = await get('/provenance/nonexistent-lot-id/qr'); + assert.equal(res.status, 404); + assert.ok(res.body.error); + }); + + test('GET /provenance/:lotId/data farm matches lot farm_id', async () => { + const res = await get(`/provenance/${lotId}/data`); + assert.equal(res.status, 200); + assert.equal(res.body.farm.id, res.body.lot.farm_id, 'farm id should match lot farm_id'); + }); + + test('GET /provenance/:lotId/data shift matches lot shift_id', async () => { + const res = await get(`/provenance/${lotId}/data`); + assert.equal(res.status, 200); + assert.equal(res.body.shift.id, res.body.lot.shift_id, 'shift id should match lot shift_id'); + }); }); describe('Payroll', () => {