bouquin/tests/test_settings_dialog_cancel_paths.py

111 lines
3.5 KiB
Python

import pytest
from PySide6.QtWidgets import QApplication, QDialog, QWidget
from bouquin.db import DBConfig, DBManager
from bouquin.settings_dialog import SettingsDialog
from bouquin.settings import APP_NAME, APP_ORG
from bouquin.key_prompt import KeyPrompt
from bouquin.theme import Theme, ThemeManager, ThemeConfig
@pytest.fixture(scope="module")
def app():
a = QApplication.instance()
if a is None:
a = QApplication([])
a.setApplicationName(APP_NAME)
a.setOrganizationName(APP_ORG)
return a
@pytest.fixture
def db(tmp_path):
cfg = DBConfig(path=tmp_path / "s.db", key="abc")
m = DBManager(cfg)
assert m.connect()
return m
def test_theme_radio_initialisation_dark_and_light(app, db, monkeypatch, qtbot):
# Dark preselection
parent = _ParentWithThemes(app)
qtbot.addWidget(parent)
dlg = SettingsDialog(db.cfg, db, parent=parent)
qtbot.addWidget(dlg)
dlg.theme_dark.setChecked(True)
dlg._save()
assert dlg.config.theme == Theme.DARK.value
# Light preselection
parent2 = _ParentWithThemes(app)
qtbot.addWidget(parent2)
dlg2 = SettingsDialog(db.cfg, db, parent=parent2)
qtbot.addWidget(dlg2)
dlg2.theme_light.setChecked(True)
dlg2._save()
assert dlg2.config.theme == Theme.LIGHT.value
def test_change_key_cancel_branches(app, db, monkeypatch, qtbot):
parent = _ParentWithThemes(app)
qtbot.addWidget(parent)
dlg = SettingsDialog(db.cfg, db, parent=parent)
qtbot.addWidget(dlg)
# First prompt cancelled -> early return
monkeypatch.setattr(KeyPrompt, "exec", lambda self: QDialog.Rejected)
dlg._change_key() # should just return without altering key
assert dlg.key == ""
# First OK, second cancelled -> early return at the second branch
state = {"calls": 0}
def _exec(self):
state["calls"] += 1
return QDialog.Accepted if state["calls"] == 1 else QDialog.Rejected
monkeypatch.setattr(KeyPrompt, "exec", _exec)
# Also monkeypatch to control key() values
monkeypatch.setattr(KeyPrompt, "key", lambda self: "new-secret")
dlg._change_key()
# Because the second prompt was rejected, key should remain unchanged
assert dlg.key == ""
def test_save_key_checkbox_cancel_restores_checkbox(app, db, monkeypatch, qtbot):
parent = _ParentWithThemes(app)
qtbot.addWidget(parent)
dlg = SettingsDialog(db.cfg, db, parent=parent)
qtbot.addWidget(dlg)
qtbot.addWidget(dlg)
# Simulate user checking the box, but cancelling the prompt -> code unchecks it again
monkeypatch.setattr(KeyPrompt, "exec", lambda self: QDialog.Rejected)
dlg.save_key_btn.setChecked(True)
# The slot toggled should run and revert it to unchecked
assert dlg.save_key_btn.isChecked() is False
def test_change_key_exception_path(app, db, monkeypatch, qtbot):
parent = _ParentWithThemes(app)
qtbot.addWidget(parent)
dlg = SettingsDialog(db.cfg, db, parent=parent)
qtbot.addWidget(dlg)
# Accept both prompts and supply a key
monkeypatch.setattr(KeyPrompt, "exec", lambda self: QDialog.Accepted)
monkeypatch.setattr(KeyPrompt, "key", lambda self: "boom")
# Force DB rekey to raise to exercise the except-branch
monkeypatch.setattr(
db, "rekey", lambda new_key: (_ for _ in ()).throw(RuntimeError("fail"))
)
# Should not raise; error is handled internally
dlg._change_key()
class _ParentWithThemes(QWidget):
def __init__(self, app):
super().__init__()
self.themes = ThemeManager(app, ThemeConfig())