75 lines
4.9 KiB
JavaScript
75 lines
4.9 KiB
JavaScript
#!/usr/bin/env node
|
|
// 0.31.7 DOM/source + executable revision-diff tests (no Rust runtime).
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import vm from 'node:vm';
|
|
const read = path => fs.readFileSync(path, 'utf8');
|
|
const html = read('src/admin/web/index.html');
|
|
const css = read('src/admin/web/style.css');
|
|
const settings = read('src/admin/web/settings.js');
|
|
const hist = read('src/admin/web/app/config-history.js');
|
|
const management = read('src/admin/web/management.js');
|
|
const listener = read('src/admin/web/integrations.js');
|
|
const router = read('src/admin/router.rs');
|
|
const core = read('src/admin/web/vhosts/core.js');
|
|
const editor = read('src/admin/web/vhosts/editor.js');
|
|
const rates = read('src/admin/web/vhosts/rates.js');
|
|
const model = read('src/rate_limit.rs');
|
|
const api = JSON.parse(read('src/admin/openapi.json'));
|
|
|
|
assert.match(html, /data-settings-tab="policies"/);
|
|
for (const name of ['user-agent', 'headers', 'response']) {
|
|
assert.match(html, new RegExp(`data-policy-settings-tab="${name}"`));
|
|
assert.match(html, new RegExp(`data-policy-settings-page="${name}"`));
|
|
}
|
|
for (const form of ['global-ua-block-form', 'headers-form', 'response-form']) {
|
|
assert.equal(html.split(`id="${form}"`).length, 2, `${form} must be unique`);
|
|
}
|
|
assert.match(settings, /selectPolicyTab\("user-agent"\)/);
|
|
assert.match(html, /id="config-history-json-dialog"/);
|
|
assert.match(html, /id="config-history-compare-open"/);
|
|
const actionStart = html.indexOf('<div class="config-history-detail-actions">');
|
|
const actionEnd = html.indexOf('</div>', actionStart);
|
|
const restorePos = html.indexOf('id="config-history-restore"', actionStart);
|
|
const comparePos = html.indexOf('id="config-history-compare-open"', actionStart);
|
|
assert.ok(actionStart > -1 && restorePos > actionStart && comparePos > restorePos && comparePos < actionEnd,
|
|
'JSON compare button must appear directly under restore inside the same action group');
|
|
assert.equal(html.split('id="config-history-compare-open"').length, 2);
|
|
assert.match(html, /id="config-json-compare-title"[\s\S]*?<div class="window-tools">[\s\S]*?id="config-history-json-close"/);
|
|
assert.match(css, /dialog\.config-history-dialog,\s*dialog\.config-history-json-dialog\s*\{/);
|
|
assert.match(css, /\.config-history-dialog\[open\]\s*\{[^}]*grid-template-rows:\s*auto minmax\(0, 1fr\)/);
|
|
assert.match(css, /\.config-history-diff\s*\{[^}]*overflow-y:\s*auto/);
|
|
assert.match(css, /\.config-history-layout\s*\{[^}]*overflow:\s*hidden/);
|
|
assert.match(css, /@media \(max-width:\s*860px\)\s*\{[\s\S]*?\.config-history-layout\s*\{[^}]*overflow-y:\s*auto/);
|
|
assert.match(css, /\.config-history-json-columns pre\s*\{[^}]*border:\s*0/);
|
|
assert.match(hist, /"config-history-json-before"\)\.textContent/);
|
|
assert.match(hist, /"config-history-json-after"\)\.textContent/);
|
|
assert.match(css, /\.listener-protocol-settings-actions\s*\{[^}]*gap:\s*14px/);
|
|
assert.match(listener, /listener-protocol-settings-actions/);
|
|
assert.match(management, /el\("details", undefined, "acl-profile-attached"\)/);
|
|
assert.doesNotMatch(management, /attached\.open\s*=\s*true/);
|
|
assert.match(router, /include_str!\("web\/vhosts\/rates\.js"\)/);
|
|
assert.match(editor, /user_agent_limits: uaRatesReader\(\)/);
|
|
assert.match(editor, /userAgentRateEditor\(g, rate\.user_agent_limits \|\| \[\]\)/);
|
|
assert.match(core, /uaRatesReader/);
|
|
assert.match(rates, /function userAgentRateEditor/);
|
|
assert.match(model, /pub user_agent_limits: Vec<UserAgentLimit>/);
|
|
assert.ok(api.components.schemas.VhostRateLimit.properties.user_agent_limits);
|
|
|
|
const start = hist.indexOf('function configDiff('), end = hist.indexOf('function renderConfigRevisionDetail(', start);
|
|
assert.ok(start > 0 && end > start, 'executable diff function must exist');
|
|
const context = { before: null, after: null };
|
|
vm.createContext(context);
|
|
vm.runInContext(`${hist.slice(start, end)}\nglobalThis.diffResult = () => configDiff(before, after);`, context);
|
|
const diff = (before, after) => { context.before=before; context.after=after; return JSON.parse(JSON.stringify(context.diffResult())); };
|
|
let result = diff({port:80, x:{a:true, b:2}, vhosts:[{id:'v1', host:'a'},{id:'v2', host:'b'}]},
|
|
{port:443, x:{a:true, b:3}, vhosts:[{id:'v2', host:'b'},{id:'v1', host:'a'}]});
|
|
assert.deepEqual(result.map(x => x.path), ['$["port"]','$["x"]["b"]']);
|
|
result = diff({a:1, headers:[]}, {a:1, headers:[{id:'one',value:'ok'}], policy:true});
|
|
assert.deepEqual(result.map(x => x.path), ['$["headers"]["one"]["id"]','$["headers"]["one"]["value"]','$["policy"]']);
|
|
result = diff({items: [{id:'one', active: true}]}, {items: [{id:'one',active:false}]});
|
|
assert.equal(result.length,1);
|
|
assert.equal(result[0].path,'$["items"]["one"]["active"]');
|
|
assert.ok(diff({}, Object.fromEntries(Array.from({length:350},(_,i) => [i, i]))).length <= 200);
|
|
console.log('PASS: 0.31.7 Settings sections, vhost UA rate editor/API, ACL/listener layout, changed-field revision diff, bounded scrolling, conventional full JSON modal.');
|