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>
87 lines
3.2 KiB
Python
87 lines
3.2 KiB
Python
from __future__ import annotations
|
|
|
|
import time
|
|
|
|
from PyQt6.QtCore import Qt
|
|
|
|
from boltclam.api_client import ApiClient
|
|
from boltclam.auth import AuthService, CredentialStore
|
|
from boltclam.clamav import ClamAVService
|
|
from boltclam.config import AccountCache, SettingsStore
|
|
from boltclam.context import AppContext
|
|
from boltclam.quarantine import QuarantineService
|
|
from boltclam.storage import Storage
|
|
from boltclam.ui.login_dialog import LoginDialog
|
|
from boltclam.ui.main_window import MainWindow
|
|
|
|
ACCOUNT = {
|
|
"user": {"id": "1", "email": "aaron@example.com", "name": "Aaron",
|
|
"username": "aaron"},
|
|
"subscription": {"tier": "premium", "label": "Premium", "status": "active",
|
|
"current_period_end": "2026-12-01T00:00:00Z"},
|
|
"balance": {"weekly_remaining": 100, "topup": 0, "allowed": True},
|
|
"features": {"licensed": True},
|
|
}
|
|
|
|
|
|
class FakeApi:
|
|
def get_account(self):
|
|
return ACCOUNT
|
|
|
|
def get_updates(self, *args, **kwargs):
|
|
raise RuntimeError("offline")
|
|
|
|
|
|
def _context(tmp_path) -> AppContext:
|
|
store = SettingsStore()
|
|
store.save(store.load())
|
|
settings = store.update(last_update_check=time.time(), logging_enabled=False,
|
|
realtime_enabled=False)
|
|
storage = Storage()
|
|
quarantine = QuarantineService(storage, tmp_path / "quarantine")
|
|
auth = AuthService(
|
|
"http://127.0.0.1:9", install_id=settings.install_id,
|
|
credentials=CredentialStore(tmp_path / "credentials.dat"),
|
|
account_cache=AccountCache(tmp_path / "account.json"))
|
|
return AppContext(
|
|
settings_store=store, settings=settings, storage=storage,
|
|
quarantine=quarantine, clamav=ClamAVService(settings.clamav_path),
|
|
auth=auth, session_key="bolt_live_fake", account=ACCOUNT,
|
|
install_id=settings.install_id, api=FakeApi())
|
|
|
|
|
|
def test_main_window_builds_four_pages_and_switches_tabs(qapp, isolated_env):
|
|
context = _context(isolated_env)
|
|
window = MainWindow(context)
|
|
try:
|
|
window.show()
|
|
qapp.processEvents()
|
|
assert window.stack.count() == 4
|
|
assert [button.text() for button in window.nav_buttons] == [
|
|
"Homepage", "Scan & results", "About & updates", "Settings"]
|
|
assert window.scan_page.tabs.currentIndex() == 0
|
|
window.scan_page.tabs.setCurrentIndex(1)
|
|
assert window.scan_page.tabs.currentIndex() == 1
|
|
window._navigate(3)
|
|
assert window.stack.currentIndex() == 3
|
|
assert window.settings_page.channel_combo.currentData() == "release"
|
|
assert window.about_page.rows["account"].value_label.text() == "Aaron"
|
|
finally:
|
|
window._allow_close = True
|
|
window.close()
|
|
qapp.processEvents()
|
|
|
|
|
|
def test_login_dialog_builds_without_starting_a_worker(qapp, isolated_env):
|
|
auth = AuthService(
|
|
"http://127.0.0.1:9", install_id="test",
|
|
credentials=CredentialStore(isolated_env / "credentials.dat"),
|
|
account_cache=AccountCache(isolated_env / "account.json"))
|
|
dialog = LoginDialog(auth, notice="Test notice")
|
|
try:
|
|
assert "BoltClam" in dialog.windowTitle()
|
|
assert dialog.browser_button.isEnabled()
|
|
assert dialog.session is None
|
|
finally:
|
|
dialog.reject()
|