Files
2026-07-13 13:12:33 +08:00

131 lines
4.8 KiB
Python

from __future__ import annotations
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
CHAT_JS = ROOT / "src" / "opensquilla" / "gateway" / "static" / "js" / "views" / "chat.js"
def test_web_chat_defaults_are_policy_driven() -> None:
source = CHAT_JS.read_text(encoding="utf-8")
assert "const _RUN_MODE_FALLBACK = 'trusted';" in source
assert "_applyHelloRunModePolicy" in source
assert "_runModePolicyDefault" in source
assert "new Set(['standard', 'trusted']);" in source
assert "Establish sandbox" in source
def _extract_js_function(source: str, name: str) -> str:
start = source.index(f"function {name}(")
brace = source.index("{", start)
depth = 0
for index in range(brace, len(source)):
char = source[index]
if char == "{":
depth += 1
elif char == "}":
depth -= 1
if depth == 0:
return source[start : index + 1]
raise AssertionError(f"could not extract JS function {name}")
def test_web_chat_run_mode_policy_fails_closed_for_missing_or_malformed_policy() -> None:
source = CHAT_JS.read_text(encoding="utf-8")
helper_names = [
"_runModePolicyValue",
"_normalizeRunModePolicyValue",
"_runModeAllowed",
"_firstAllowedRunMode",
"_clampRunMode",
"_readStoredRunModePreference",
"_clearStoredRunModePreference",
"_fullHostAccessDisabledMessage",
"_applyHelloRunModePolicy",
]
helpers = "\n".join(_extract_js_function(source, name) for name in helper_names)
script = f"""
const assert = require('assert');
const _RUN_MODE_FALLBACK = 'trusted';
const _RUN_MODE_PREF_KEY = 'opensquilla.chat.runMode';
let _runModePolicyDefault = _RUN_MODE_FALLBACK;
let _allowedRunModes = new Set(['standard', 'trusted', 'full']);
let _fullHostAccessDisabledReason = null;
let _runMode = _runModePolicyDefault;
let _runModeUserSelected = false;
let _toolbarState = {{ runMode: _runModePolicyDefault }};
const localStorage = {{ getItem() {{ return null; }}, removeItem() {{}}, setItem() {{}} }};
function _updateRunModeControl() {{}}
function _refreshToolbarTriggerGlow() {{}}
{helpers}
_applyHelloRunModePolicy(null);
assert.deepStrictEqual([..._allowedRunModes].sort(), ['standard', 'trusted']);
assert.strictEqual(_runModePolicyDefault, 'trusted');
assert.strictEqual(_runMode, 'trusted');
assert.strictEqual(_fullHostAccessDisabledReason, 'owner_required');
_applyHelloRunModePolicy({{ auth: {{ runModePolicy: {{
allowedRunModes: ['unknown'],
defaultRunMode: 'full',
}} }} }});
assert.deepStrictEqual([..._allowedRunModes].sort(), ['standard', 'trusted']);
assert.strictEqual(_runModePolicyDefault, 'trusted');
assert.strictEqual(_runMode, 'trusted');
assert.strictEqual(_fullHostAccessDisabledReason, 'owner_required');
_applyHelloRunModePolicy({{ auth: {{ runModePolicy: {{
allowedRunModes: ['standard', 'trusted', 'full'],
}} }} }});
assert.deepStrictEqual([..._allowedRunModes].sort(), ['full', 'standard', 'trusted']);
assert.strictEqual(_runModePolicyDefault, 'full');
assert.strictEqual(_runMode, 'full');
assert.strictEqual(_fullHostAccessDisabledReason, null);
_applyHelloRunModePolicy({{ auth: {{ runModePolicy: {{
allowedRunModes: ['standard', 'trusted'],
defaultRunMode: 'full',
fullHostAccessDisabledReason: 'owner_required',
}} }} }});
assert.deepStrictEqual([..._allowedRunModes].sort(), ['standard', 'trusted']);
assert.strictEqual(_runModePolicyDefault, 'trusted');
assert.strictEqual(_runMode, 'trusted');
assert.strictEqual(_fullHostAccessDisabledReason, 'owner_required');
"""
result = subprocess.run(
["node", "-e", script],
cwd=ROOT,
capture_output=True,
text=True,
check=False,
)
assert result.returncode == 0, result.stdout + result.stderr
def test_web_chat_run_mode_switch_uses_setup_gate_for_sandbox_modes() -> None:
source = CHAT_JS.read_text(encoding="utf-8")
assert "_requestSandboxSetupForMode" in source
assert "_ensureSandboxSetupOnly" in source
assert "_sandboxSetupReadyForMode" in source
assert "const pendingPrompt = !!_pendingSandboxSetupMode;" in source
assert "const optionalPrompt = setupKnown && !_sandboxSetupPromptDismissed;" in source
assert "sandbox.setup.status" in source
assert "sandbox.setup.ensure" in source
assert "if (mode === 'full') return true;" in source
assert "if (!(await _requestSandboxSetupForMode(mode))) return;" in source
def test_web_chat_run_mode_is_not_loaded_from_gateway_or_session_context() -> None:
source = CHAT_JS.read_text(encoding="utf-8")
assert "_loadRunModeStatusFallback" not in source
assert "sandbox.status" not in source
assert "_loadRunContext" not in source
assert "_syncRunMode" not in source
assert "sandbox.run_context.get" not in source
assert "sandbox.run_context.set" not in source