This commit is contained in:
Mateusz Gruszczyński committed 2026-10-21 09:38:21 +02:00
1 parent 3776edf4fc
commit 7cfc3a6da1
35 files changed
+1377 -875

No files matched your search

+59
View File
@@ -0,0 +1,59 @@
// Run with: node tests/vhost_ui_layout.cjs
// Regression guard for purely presentational Vhost grouping and corner settings.
"use strict";
const fs = require("node:fs");
const path = require("node:path");
const assert = require("node:assert/strict");
const root = path.resolve(__dirname, "..");
const source = file => fs.readFileSync(path.join(root, file), "utf8");
const core = source("src/admin/web/vhosts/core.js");
const editor = source("src/admin/web/vhosts/editor.js");
const rates = source("src/admin/web/vhosts/rates.js");
const docker = source("src/admin/web/docker.js");
const css = source("src/admin/web/style.css");
const keys = [
"vhGeneralDetailsSection", "vhWebsocketOptionsSection", "vhBalancerAlgorithmSection",
"vhBalancerRetrySection", "vhBalancerKeepaliveSection", "vhTrafficMethodsSection",
"vhTrafficRateSection", "vhTrafficCountrySection", "vhTrafficCountryRatesSection",
"vhSecurityHstsSection", "vhSecurityHeadersSection", "vhUaBlockSection",
"vhLocationIpAclSection", "vhSslSettings",
];
for (const locale of ["en_US", "pl_pl"]) {
const pack = JSON.parse(source(`langs/${locale}.json`));
for (const key of keys) {
assert.ok(pack.translations[key]?.trim(), `${locale}: ${key} must be translated`);
const occurrences = source(`langs/${locale}.json`).split("\n").filter(line => line.trimStart().startsWith(`"${key}":`));
assert.equal(occurrences.length, 1, `${locale}: ${key} must occur exactly once`);
}
}
assert.match(core, /const subsection = \(parent, key\) =>/);
assert.match(core, /"vh-wide vh-setting-section"/);
assert.match(core, /vhSslSettings: "ssl"/);
assert.match(core, /subsection\(accessBody, "vhAclProfile"\)/);
assert.match(core, /subsection\(accessBody, "vhTrafficMethodsSection"\)/);
assert.match(core, /subsection\(accessBody, "vhTrafficCountrySection"\)/);
assert.match(core, /subsection\(accessBody, "vhLocationIpAclSection"\)/);
for (const key of keys.filter(k => k !== "vhLocationIpAclSection" && k !== "vhSslSettings")) {
if (key === "vhTrafficCountryRatesSection" || key === "vhGeneralDetailsSection" || key.startsWith("vhBalancer") || key.startsWith("vhSecurity") || key === "vhUaBlockSection" || key.includes("Traffic") || key === "vhWebsocketOptionsSection") {
assert.ok(editor.includes(`subsection(g, "${key}")`), `missing editor subgroup ${key}`);
}
}
assert.match(editor, /g = group\("vhSsl"\);[\s\S]*?g = group\("vhSslSettings"\)/);
assert.match(editor, /"allow-certificate-mismatch"/);
assert.match(editor, /"tls-policy-custom"/);
assert.match(editor, /"ua-block-enabled"/);
assert.match(editor, /"ua-block-patterns"/);
assert.match(rates, /showHeading = true/);
assert.match(editor, /userAgentRateEditor\(uaRateFields, rate\.user_agent_limits \|\| \[\], false\)/);
assert.match(docker, /backendIpSettings\.append\(labeled\("dockerBackendIp", target\), certificateBar\)/);
assert.match(css, /\.docker-backend-ip-settings\s*\{[^}]*gap:\s*12px;/);
for (const selector of [".vh-setting-section", ".cache-memory-sizing", ".appearance-chart-preview", ".draft-dock"]) {
const escaped = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const block = css.match(new RegExp(escaped + "\\s*\\{([^}]+)\\}"));
assert.ok(block, `missing CSS: ${selector}`);
assert.match(block[1], /border-radius:\s*var\(--rp-radius-surface/, `${selector} must use system corner setting`);
}
assert.match(css, /\.vh-form \.vh-grid>\.vh-check:not\(\.vh-enable-control\)/);
assert.match(css, /\.form-actions \.check/);
assert.match(css, /\.docker-service-certificate-bar>\.check\s*\{[^}]*margin:\s*0\s*!important/);
console.log("Vhost UI grouping, certificate controls, checkbox alignment and corner preset: PASS");