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

62 lines
2.6 KiB
Python

"""Install receipt: round-trip, robustness, and detection fallback."""
from __future__ import annotations
from pathlib import Path
from opensquilla.uninstall import inventory
from opensquilla.uninstall.inventory import METHOD_PIP, METHOD_UNKNOWN, METHOD_UV_TOOL
from opensquilla.uninstall.receipt import build_receipt, read_receipt, write_receipt
def test_receipt_round_trip(tmp_path: Path) -> None:
payload = build_receipt(
install_method="uv-tool",
installed_at="2026-06-29T00:00:00Z",
entrypoints=["/x/bin/opensquilla"],
owned_paths=["/x/tools/opensquilla"],
data_root=str(tmp_path),
)
write_receipt(payload, home=tmp_path)
loaded = read_receipt(tmp_path)
assert loaded == payload
def test_read_receipt_missing_or_malformed(tmp_path: Path) -> None:
assert read_receipt(tmp_path) is None # absent
(tmp_path / "install-receipt.json").write_text("{not json", encoding="utf-8")
assert read_receipt(tmp_path) is None # malformed -> conservative mode
(tmp_path / "install-receipt.json").write_text("[]", encoding="utf-8")
assert read_receipt(tmp_path) is None # wrong shape
def test_detect_uses_receipt_hint_only_when_unknown(monkeypatch) -> None:
for var in (
"OPENSQUILLA_INSTALL_METHOD",
"OPENSQUILLA_DESKTOP",
"OPENSQUILLA_RUNNING_IN_CONTAINER",
):
monkeypatch.delenv(var, raising=False)
monkeypatch.setattr(inventory, "_docker_image_install", lambda: False)
monkeypatch.setattr(inventory, "_portable_venv_dir", lambda: None)
monkeypatch.setattr(inventory, "_is_editable_install", lambda: False)
monkeypatch.setattr(inventory, "_venv_ancestry", lambda: None)
# No distribution → would be unknown; the receipt hint fills in.
monkeypatch.setattr(inventory, "_has_distribution", lambda: False)
assert inventory.detect_install_method(receipt_hint="uv-tool") == METHOD_UV_TOOL
assert inventory.detect_install_method(receipt_hint="bogus") == METHOD_UNKNOWN
# A concrete runtime signal is never overridden by the hint.
monkeypatch.setattr(inventory, "_has_distribution", lambda: True)
assert inventory.detect_install_method(receipt_hint="uv-tool") == METHOD_PIP
def test_read_receipt_tolerates_utf8_bom(tmp_path: Path) -> None:
# Windows PowerShell 5.1 `Set-Content -Encoding utf8` writes a BOM.
payload = '{"version": 1, "install_method": "uv-tool"}'
(tmp_path / "install-receipt.json").write_bytes(b"\xef\xbb\xbf" + payload.encode("utf-8"))
loaded = read_receipt(tmp_path)
assert loaded is not None
assert loaded["install_method"] == "uv-tool"