// 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); });