fix: fail-fast on non-JSON responses, harden scrape, cover CLI branches

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7rEog2rS7uKNMb1CvpVjr
This commit is contained in:
2026-06-28 21:10:49 -05:00
parent 48bfe4492d
commit 0113797879
3 changed files with 72 additions and 6 deletions

View File

@@ -169,3 +169,52 @@ def test_main_returns_1_on_error(monkeypatch, capsys):
rc = web.main(["search", "x"])
assert rc == 1
assert "error:" in capsys.readouterr().err
def test_request_does_not_retry_on_bad_json(monkeypatch):
calls = {"n": 0}
class BadResp:
def read(self):
return b"<html>not json</html>"
def __enter__(self):
return self
def __exit__(self, *exc):
return False
def once(req, timeout=None):
calls["n"] += 1
return BadResp()
monkeypatch.setattr(web.urllib.request, "urlopen", once)
monkeypatch.setattr(web.time, "sleep", lambda *_: None)
with pytest.raises(web.WebToolsError):
web._request("http://x/y", retries=2)
assert calls["n"] == 1 # deterministic failure, not retried
def test_scrape_raises_on_null_data(monkeypatch):
monkeypatch.setattr(web, "_request",
lambda url, **kw: {"success": True, "data": None})
with pytest.raises(web.WebToolsError):
web.scrape("http://a")
def test_main_search_human_format(monkeypatch, capsys):
monkeypatch.setattr(web, "search",
lambda q, max_results=12: [{"title": "T", "url": "http://u",
"snippet": "s" * 200, "engine": "e"}])
rc = web.main(["search", "x"])
assert rc == 0
out = capsys.readouterr().out
assert "T" in out and "http://u" in out
def test_main_scrape_out_prints_status(monkeypatch, capsys, tmp_path):
monkeypatch.setattr(web, "scrape", lambda url: "# X")
out = tmp_path / "p.md"
rc = web.main(["scrape", "http://a", "--out", str(out)])
assert rc == 0
assert f"wrote {out}" in capsys.readouterr().out