50 lines
2.5 KiB
JavaScript
50 lines
2.5 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import {readFile} from 'node:fs/promises';
|
|
import vm from 'node:vm';
|
|
import test from 'node:test';
|
|
import {transformSync} from 'esbuild';
|
|
|
|
const source = await readFile(new URL('../service/server/update/function_list.ts', import.meta.url), 'utf8');
|
|
const code = transformSync(source.replace(/^import .*;\n/gm, '')
|
|
.replace('export async function', 'async function'), {loader: 'ts'}).code;
|
|
|
|
function fixture(response = {status: 'success', data: 0}) {
|
|
const reports = []; const logs = [];
|
|
const list = [{path: 'inventory', name: 'inventory', i18n: [], function_list: []}];
|
|
const context = {
|
|
get_function_list: async () => list,
|
|
console_print: {log: value => logs.push(value), success: value => value},
|
|
socket: {connected: true, timeout(ms) {assert.equal(ms, 5000); return this;},
|
|
async emitWithAck(...args) {reports.push(args); return response;}},
|
|
};
|
|
return {context, reports, logs, list, run: () => vm.runInNewContext(`${code}\nupdate_function_list(socket, 1, is_current);`,
|
|
{...context, is_current: () => context.socket.connected && context.current !== false})};
|
|
}
|
|
|
|
test('function list reports grouped metadata and validates success, error and malformed ACKs', async () => {
|
|
const f = fixture(); await f.run();
|
|
assert.equal(f.reports[0][0], 'update_function_list');
|
|
assert.equal(f.reports[0][1].id, 1);
|
|
assert.equal(f.reports[0][1].function_list, f.list);
|
|
assert.equal(f.logs.length, 1);
|
|
for (const response of [undefined, null, {}, {status: 'unknown'}, {status: 'error', data: 403}]) {
|
|
const failed = fixture(response);
|
|
if (response === undefined) failed.context.socket.emitWithAck = async () => undefined;
|
|
await assert.rejects(failed.run(), /函数列表上报失败/);
|
|
assert.equal(failed.logs.length, 0);
|
|
}
|
|
});
|
|
|
|
test('function list never reports a late scan or ACK through a replaced session', async () => {
|
|
const f = fixture(); let finish;
|
|
f.context.get_function_list = () => new Promise(resolve => {finish = resolve;});
|
|
const task = f.run(); f.context.current = false; finish(f.list); await task;
|
|
assert.equal(f.reports.length, 0);
|
|
const late = fixture(); let ack; let started;
|
|
const emitted = new Promise(resolve => {started = resolve;});
|
|
late.context.socket.emitWithAck = () => new Promise(resolve => {ack = resolve; started();});
|
|
const reporting = late.run(); await emitted; late.context.current = false;
|
|
ack({status: 'success'}); await reporting;
|
|
assert.equal(late.logs.length, 0);
|
|
});
|