返回 last30days-skill
test_setup_wizard_pp_sources.py
根目录 / tests / test_setup_wizard_pp_sources.py
1 """Tests for setup-wizard auto-install of the default-on Printing Press sources
2 (arxiv, techmeme, trustpilot) -- lib/setup_wizard.py."""
3
4 from __future__ import annotations
5
6 import pytest
7
8 from lib import setup_wizard as sw
9
10
11 @pytest.fixture
12 def no_off_path(monkeypatch):
13 # Default: no binary present on disk in known dirs.
14 monkeypatch.setattr(sw, "_pp_off_path_binary", lambda bin_name: None)
15
16
17 def test_already_installed_when_on_path(monkeypatch):
18 monkeypatch.setattr(sw.shutil, "which", lambda name: f"/usr/bin/{name}")
19 installed, action, stderr, off = sw._install_pp_cli("arxiv", "arxiv-pp-cli")
20 assert installed is True
21 assert action == "already_installed"
22
23
24 def test_installed_off_path(monkeypatch, no_off_path):
25 monkeypatch.setattr(sw.shutil, "which", lambda name: None)
26 monkeypatch.setattr(sw, "_pp_off_path_binary", lambda bin_name: "/home/u/.local/bin/" + bin_name)
27 installed, action, stderr, off = sw._install_pp_cli("techmeme", "techmeme-pp-cli")
28 assert installed is False
29 assert action == "installed_off_path"
30 assert off.endswith("techmeme-pp-cli")
31
32
33 def test_no_npx(monkeypatch, no_off_path):
34 monkeypatch.setattr(sw.shutil, "which", lambda name: None) # neither bin nor npx
35 installed, action, stderr, off = sw._install_pp_cli("trustpilot", "trustpilot-pp-cli")
36 assert installed is False
37 assert action == "no_npx"
38
39
40 def test_install_success(monkeypatch, no_off_path):
41 # npx present; binary absent before, resolves after the install.
42 calls = {"n": 0}
43
44 def fake_which(name):
45 if name == "npx":
46 return "/usr/bin/npx"
47 if name == "arxiv-pp-cli":
48 # absent on first check, present after install
49 calls["n"] += 1
50 return None if calls["n"] == 1 else "/home/u/.local/bin/arxiv-pp-cli"
51 return None
52
53 monkeypatch.setattr(sw.shutil, "which", fake_which)
54 monkeypatch.setattr(sw.subprocess, "run",
55 lambda *a, **k: type("P", (), {"returncode": 0, "stdout": "", "stderr": ""})())
56 installed, action, stderr, off = sw._install_pp_cli("arxiv", "arxiv-pp-cli")
57 assert installed is True
58 assert action == "installed"
59
60
61 def test_install_uses_resolved_windows_npx_path(monkeypatch, no_off_path):
62 """Regression for #904: subprocess.run must receive the resolved npx
63 path (e.g. a Windows PATHEXT-resolved npx.CMD), not the bare "npx"
64 string -- bare "npx" fails with WinError 2 on Windows."""
65 calls = {"n": 0}
66 windows_npx = r"C:\Program Files\nodejs\npx.CMD"
67
68 def fake_which(name):
69 if name == "npx":
70 return windows_npx
71 if name == "techmeme-pp-cli":
72 calls["n"] += 1
73 return None if calls["n"] == 1 else r"C:\Users\me\.local\bin\techmeme-pp-cli"
74 return None
75
76 run_calls = []
77
78 def fake_run(cmd, **kwargs):
79 run_calls.append(cmd)
80 return type("P", (), {"returncode": 0, "stdout": "", "stderr": ""})()
81
82 monkeypatch.setattr(sw.shutil, "which", fake_which)
83 monkeypatch.setattr(sw.subprocess, "run", fake_run)
84 installed, action, stderr, off = sw._install_pp_cli("techmeme", "techmeme-pp-cli")
85 assert installed is True
86 assert action == "installed"
87 assert run_calls[0][0] == windows_npx
88
89
90 def test_install_failed_nonzero_rc(monkeypatch, no_off_path):
91 def fake_which(name):
92 return "/usr/bin/npx" if name == "npx" else None
93
94 monkeypatch.setattr(sw.shutil, "which", fake_which)
95 monkeypatch.setattr(sw.subprocess, "run",
96 lambda *a, **k: type("P", (), {"returncode": 1, "stdout": "", "stderr": "boom"})())
97 installed, action, stderr, off = sw._install_pp_cli("techmeme", "techmeme-pp-cli")
98 assert installed is False
99 assert action == "install_failed"
100 assert "boom" in stderr
101
102
103 def test_install_default_pp_sources_covers_default_on_pair(monkeypatch):
104 # Only the zero-auth default-on sources are auto-installed. Trustpilot is
105 # opt-in (INCLUDE_SOURCES=trustpilot) and intentionally excluded here.
106 monkeypatch.setattr(sw.shutil, "which", lambda name: f"/usr/bin/{name}")
107 out = sw.install_default_pp_sources()
108 assert set(out.keys()) == {"arxiv", "techmeme"}
109 assert "trustpilot" not in out
110 for entry in out.values():
111 assert entry["action"] == "already_installed"
112 assert entry["installed"] is True
113
114
115 def test_install_is_idempotent(monkeypatch):
116 monkeypatch.setattr(sw.shutil, "which", lambda name: f"/usr/bin/{name}")
117 run_calls = []
118 monkeypatch.setattr(sw.subprocess, "run", lambda *a, **k: run_calls.append(a))
119 sw.install_default_pp_sources()
120 sw.install_default_pp_sources()
121 # All already on PATH -> npx install never invoked.
122 assert run_calls == []
123
123 lines PYTHON