mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-06 06:52:20 +02:00
settings.js is 5,721 lines and the registry/navigation/search/sidebar/
lifecycle primitives already live in static/js/settings/. What was left
behind in the coordinator was the layer above them: what happens when a
panel becomes active, where an admin-managed tab is handed to admin.js,
which elements are admin-only, the Appearance window fade, and the
public open/close. That layer reached module-global `modalEl` and
`initialized` directly, so none of it could be exercised without
booting every panel in the file — and every panel I eventually move out
would have to route back through it.
Three modules, no behavior change:
shell.js panel-activation side effects, the admin handoff,
.admin-only visibility, open()/close(). Takes what it
needs from settings.js as injected callbacks, the same
shape bindSettingsNavigation() already uses, so it
holds no panel state.
peek.js the Appearance window fade and its toggle. It is window
chrome rather than Appearance panel data, and it has to
be cleared when the user leaves that panel.
oauthReturn.js the once-per-load return path from the Google OAuth
redirect. It was an IIFE running at module evaluation
in the middle of a 5,700-line file.
settings.js keeps open/close/syncAdminVisibility as exports, so every
caller (app.js, calendar.js, chatStream.js, gallery.js, admin.js,
modelPicker.js, slashCommands.js, chatRenderer.js, emailLibrary.js) is
untouched. 5,721 -> 5,583 lines; the settings/ modules go 887 -> 1,107.
The real-ESM coordinator smoke now links the three new files and asserts
what moved: admin-only elements hidden for a non-admin and shown for an
admin, an admin-managed tab click handed to admin.js without a second
local activation, and the Peek fade applying on Appearance and clearing
when the user navigates away. The OAuth test follows its handler to the
new file and additionally pins the coordinator wiring, since "uses the
module-local open()" is now a property of the seam rather than of one
source slice.
No new module needs a cache-busting query or an sw.js precache entry:
the existing settings/ submodules have neither, they load transitively
from settings.js's versioned URL, and sw.js serves JS network-first.
admin.js stays where it is. It has no shell to extract — open() and
close() already delegate to settingsModule, and its 4,122 lines are all
panel code. That is a panel split, not this one.
121 lines
3.4 KiB
Python
121 lines
3.4 KiB
Python
"""Behavioral coverage for the modular Settings shell.
|
|
|
|
The leaf harness provides focused assertions around the extracted navigation
|
|
and lifecycle primitives. The coordinator smoke separately loads the real
|
|
settings.js module through Node's native ESM linker together with the real
|
|
Settings shell modules, covering their import/export contract and the public
|
|
open/close wiring.
|
|
"""
|
|
|
|
import json
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
|
|
_REPO = Path(__file__).resolve().parent.parent
|
|
_LEAF_HELPER = _REPO / "tests" / "helpers" / "test_settings_shell.js"
|
|
_COORDINATOR_HELPER = (
|
|
_REPO / "tests" / "helpers" / "test_settings_shell_coordinator.mjs"
|
|
)
|
|
_HAS_NODE = shutil.which("node") is not None
|
|
_STYLE = _REPO / "static" / "style.css"
|
|
|
|
|
|
def test_settings_desktop_width_targets_settings_not_cookbook():
|
|
source = _STYLE.read_text(encoding="utf-8")
|
|
|
|
settings_rule = re.search(
|
|
r"(?ms)^\.settings-modal-content\s*\{[^}]*"
|
|
r"width:\s*min\(1040px,\s*94vw\);[^}]*\}",
|
|
source,
|
|
)
|
|
cookbook_rule = re.search(
|
|
r"(?ms)^\.cookbook-edit-modal\s*\{[^}]*"
|
|
r"width:\s*min\(720px,\s*92vw\);[^}]*\}",
|
|
source,
|
|
)
|
|
cookbook_wrong_width = re.search(
|
|
r"(?ms)^\.cookbook-edit-modal\s*\{[^}]*"
|
|
r"width:\s*min\(1040px,\s*94vw\);[^}]*\}",
|
|
source,
|
|
)
|
|
|
|
assert settings_rule is not None, (
|
|
"The standalone .settings-modal-content rule must carry the "
|
|
"1040px/94vw desktop width"
|
|
)
|
|
assert cookbook_rule is not None, (
|
|
"The standalone .cookbook-edit-modal rule must retain its "
|
|
"720px/92vw width"
|
|
)
|
|
assert cookbook_wrong_width is None, (
|
|
"The Settings desktop width must not leak into Cookbook"
|
|
)
|
|
|
|
|
|
def _run_node(*args: str) -> subprocess.CompletedProcess[str]:
|
|
return subprocess.run(
|
|
["node", *args],
|
|
cwd=str(_REPO),
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=30,
|
|
)
|
|
|
|
|
|
@pytest.mark.skipif(not _HAS_NODE, reason="node binary not on PATH")
|
|
def test_settings_shell_leaf_behavior():
|
|
proc = _run_node(str(_LEAF_HELPER))
|
|
|
|
assert proc.returncode == 0, (
|
|
f"Node execution error:\nSTDERR:\n{proc.stderr}\nSTDOUT:\n{proc.stdout}"
|
|
)
|
|
|
|
results = json.loads(proc.stdout.strip())
|
|
|
|
assert results, "Settings shell leaf harness returned no assertions"
|
|
|
|
for result in results:
|
|
assert result["pass"] is True, (
|
|
f"Failed JS behavioral test: {result['test']}"
|
|
+ (
|
|
f" ({result.get('detail')})"
|
|
if result.get("detail")
|
|
else ""
|
|
)
|
|
)
|
|
|
|
|
|
@pytest.mark.skipif(not _HAS_NODE, reason="node binary not on PATH")
|
|
def test_settings_shell_real_esm_coordinator():
|
|
proc = _run_node(
|
|
"--experimental-vm-modules",
|
|
str(_COORDINATOR_HELPER),
|
|
)
|
|
|
|
assert proc.returncode == 0, (
|
|
"Real Settings coordinator smoke failed:\n"
|
|
f"STDERR:\n{proc.stderr}\n"
|
|
f"STDOUT:\n{proc.stdout}"
|
|
)
|
|
|
|
result = json.loads(proc.stdout.strip())
|
|
|
|
assert result == {
|
|
"realEsmGraph": True,
|
|
"initialization": True,
|
|
"finderBinding": True,
|
|
"sidebarBinding": True,
|
|
"navigationCallback": True,
|
|
"directOpen": True,
|
|
"directClose": True,
|
|
"peekChrome": True,
|
|
"adminVisibility": True,
|
|
"adminTabHandoff": True,
|
|
}
|