Files
wehub-resource-sync f3d80b4628
Auto Release / auto-release (push) Failing after 1s
CI / lint (push) Failing after 0s
CI / screenshot-quality (push) Failing after 3s
CI / pr-policy (push) Has been skipped
CI / test (3.11) (push) Failing after 0s
CI / test (3.12) (push) Failing after 0s
CI / test (3.13) (push) Failing after 3s
CI / coverage (push) Failing after 1s
Legibility / legibility (push) Failing after 3s
chore: import upstream snapshot with attribution
2026-07-13 12:31:48 +08:00

304 lines
10 KiB
Python

from __future__ import annotations
import subprocess
from argparse import Namespace
from pathlib import Path
import pytest
from claude_tap import parse_args
from claude_tap.certs import (
build_macos_trust_ca_command,
build_macos_verify_ca_command,
is_macos_ca_trusted,
trust_macos_ca,
)
from claude_tap.cli import _ensure_ca_trust_for_forward_proxy, _trust_ca_for_current_user, async_main, trust_ca_main
from claude_tap.trace_store import get_trace_store, reset_trace_store
def test_parse_args_accepts_tap_trust_ca() -> None:
args = parse_args(["--tap-client", "agy", "--tap-trust-ca"])
assert args.client == "agy"
assert args.proxy_mode == "forward"
assert args.trust_ca is True
def test_parse_args_agy_does_not_require_tap_trust_ca() -> None:
args = parse_args(["--tap-client", "agy"])
assert args.client == "agy"
assert args.proxy_mode == "forward"
assert args.trust_ca is False
def test_parse_args_rejects_tap_trust_ca_with_reverse_proxy() -> None:
with pytest.raises(SystemExit):
parse_args(["--tap-client", "agy", "--tap-proxy-mode", "reverse", "--tap-trust-ca"])
def test_macos_trust_ca_command_uses_user_keychain_without_sudo() -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
keychain_path = Path("/Users/test/Library/Keychains/login.keychain-db")
cmd = build_macos_trust_ca_command(ca_path, keychain_path)
assert cmd == [
"security",
"add-trusted-cert",
"-r",
"trustRoot",
"-p",
"ssl",
"-k",
str(keychain_path),
str(ca_path),
]
assert "sudo" not in cmd
def test_macos_verify_ca_command_is_non_mutating() -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
keychain_path = Path("/Users/test/Library/Keychains/login.keychain-db")
cmd = build_macos_verify_ca_command(ca_path, keychain_path)
assert cmd[0] == "security"
assert "verify-cert" in cmd
assert "add-trusted-cert" not in cmd
assert str(keychain_path) in cmd
def test_is_macos_ca_trusted_reads_security_verify_result(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
calls: list[list[str]] = []
def fake_run(cmd, **kwargs):
calls.append(cmd)
assert kwargs == {"capture_output": True, "text": True, "check": False}
return subprocess.CompletedProcess(cmd, 0, "", "")
monkeypatch.setattr("claude_tap.certs.subprocess.run", fake_run)
assert is_macos_ca_trusted(ca_path) is True
assert calls[0][1] == "verify-cert"
def test_is_macos_ca_trusted_returns_false_on_verify_failure(monkeypatch: pytest.MonkeyPatch) -> None:
def fake_run(cmd, **kwargs):
return subprocess.CompletedProcess(cmd, 1, "", "not trusted")
monkeypatch.setattr("claude_tap.certs.subprocess.run", fake_run)
assert is_macos_ca_trusted(Path("/tmp/claude-tap-ca.pem")) is False
def test_trust_macos_ca_runs_add_trusted_cert(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
calls: list[list[str]] = []
def fake_run(cmd, **kwargs):
calls.append(cmd)
assert kwargs == {"capture_output": True, "text": True, "check": False}
return subprocess.CompletedProcess(cmd, 0, "ok", "")
monkeypatch.setattr("claude_tap.certs.subprocess.run", fake_run)
result = trust_macos_ca(ca_path)
assert result.returncode == 0
assert calls[0][1] == "add-trusted-cert"
assert calls[0][-1] == str(ca_path)
def test_trust_ca_for_current_user_rejects_non_macos(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr("claude_tap.cli.sys.platform", "linux")
code = _trust_ca_for_current_user(Path("/tmp/claude-tap-ca.pem"))
assert code == 1
def test_trust_ca_for_current_user_skips_when_already_trusted(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
monkeypatch.setattr("claude_tap.cli.sys.platform", "darwin")
monkeypatch.setattr("claude_tap.cli.is_macos_ca_trusted", lambda _: True)
monkeypatch.setattr(
"claude_tap.cli.trust_macos_ca",
lambda _: (_ for _ in ()).throw(AssertionError("trust command should not run")),
)
assert _trust_ca_for_current_user(ca_path) == 0
def test_trust_ca_for_current_user_reports_install_failure(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
monkeypatch.setattr("claude_tap.cli.sys.platform", "darwin")
monkeypatch.setattr("claude_tap.cli.is_macos_ca_trusted", lambda _: False)
monkeypatch.setattr(
"claude_tap.cli.trust_macos_ca",
lambda _: subprocess.CompletedProcess(["security"], 2, "", "keychain locked"),
)
assert _trust_ca_for_current_user(ca_path) == 2
def test_trust_ca_for_current_user_reports_verify_failure_after_install(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
trusted_checks = iter([False, False])
monkeypatch.setattr("claude_tap.cli.sys.platform", "darwin")
monkeypatch.setattr("claude_tap.cli.is_macos_ca_trusted", lambda _: next(trusted_checks))
monkeypatch.setattr(
"claude_tap.cli.trust_macos_ca",
lambda _: subprocess.CompletedProcess(["security"], 0, "", ""),
)
assert _trust_ca_for_current_user(ca_path) == 1
def test_trust_ca_for_current_user_installs_and_rechecks(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
trusted_checks = iter([False, True])
installed: list[Path] = []
def fake_is_trusted(path: Path) -> bool:
assert path == ca_path
return next(trusted_checks)
def fake_trust(path: Path) -> subprocess.CompletedProcess[str]:
installed.append(path)
return subprocess.CompletedProcess(["security"], 0, "", "")
monkeypatch.setattr("claude_tap.cli.sys.platform", "darwin")
monkeypatch.setattr("claude_tap.cli.is_macos_ca_trusted", fake_is_trusted)
monkeypatch.setattr("claude_tap.cli.trust_macos_ca", fake_trust)
code = _trust_ca_for_current_user(ca_path)
assert code == 0
assert installed == [ca_path]
def test_trust_ca_main_uses_generated_ca(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
ca_path = tmp_path / "ca.pem"
key_path = tmp_path / "ca-key.pem"
trusted: list[Path] = []
monkeypatch.setattr("claude_tap.cli.ensure_ca", lambda: (ca_path, key_path))
monkeypatch.setattr("claude_tap.cli._trust_ca_for_current_user", lambda path: trusted.append(path) or 0)
assert trust_ca_main([]) == 0
assert trusted == [ca_path]
def test_auto_ca_trust_skips_non_agy_clients(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
args = parse_args(["--tap-client", "gemini"])
monkeypatch.setattr("claude_tap.cli.sys.platform", "darwin")
monkeypatch.setattr(
"claude_tap.cli.is_macos_ca_trusted",
lambda _: (_ for _ in ()).throw(AssertionError("non-agy clients should not auto-check CA trust")),
)
assert _ensure_ca_trust_for_forward_proxy(args, ca_path) == 0
def test_auto_ca_trust_skips_when_agy_ca_is_already_trusted(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
args = parse_args(["--tap-client", "agy"])
monkeypatch.setattr("claude_tap.cli.sys.platform", "darwin")
monkeypatch.setattr("claude_tap.cli.is_macos_ca_trusted", lambda _: True)
monkeypatch.setattr(
"claude_tap.cli._trust_ca_for_current_user",
lambda _: (_ for _ in ()).throw(AssertionError("already-trusted CA should not reinstall")),
)
assert _ensure_ca_trust_for_forward_proxy(args, ca_path) == 0
def test_auto_ca_trust_installs_for_agy_on_macos(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
args = parse_args(["--tap-client", "agy"])
trusted: list[Path] = []
monkeypatch.setattr("claude_tap.cli.sys.platform", "darwin")
monkeypatch.setattr("claude_tap.cli.is_macos_ca_trusted", lambda _: False)
monkeypatch.setattr("claude_tap.cli._trust_ca_for_current_user", lambda path: trusted.append(path) or 0)
assert _ensure_ca_trust_for_forward_proxy(args, ca_path) == 0
assert trusted == [ca_path]
def test_auto_ca_trust_skips_agy_on_non_macos(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
args = parse_args(["--tap-client", "agy"])
monkeypatch.setattr("claude_tap.cli.sys.platform", "linux")
monkeypatch.setattr(
"claude_tap.cli.is_macos_ca_trusted",
lambda _: (_ for _ in ()).throw(AssertionError("non-macOS should not auto-check CA trust")),
)
assert _ensure_ca_trust_for_forward_proxy(args, ca_path) == 0
def test_explicit_ca_trust_still_runs_for_other_forward_clients(monkeypatch: pytest.MonkeyPatch) -> None:
ca_path = Path("/tmp/claude-tap-ca.pem")
args = parse_args(["--tap-client", "gemini", "--tap-trust-ca"])
trusted: list[Path] = []
monkeypatch.setattr("claude_tap.cli._trust_ca_for_current_user", lambda path: trusted.append(path) or 0)
assert _ensure_ca_trust_for_forward_proxy(args, ca_path) == 0
assert trusted == [ca_path]
@pytest.mark.asyncio
async def test_async_main_returns_before_starting_proxy_when_trust_ca_fails(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
) -> None:
ca_path = tmp_path / "ca.pem"
key_path = tmp_path / "ca-key.pem"
proxy_started = False
monkeypatch.setenv("CLOUDTAP_DB", str(tmp_path / "trust-failed.sqlite3"))
reset_trace_store()
def fail_if_proxy_starts(*args, **kwargs):
nonlocal proxy_started
proxy_started = True
raise AssertionError("proxy should not start when CA trust fails")
monkeypatch.setattr("claude_tap.cli.ensure_ca", lambda: (ca_path, key_path))
monkeypatch.setattr("claude_tap.cli._ensure_ca_trust_for_forward_proxy", lambda _args, _path: 7)
monkeypatch.setattr("claude_tap.cli.ForwardProxyServer", fail_if_proxy_starts)
code = await async_main(
Namespace(
output_dir=str(tmp_path / "traces"),
live_viewer=False,
live_port=0,
host="127.0.0.1",
proxy_mode="forward",
trust_ca=True,
port=0,
client="agy",
target="https://antigravity.goog",
extra_allowed_paths=[],
no_launch=True,
claude_args=[],
max_traces=0,
open_viewer=False,
)
)
assert code == 7
assert proxy_started is False
assert get_trace_store().list_session_rows() == []