This commit is contained in:
+63
-2
@@ -1,4 +1,6 @@
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
import sys
|
||||
|
||||
from click.testing import CliRunner
|
||||
from unittest.mock import patch
|
||||
@@ -31,14 +33,18 @@ def test_project_version_falls_back_to_installed_package_metadata():
|
||||
assert _project_version() == "9.9.9"
|
||||
|
||||
def test_clients_rename_uses_command_level_browser_target():
|
||||
with patch("browser_cli.cli.send_command") as send_command:
|
||||
with patch("browser_cli.cli.REGISTRY_PATH", Path("/nonexistent/browser-cli-registry.json")), patch(
|
||||
"browser_cli.cli.send_command"
|
||||
) as send_command:
|
||||
result = CliRunner().invoke(main, ["clients", "rename", "--browser", "old-id", "work"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
send_command.assert_called_once_with("clients.rename_profile", {"alias": "work"}, profile="old-id")
|
||||
|
||||
def test_clients_rename_uses_global_browser_target_when_set():
|
||||
with patch("browser_cli.cli.send_command") as send_command:
|
||||
with patch("browser_cli.cli.REGISTRY_PATH", Path("/nonexistent/browser-cli-registry.json")), patch(
|
||||
"browser_cli.cli.send_command"
|
||||
) as send_command:
|
||||
result = CliRunner().invoke(main, ["--browser", "old-id", "clients", "rename", "work"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
@@ -72,6 +78,61 @@ def test_install_help_lists_supported_browsers():
|
||||
assert result.exit_code == 0
|
||||
assert "[chrome|chromium|brave|edge|vivaldi]" in result.output
|
||||
|
||||
|
||||
def test_install_windows_registers_native_host(tmp_path, monkeypatch):
|
||||
local_app_data = tmp_path / "LocalAppData"
|
||||
extension_dir = tmp_path / "extension"
|
||||
extension_dir.mkdir()
|
||||
native_host_src = tmp_path / "native_host.py"
|
||||
native_host_src.write_text("print('ok')", encoding="utf-8")
|
||||
writes = []
|
||||
|
||||
class FakeKey:
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc, tb):
|
||||
return False
|
||||
|
||||
fake_winreg = SimpleNamespace(
|
||||
HKEY_CURRENT_USER="HKCU",
|
||||
KEY_WRITE=0x20006,
|
||||
KEY_WOW64_32KEY=0x0200,
|
||||
KEY_WOW64_64KEY=0x0100,
|
||||
REG_SZ=1,
|
||||
)
|
||||
|
||||
def fake_create_key(root, path, reserved, access):
|
||||
return FakeKey(path)
|
||||
|
||||
def fake_set_value(key, name, reserved, reg_type, value):
|
||||
writes.append((key.path, name, value))
|
||||
|
||||
fake_winreg.CreateKeyEx = fake_create_key
|
||||
fake_winreg.SetValueEx = fake_set_value
|
||||
|
||||
monkeypatch.setenv("LOCALAPPDATA", str(local_app_data))
|
||||
|
||||
with patch("browser_cli.cli.is_windows", return_value=True), patch(
|
||||
"browser_cli.cli.Path.home", return_value=tmp_path
|
||||
), patch("browser_cli.cli.click.prompt", return_value="abc123"), patch(
|
||||
"browser_cli.cli.shutil.copy2"
|
||||
) as copy2, patch("browser_cli.cli.Path.write_text") as write_text, patch.dict(
|
||||
sys.modules, {"winreg": fake_winreg}
|
||||
):
|
||||
copy2.side_effect = lambda src, dst: Path(dst).write_text(native_host_src.read_text(encoding="utf-8"), encoding="utf-8")
|
||||
result = CliRunner().invoke(main, ["install", "edge"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert any("Software\\Microsoft\\Edge\\NativeMessagingHosts\\com.browsercli.host" in path for path, _, _ in writes)
|
||||
assert "Registered native host" in result.output
|
||||
assert "Wrote native host manifest" in result.output
|
||||
wrapper_writes = [call.args[0] for call in write_text.call_args_list if call.args]
|
||||
assert any("@echo off" in text for text in wrapper_writes)
|
||||
|
||||
def test_clients_exits_cleanly_when_registry_is_missing():
|
||||
with patch("browser_cli.cli.REGISTRY_PATH", Path("/nonexistent/browser-cli-registry.json")):
|
||||
result = CliRunner().invoke(main, ["clients"])
|
||||
|
||||
@@ -4,6 +4,7 @@ from pathlib import Path
|
||||
import pytest
|
||||
|
||||
from browser_cli.client import BrowserNotConnected, _resolve_socket, active_browser_targets, display_browser_name
|
||||
from browser_cli.platform import endpoint_for_alias
|
||||
|
||||
def test_resolve_socket_raises_when_registry_missing(monkeypatch):
|
||||
monkeypatch.delenv("BROWSER_CLI_PROFILE", raising=False)
|
||||
@@ -46,6 +47,13 @@ def test_display_browser_name_uses_uuid_stem_for_default():
|
||||
)
|
||||
|
||||
|
||||
def test_resolve_socket_uses_platform_endpoint_for_explicit_alias(monkeypatch):
|
||||
monkeypatch.delenv("BROWSER_CLI_PROFILE", raising=False)
|
||||
monkeypatch.setattr("browser_cli.client.REGISTRY_PATH", Path("/nonexistent/browser-cli-registry.json"))
|
||||
|
||||
assert _resolve_socket("work") == endpoint_for_alias("work")
|
||||
|
||||
|
||||
def test_active_browser_targets_filters_stale_entries(monkeypatch, tmp_path):
|
||||
active_socket = tmp_path / "work.sock"
|
||||
active_socket.write_text("")
|
||||
@@ -60,3 +68,16 @@ def test_active_browser_targets_filters_stale_entries(monkeypatch, tmp_path):
|
||||
assert len(targets) == 1
|
||||
assert targets[0].profile == "work"
|
||||
assert targets[0].display_name == "work"
|
||||
|
||||
|
||||
def test_active_browser_targets_keeps_windows_registry_entries(monkeypatch, tmp_path):
|
||||
registry_path = tmp_path / "registry.json"
|
||||
registry_path.write_text(json.dumps({"work": r"\\.\pipe\browser-cli-work"}))
|
||||
|
||||
monkeypatch.setattr("browser_cli.client.REGISTRY_PATH", registry_path)
|
||||
monkeypatch.setattr("browser_cli.client.is_windows", lambda: True)
|
||||
|
||||
targets = active_browser_targets()
|
||||
|
||||
assert len(targets) == 1
|
||||
assert targets[0].socket_path == r"\\.\pipe\browser-cli-work"
|
||||
|
||||
@@ -18,8 +18,9 @@ def test_cleanup_removes_socket_and_registry_entry(monkeypatch, tmp_path):
|
||||
registry_path = tmp_path / "registry.json"
|
||||
registry_path.write_text(json.dumps({alias: str(socket_path), "other": str(tmp_path / "other.sock")}))
|
||||
|
||||
monkeypatch.setattr(native_host, "SOCKET_DIR", tmp_path)
|
||||
monkeypatch.setattr(native_host, "REGISTRY_PATH", registry_path)
|
||||
monkeypatch.setattr(native_host, "_socket_path_for", lambda alias: str(socket_path))
|
||||
monkeypatch.setattr(native_host, "is_windows", lambda: False)
|
||||
|
||||
native_host._cleanup(alias)
|
||||
|
||||
@@ -41,6 +42,18 @@ def test_stdin_reader_cleans_up_on_eof(monkeypatch):
|
||||
assert cleaned == ["work"]
|
||||
|
||||
|
||||
def test_cleanup_windows_skips_socket_unlink(monkeypatch, tmp_path):
|
||||
registry_path = tmp_path / "registry.json"
|
||||
registry_path.write_text(json.dumps({"work": r"\\.\pipe\browser-cli-work"}))
|
||||
|
||||
monkeypatch.setattr(native_host, "REGISTRY_PATH", registry_path)
|
||||
monkeypatch.setattr(native_host, "is_windows", lambda: True)
|
||||
|
||||
native_host._cleanup("work")
|
||||
|
||||
assert json.loads(registry_path.read_text()) == {}
|
||||
|
||||
|
||||
def test_stdin_reader_cleans_up_on_bye(monkeypatch):
|
||||
cleaned = []
|
||||
messages = iter([{"type": "bye"}])
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
from pathlib import Path
|
||||
|
||||
from browser_cli.platform import endpoint_for_alias, install_base_dir, registry_path, runtime_dir
|
||||
|
||||
|
||||
def test_runtime_dir_defaults_to_tmp_on_unix(monkeypatch):
|
||||
monkeypatch.setattr("browser_cli.platform.is_windows", lambda: False)
|
||||
|
||||
assert runtime_dir() == Path("/tmp/.browser_cli")
|
||||
|
||||
|
||||
def test_runtime_dir_uses_localappdata_on_windows(monkeypatch, tmp_path):
|
||||
monkeypatch.setattr("browser_cli.platform.is_windows", lambda: True)
|
||||
monkeypatch.setenv("LOCALAPPDATA", str(tmp_path / "LocalAppData"))
|
||||
|
||||
assert runtime_dir() == tmp_path / "LocalAppData" / "browser-cli"
|
||||
assert registry_path() == tmp_path / "LocalAppData" / "browser-cli" / "registry.json"
|
||||
|
||||
|
||||
def test_endpoint_for_alias_uses_pipe_on_windows(monkeypatch):
|
||||
monkeypatch.setattr("browser_cli.platform.is_windows", lambda: True)
|
||||
|
||||
assert endpoint_for_alias("work/browser") == r"\\.\pipe\browser-cli-work_browser"
|
||||
|
||||
|
||||
def test_install_base_dir_uses_runtime_dir_on_windows(monkeypatch, tmp_path):
|
||||
monkeypatch.setattr("browser_cli.platform.is_windows", lambda: True)
|
||||
monkeypatch.setenv("LOCALAPPDATA", str(tmp_path / "LocalAppData"))
|
||||
|
||||
assert install_base_dir() == tmp_path / "LocalAppData" / "browser-cli"
|
||||
Reference in New Issue
Block a user