mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-09-14 20:34:19 +08:00
56 lines
2.1 KiB
JavaScript
56 lines
2.1 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const { readFileSync } = require('node:fs');
|
|
const { test } = require('node:test');
|
|
const vm = require('node:vm');
|
|
const ts = require('typescript');
|
|
|
|
test('service status does not cause its parent form to be saved twice', async () => {
|
|
const source = readFileSync(new URL('../utils/base/luci/service.ts', `file://${__filename}`), 'utf8');
|
|
const { outputText } = ts.transpileModule(source, {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, esModuleInterop: true }
|
|
});
|
|
function E(tag, attrs, children) {
|
|
const node = { tag, attrs, children: Array.isArray(children) ? children : [children] };
|
|
for (const child of node.children) {
|
|
if (child && typeof child === 'object') child.parentNode = node;
|
|
}
|
|
return node;
|
|
}
|
|
const sandbox = {
|
|
exports: {}, E, _: value => value,
|
|
window: { setTimeout() {} },
|
|
require(name) {
|
|
if (name === 'rpc') return { declare: () => () => Promise.resolve({}) };
|
|
if (name === 'poll') return { add() {} };
|
|
return {};
|
|
}
|
|
};
|
|
vm.runInNewContext(outputText, sandbox);
|
|
const status = sandbox.exports.ServiceUtils.renderServiceStatus('dns')();
|
|
const root = E('div', { class: 'cbi-map' }, status);
|
|
let saves = 0;
|
|
let deletes = 0;
|
|
let customOptionExists = true;
|
|
root.instance = { async save() {
|
|
saves++;
|
|
deletes++;
|
|
assert.ok(customOptionExists, 'duplicate delete would return UCI not found');
|
|
customOptionExists = false;
|
|
} };
|
|
const maps = [];
|
|
function visit(node) {
|
|
if (!node || typeof node !== 'object') return;
|
|
if ((node.attrs.class || '').split(/\s+/).includes('cbi-map')) maps.push(node);
|
|
node.children.forEach(visit);
|
|
}
|
|
visit(root);
|
|
// LuCI handleSave scans .cbi-map; findClassInstance walks up to the owner.
|
|
await Promise.all(maps.map(node => {
|
|
while (!node.instance) node = node.parentNode;
|
|
return node.instance.save();
|
|
}));
|
|
assert.equal(saves, 1);
|
|
assert.equal(deletes, 1);
|
|
assert.equal(status.children[0].attrs.class, 'cbi-section');
|
|
});
|