test_q3_desktop_unit.py
python
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
9 hours ago
| 1 | """Unit tests for Track Q / Q3 Tauri desktop packaging.""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | import json |
| 6 | from pathlib import Path |
| 7 | |
| 8 | import pytest |
| 9 | |
| 10 | from tests.support import KIT_ROOT |
| 11 | from tools.desktop.banner import StartupBanner, parse_startup_banner_line, parse_startup_stderr |
| 12 | from tools.desktop.constants import ( |
| 13 | CANONICAL_LAUNCHER, |
| 14 | CANONICAL_SUBCOMMAND, |
| 15 | DEFAULT_BIND, |
| 16 | DEFAULT_PORT, |
| 17 | DESKTOP_IDENTIFIER, |
| 18 | DESKTOP_PRODUCT_NAME, |
| 19 | LISTENING_BANNER, |
| 20 | ) |
| 21 | from tools.desktop.init_script import build_auth_bootstrap_script |
| 22 | from tools.desktop.launcher import build_launch_argv, resolve_kit_root, resolve_repo_root |
| 23 | from tools.desktop.manifest import DesktopManifest, validate_desktop_manifest |
| 24 | |
| 25 | |
| 26 | def test_canonical_launcher_constants() -> None: |
| 27 | assert CANONICAL_LAUNCHER == "ok" |
| 28 | assert CANONICAL_SUBCOMMAND == "app" |
| 29 | assert DEFAULT_PORT == 8765 |
| 30 | assert DEFAULT_BIND == "127.0.0.1" |
| 31 | assert DESKTOP_PRODUCT_NAME == "Overseer Kit" |
| 32 | assert DESKTOP_IDENTIFIER == "com.overseer.kit.desktop" |
| 33 | |
| 34 | |
| 35 | def test_build_launch_argv_uses_ok_app(tmp_path: Path) -> None: |
| 36 | argv = build_launch_argv(kit_root_path=KIT_ROOT, repo_root=tmp_path, port=9999) |
| 37 | assert argv[0].endswith("/cli/ok") |
| 38 | assert argv[1:6] == ["app", "--repo", str(tmp_path.resolve()), "--port", "9999"] |
| 39 | assert argv[-2:] == ["--bind", "127.0.0.1"] |
| 40 | |
| 41 | |
| 42 | def test_resolve_kit_root_prefers_explicit() -> None: |
| 43 | assert resolve_kit_root(KIT_ROOT) == KIT_ROOT.resolve() |
| 44 | |
| 45 | |
| 46 | def test_resolve_repo_root_prefers_explicit(tmp_path: Path) -> None: |
| 47 | assert resolve_repo_root(kit=KIT_ROOT, explicit=tmp_path) == tmp_path.resolve() |
| 48 | |
| 49 | |
| 50 | @pytest.mark.parametrize( |
| 51 | ("line", "field", "value"), |
| 52 | [ |
| 53 | (LISTENING_BANNER, "listening", LISTENING_BANNER), |
| 54 | ("url: http://127.0.0.1:8765/", "url", "http://127.0.0.1:8765/"), |
| 55 | ("session_credential: abc123", "session_credential", "abc123"), |
| 56 | ("csrf_token: def456", "csrf_token", "def456"), |
| 57 | ], |
| 58 | ) |
| 59 | def test_parse_startup_banner_line(line: str, field: str, value: str) -> None: |
| 60 | parsed = parse_startup_banner_line(line) |
| 61 | assert parsed == (field, value) |
| 62 | |
| 63 | |
| 64 | def test_parse_startup_stderr_complete() -> None: |
| 65 | lines = [ |
| 66 | "ok app listening\n", |
| 67 | "url: http://127.0.0.1:8765/\n", |
| 68 | "session_credential: sess\n", |
| 69 | "csrf_token: csrf\n", |
| 70 | ] |
| 71 | banner = parse_startup_stderr(lines) |
| 72 | assert banner == StartupBanner( |
| 73 | url="http://127.0.0.1:8765/", |
| 74 | session_credential="sess", |
| 75 | csrf_token="csrf", |
| 76 | ) |
| 77 | |
| 78 | |
| 79 | def test_parse_startup_stderr_incomplete() -> None: |
| 80 | assert parse_startup_stderr(["ok app listening\n"]) is None |
| 81 | |
| 82 | |
| 83 | def test_init_script_uses_json_encoded_secrets() -> None: |
| 84 | script = build_auth_bootstrap_script(session_credential='a"b', csrf_token="c'd") |
| 85 | assert json.dumps('a"b') in script |
| 86 | assert json.dumps("c'd") in script |
| 87 | assert "localStorage" not in script |
| 88 | |
| 89 | |
| 90 | def test_desktop_manifest_validates(tmp_path: Path) -> None: |
| 91 | manifest = DesktopManifest.from_kit_root(KIT_ROOT) |
| 92 | errors = validate_desktop_manifest(manifest) |
| 93 | assert errors == [] |
| 94 | |
| 95 | |
| 96 | def test_before_build_command_resolves_from_desktop_cwd() -> None: |
| 97 | """Tauri runs beforeBuildCommand with cwd=desktop/; path must not escape the kit.""" |
| 98 | conf = json.loads( |
| 99 | (KIT_ROOT / "desktop" / "src-tauri" / "tauri.conf.json").read_text(encoding="utf-8") |
| 100 | ) |
| 101 | cmd = conf["build"]["beforeBuildCommand"] |
| 102 | assert "cd ../.." not in cmd |
| 103 | # Resolve like a shell would from desktop/ |
| 104 | desktop = KIT_ROOT / "desktop" |
| 105 | script = (desktop / Path(cmd)).resolve() if not cmd.startswith("cd ") else None |
| 106 | if script is None: |
| 107 | # Allow `cd .. && ./scripts/...` form |
| 108 | assert "scripts/bundle-desktop-kit.sh" in cmd |
| 109 | script = (KIT_ROOT / "scripts" / "bundle-desktop-kit.sh").resolve() |
| 110 | assert script.is_file(), f"beforeBuildCommand does not resolve to an existing script: {cmd}" |
| 111 | assert script == (KIT_ROOT / "scripts" / "bundle-desktop-kit.sh").resolve() |
File History
1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
9 hours ago