Files
RustProxy/tests/ux_0345.cjs
T
2026-10-21 14:39:51 +02:00

72 lines
4.6 KiB
JavaScript

// Run with: node tests/ux_0345.cjs
// Prevent editor grouping regressions without changing saved input names or IDs.
"use strict";
const fs = require("node:fs");
const path = require("node:path");
const assert = require("node:assert/strict");
const source = file => fs.readFileSync(path.resolve(__dirname, "..", file), "utf8");
const html = source("src/admin/web/index.html");
const streams = source("src/admin/web/streams.js");
const css = source("src/admin/web/style.css");
const php = html.split('data-web-service-page="php" hidden>')[1].split('data-web-service-page="security"')[0];
const delivery = html.split('data-web-service-page="delivery" hidden>')[1].split('data-web-service-page="php"')[0];
function assertGroups(page, groups) {
let prev = -1;
for (const [key, ids] of groups) {
const heading = page.indexOf(`data-i18n="${key}"`);
assert.ok(heading > prev, `section ${key} must exist in order`);
const nextHeading = groups[groups.findIndex(item => item[0] === key) + 1];
const end = nextHeading ? page.indexOf(`data-i18n="${nextHeading[0]}"`) : page.length;
for (const id of ids) {
const pos = page.indexOf(`id="${id}"`);
assert.ok(pos > heading && pos < end, `${id} must belong to ${key}`);
assert.equal(page.split(`id="${id}"`).length - 1, 1, `${id} must occur once`);
}
prev = heading;
}
}
assertGroups(delivery, [
["webServiceStaticDeliverySection", ["web-service-sendfile", "web-service-download-extensions"]],
["webServiceDynamicCompressionSection", ["web-service-compression", "web-service-compression-options", "web-service-compression-zstd", "web-service-compression-br", "web-service-compression-gzip", "web-service-compression-deflate"]],
["webServiceSidecarsSection", ["web-service-precompressed", "web-service-precompressed-br", "web-service-precompressed-gzip"]]
]);
assertGroups(php, [
["webServicePhpSourceSection", ["web-service-php-profile", "web-service-php-profiles", "web-service-php-enabled", "web-service-php-endpoint", "web-service-php-extensions"]],
["webServicePhpRequestSection", ["web-service-php-pass-authorization", "web-service-php-path-info"]],
["webServicePhpLimitsSection", ["web-service-php-connect-timeout", "web-service-php-request-timeout", "web-service-php-concurrency", "web-service-php-body-limit", "web-service-php-header-limit", "web-service-php-stderr-limit"]],
["webServicePhpOverridesSection", ["web-service-php-custom-params", "web-service-php-values", "web-service-php-admin-values", "web-service-php-help"]]
]);
for (const name of ["redirect", "notfound"]) {
const form = html.split(`id="${name}-form"`)[1].split("</form>")[0];
const identity = form.indexOf('data-i18n="hostIdentitySection"');
const cert = form.indexOf(`id="${name}-certificate"`);
const listener = form.indexOf(`id="${name}-listeners"`);
assert.ok(identity >= 0 && cert > identity && listener > cert, `${name}: separate identity and frontend certificate/listeners`);
assert.equal(form.split(`id="${name}-certificate"`).length - 1, 1);
}
for (const needle of [
'backendSection("streamBackendConnectionSection")',
'backendSection("streamBackendHealthSection")',
'healthMode.addEventListener("change", syncProbeFields)',
'probeFields.hidden = inactive;',
'input.disabled = inactive;',
'field(probeFields, "backend-health-timeout"',
'field(connectionFields, "backend-address"',
'get(row, "backend-health-mode").value',
'get(row, "backend-address").value.trim()'
]) assert.ok(streams.includes(needle), `Streams behavior must retain: ${needle}`);
assert.match(css, /\.vh-setting-section\s*\{[^}]*border-radius:\s*var\(--rp-radius-surface/);
assert.match(css, /\.stream-health-probe-fields\[hidden\][\s\S]*?display:\s*none !important/);
for (const locale of ["en_US", "pl_pl"]) {
const pack = JSON.parse(source(`langs/${locale}.json`)).translations;
for (const key of ["webServiceStaticDeliverySection", "webServiceDynamicCompressionSection", "webServiceSidecarsSection", "webServicePhpSourceSection", "webServicePhpRequestSection", "webServicePhpLimitsSection", "webServicePhpOverridesSection", "hostIdentitySection", "streamBackendConnectionSection", "streamBackendHealthSection"]) {
assert.ok(pack[key]?.trim(), `${locale} missing ${key}`);
}
}
const currentVersion = source("Cargo.toml").match(/^version = "([^"]+)"/m)?.[1];
assert.ok(currentVersion, "Cargo.toml must declare a release version");
assert.equal(JSON.parse(source("src/admin/openapi.json")).info.version, currentVersion);
assert.match(source("CHANGELOG.md"), /## 0\.34\.5 — Administration UX improvements/);
console.log("0.34.5 UI layout, inactive probe controls, localization and synchronized API version: PASS");