Files
BoltClam/tests/test_realtime.py
T
TheMajesticMagicianandClaude Code 47f520fb8f Improve crash diagnostics and isolate watcher-thread failures
Main-thread unhandled exceptions now show the traceback and log path; worker-thread exceptions log without touching Qt widgets. The download watcher catches its own loop failures and reports that it stopped instead of surfacing a blank error dialog. Adds a regression test for the watcher failure path.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-25 17:22:20 -06:00

84 lines
3.0 KiB
Python

from __future__ import annotations
import json
from pathlib import Path
from boltclam import realtime
from boltclam.realtime import browser_download_roots, snapshot
from boltclam.winlock import copy_for_scan
def test_snapshot_finds_final_files_and_skips_partials(tmp_path):
root = tmp_path / "Downloads"
root.mkdir()
(root / "old.exe").write_bytes(b"abc")
(root / "new.crdownload").write_bytes(b"partial")
(root / ".hidden").write_bytes(b"hidden")
sub = root / "Sub"
sub.mkdir()
(sub / "inside.zip").write_bytes(b"zip")
found = snapshot([root])
names = {Path(value[2]).name for value in found.values()}
assert names == {"old.exe", "inside.zip"}
def test_chromium_download_preference_is_watched(tmp_path, monkeypatch):
local = tmp_path / "Local"
roaming = tmp_path / "Roaming"
monkeypatch.setenv("LOCALAPPDATA", str(local))
monkeypatch.setenv("APPDATA", str(roaming))
download = tmp_path / "Custom Downloads"
download.mkdir()
profile = local / "Google" / "Chrome" / "User Data" / "Default"
profile.mkdir(parents=True)
(profile / "Preferences").write_text(json.dumps({
"download": {"default_directory": str(download)}}), encoding="utf-8")
monkeypatch.setattr(realtime.paths, "browser_download_roots", lambda: [])
roots = browser_download_roots()
assert download.resolve() in [path.resolve() for path in roots]
def test_firefox_download_preference_is_watched(tmp_path, monkeypatch):
local = tmp_path / "Local"
roaming = tmp_path / "Roaming"
monkeypatch.setenv("LOCALAPPDATA", str(local))
monkeypatch.setenv("APPDATA", str(roaming))
download = tmp_path / "Firefox Downloads"
download.mkdir()
profile = roaming / "Mozilla" / "Firefox" / "Profiles" / "abc.default"
profile.mkdir(parents=True)
escaped = str(download).replace("\\", "\\\\")
(profile / "prefs.js").write_text(
f'user_pref("browser.download.dir", "{escaped}");\n', encoding="utf-8")
monkeypatch.setattr(realtime.paths, "browser_download_roots", lambda: [])
roots = browser_download_roots()
assert download.resolve() in [path.resolve() for path in roots]
def test_watcher_stops_cleanly_instead_of_raising(monkeypatch, qapp):
messages: list[str] = []
watcher = realtime.DownloadWatcher(interval=0.1)
watcher.watch_status.connect(messages.append)
monkeypatch.setattr(realtime, "browser_download_roots", lambda extra: (_ for _ in ()).throw(
RuntimeError("simulated watcher failure")))
watcher.start()
assert watcher.wait(3000)
qapp.processEvents()
assert not watcher.isRunning()
assert "stopped" in " ".join(messages).lower()
def test_copy_for_scan_preserves_bytes(tmp_path):
source = tmp_path / "download.exe"
source.write_bytes(b"sample bytes")
destination = tmp_path / "copy.bin"
locker, exclusive = copy_for_scan(source, destination, attempts=1, delay=0)
try:
assert destination.read_bytes() == b"sample bytes"
assert isinstance(exclusive, bool)
finally:
locker.close()