Adds the PyQt6 Windows client (Homepage, Scan & results, About & updates, Settings), ClamAV scanning and quarantine, browser-download watch with an exclusive scan gate, Bolt loopback/PKCE sign-in with DPAPI key storage, Gitea release feed with checksum verification, opt-in diagnostics, and Windows/portable build tooling. Co-Authored-By: Claude Code <noreply@anthropic.com>
71 lines
2.5 KiB
Python
71 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
from boltclam.config import AccountCache, AppSettings, SettingsStore
|
|
|
|
|
|
def test_defaults_are_normalized_and_install_id_is_generated(isolated_env):
|
|
settings = SettingsStore().load()
|
|
assert settings.update_channel == "release"
|
|
assert settings.scan_scope == "homes"
|
|
assert settings.auto_action == "quarantine"
|
|
assert settings.install_id
|
|
assert len(settings.install_id) == 32
|
|
|
|
|
|
def test_invalid_values_fall_back_to_defaults(isolated_env):
|
|
settings = AppSettings(
|
|
update_channel="nightly",
|
|
scan_scope="somewhere",
|
|
auto_action="explode",
|
|
debug_logging=True,
|
|
logging_enabled=False,
|
|
api_base_url="",
|
|
).normalized()
|
|
assert settings.update_channel == "release"
|
|
assert settings.scan_scope == "homes"
|
|
assert settings.auto_action == "quarantine"
|
|
assert settings.debug_logging is False
|
|
assert settings.api_base_url == "https://api.themajesticnetwork.com"
|
|
assert settings.install_id
|
|
|
|
|
|
def test_round_trip_and_atomic_save(isolated_env):
|
|
store = SettingsStore()
|
|
settings = store.load()
|
|
saved = store.update(update_channel="beta", extra_options="--max-filesize=200M",
|
|
extra_watch_dirs=["~/Downloads/Test", ""])
|
|
reloaded = SettingsStore().load()
|
|
assert reloaded.update_channel == "beta"
|
|
assert reloaded.extra_options == "--max-filesize=200M"
|
|
assert len(reloaded.extra_watch_dirs) == 1
|
|
assert saved.install_id == reloaded.install_id
|
|
assert json.loads(store.path.read_text())["update_channel"] == "beta"
|
|
|
|
|
|
def test_corrupt_settings_are_backed_up_and_defaults_load(isolated_env):
|
|
store = SettingsStore()
|
|
store.path.parent.mkdir(parents=True, exist_ok=True)
|
|
store.path.write_text("{not json", encoding="utf-8")
|
|
loaded = SettingsStore().load()
|
|
assert loaded.update_channel == "release"
|
|
backups = list(store.path.parent.glob("settings.corrupt-*.json"))
|
|
assert len(backups) == 1
|
|
|
|
|
|
def test_public_snapshot_does_not_expose_install_id(isolated_env):
|
|
settings = SettingsStore().load()
|
|
public = settings.public_snapshot()
|
|
assert "install_id" not in public
|
|
assert public["update_channel"] == "release"
|
|
|
|
|
|
def test_account_cache_round_trip_and_clear(isolated_env):
|
|
cache = AccountCache()
|
|
account = {"user": {"email": "a@example.com"}, "subscription": {"tier": "premium"}}
|
|
cache.save(account)
|
|
assert cache.load() == account
|
|
cache.clear()
|
|
assert cache.load() is None
|