c6d4260ede
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
111 lines
4.6 KiB
JavaScript
111 lines
4.6 KiB
JavaScript
// Behaviour test for static/js/task-results.js (#53 #54 #55), plain node, no framework.
|
|
// Run: node tests/js/test_task_results.js (exit code != 0 on failure)
|
|
const assert = require('assert');
|
|
const { taskResultForm } = require('../../static/js/task-results.js');
|
|
|
|
const calls = [];
|
|
let responses = [];
|
|
global.window = {
|
|
__taskResultsCfg: {
|
|
saveUrl: '/s', listUrl: '/l', uploadUrl: '/u', taskUrlTpl: '/t/0',
|
|
labels: { nokNeedsNote: 'Per un NOK serve la nota' },
|
|
},
|
|
sessionStorage: { _d: {}, getItem(k) { return this._d[k] || null; }, setItem(k, v) { this._d[k] = v; } },
|
|
};
|
|
global.FormData = class { constructor() { this.d = []; } append(k, v, n) { this.d.push([k, v, n]); } };
|
|
global.fetch = async (url, opts) => {
|
|
calls.push({ url, opts });
|
|
const r = responses.shift() || { status: 200, body: {} };
|
|
return { ok: r.status < 400, status: r.status, json: async () => r.body };
|
|
};
|
|
|
|
function comp(runId) {
|
|
const c = taskResultForm();
|
|
c.ctx = () => ({ runId, done() { c._done = (c._done || 0) + 1; } });
|
|
return c;
|
|
}
|
|
|
|
(async () => {
|
|
// check: NOK without note is refused before any request
|
|
let c = comp(4);
|
|
c.initForTask({ id: 30, task_type: 'check' });
|
|
responses = [{ status: 200, body: [] }]; // loadLast
|
|
await c.submit('nok');
|
|
assert.strictEqual(c.forms[0].error, 'Per un NOK serve la nota');
|
|
assert.ok(!calls.some((x) => x.url === '/s'), 'no POST for a NOK without note');
|
|
|
|
// check: OK goes to the server with the run id, then hands over
|
|
calls.length = 0;
|
|
responses = [{ status: 201, body: { id: 1, outcome: 'ok' } }];
|
|
await c.submit('ok');
|
|
const post = calls.find((x) => x.url === '/s');
|
|
const body = JSON.parse(post.opts.body);
|
|
assert.deepStrictEqual([body.task_id, body.production_run_id, body.outcome, body.values], [30, 4, 'ok', null]);
|
|
assert.strictEqual(c._done, 1);
|
|
assert.strictEqual(c.forms[0].result.outcome, 'ok');
|
|
|
|
// server 422: the detail is shown, nothing is handed over
|
|
c = comp(4);
|
|
responses = [{ status: 200, body: [] }, { status: 422, body: { detail: 'Per un NOK serve la nota' } }];
|
|
c.initForTask({ id: 30, task_type: 'check' }); // consumes the first one (loadLast)
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
c.forms[0].note = 'x';
|
|
await c.submit('nok');
|
|
assert.strictEqual(c.forms[0].error, 'Per un NOK serve la nota');
|
|
assert.ok(!c._done);
|
|
|
|
// note with fields: defaults, upload of the attachment, values + attachments in the result
|
|
calls.length = 0;
|
|
c = comp(null);
|
|
const task = { id: 31, task_type: 'note', fields: [
|
|
{ key: 'peso', label: 'Peso', type: 'number', default: '1,5', attachment: false },
|
|
{ key: 'foto', label: 'Foto', type: 'text', default: null, attachment: true },
|
|
] };
|
|
c.initForTask(task);
|
|
assert.strictEqual(c.forms[0].values.peso, '1,5');
|
|
c.forms[0].files.foto = { name: 'a.png' };
|
|
responses = [
|
|
{ status: 201, body: { file_path: 'general/a.png' } },
|
|
{ status: 201, body: { id: 2, outcome: 'done' } },
|
|
];
|
|
await c.submit('done');
|
|
const saved = JSON.parse(calls.find((x) => x.url === '/s').opts.body);
|
|
assert.deepStrictEqual(saved.values, { peso: '1.5' });
|
|
assert.deepStrictEqual(saved.attachments, [{ key: 'foto', path: 'general/a.png', name: 'a.png' }]);
|
|
assert.strictEqual(saved.outcome, 'done');
|
|
assert.strictEqual(saved.production_run_id, null);
|
|
|
|
// non numeric value in a number field is refused locally
|
|
c = comp(null);
|
|
c.initForTask(task);
|
|
c.forms[0].values.peso = 'abc';
|
|
await c.submit('done');
|
|
assert.ok(c.forms[0].error.indexOf('Peso') !== -1);
|
|
|
|
// a note without fields has no panel
|
|
c = comp(null);
|
|
c.initForTask({ id: 33, task_type: 'note', fields: [] });
|
|
assert.strictEqual(c.forms.length, 0);
|
|
|
|
// end of production: tasks already recorded in the run are skipped; the rest recorded then handed over
|
|
calls.length = 0;
|
|
c = comp(4);
|
|
responses = [
|
|
{ status: 200, body: [{ task_id: 40 }] }, // results of the run
|
|
{ status: 200, body: { id: 40, title: 'A', task_type: 'note', fields: [] } },
|
|
{ status: 200, body: { id: 41, title: 'B', task_type: 'note', fields: [{ key: 'k', label: 'K', type: 'text', default: null, attachment: false }] } },
|
|
];
|
|
await c.openClose([40, 41]);
|
|
assert.strictEqual(c.forms[0].recorded, true);
|
|
assert.strictEqual(c.forms[1].recorded, false);
|
|
assert.ok(c.open && !c._done);
|
|
c.forms[1].values.k = 'ok';
|
|
responses = [{ status: 201, body: { id: 5, outcome: 'done' } }];
|
|
await c.submitClose();
|
|
assert.strictEqual(c._done, 1);
|
|
assert.strictEqual(c.open, false);
|
|
assert.strictEqual(calls.filter((x) => x.url === '/s').length, 1, 'only the pending task is posted');
|
|
|
|
console.log('ok');
|
|
})().catch((e) => { console.error(e); process.exit(1); });
|