Files
bal-electrum-plugin/tests/test_group_c_settings.py

215 lines
7.5 KiB
Python

"""
Tests for Group C (settings-dialog enhancements).
Covered behaviour:
* C2 - the persisted ``EDITABLE_DATES`` configuration key exists, defaults to
OFF, and can be toggled and read back. This is the flag that makes the
delivery-time / check-alive date fields editable outside the wizard.
* C4b - the "Reset" logic restores each of the six dialog settings to its
factory default. The factory default is taken from ``BalConfig.default``
(the third argument used when the config was created), so the dialog's
Reset button has a single source of truth and never hard-codes values.
The Qt widgets are not imported (they need PyQt6 + an Electrum window). Instead
we reproduce the small, GUI-free decision logic with the same lightweight
``FakeConfig`` used by the Group B tests, which keeps the tests fast and
headless while still verifying the real contract.
Run:
PYTHONPATH=electrum-src python3 -m pytest tests/test_group_c_settings.py -q
"""
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir))
from bal.core.plugin_base import BalConfig
# ------------------------------------------------------------------ #
# Mocks
# ------------------------------------------------------------------ #
class FakeConfig:
"""Minimal mock for Electrum's config object (key/value store)."""
def __init__(self):
self._store = {}
def get(self, key, default=None):
return self._store.get(key, default)
def set_key(self, key, value, save=True):
self._store[key] = value
# ------------------------------------------------------------------ #
# C2 - EDITABLE_DATES config
# ------------------------------------------------------------------ #
def test_editable_dates_defaults_off():
"""C2: the editable-dates flag defaults to OFF (dates display-only)."""
cfg = FakeConfig()
editable = BalConfig(cfg, "bal_editable_dates", False)
assert editable.get() is False
def test_editable_dates_can_be_enabled():
"""C2: turning the flag ON is persisted and read back as True."""
cfg = FakeConfig()
editable = BalConfig(cfg, "bal_editable_dates", False)
editable.set(True)
# Re-read through a fresh accessor to prove it is persisted in the config.
assert BalConfig(cfg, "bal_editable_dates", False).get() is True
# ------------------------------------------------------------------ #
# History persistence settings (SAVE_HISTORY / HISTORY_LABEL)
# ------------------------------------------------------------------ #
def test_save_history_defaults_on():
"""History persistence is opt-out: the flag defaults to ON."""
cfg = FakeConfig()
save_history = BalConfig(cfg, "bal_save_history", True)
assert save_history.get() is True
def test_save_history_can_be_disabled_and_read_back():
cfg = FakeConfig()
save_history = BalConfig(cfg, "bal_save_history", True)
save_history.set(False)
assert BalConfig(cfg, "bal_save_history", True).get() is False
def test_history_label_default_template():
"""The default label contains the {willexecutor} variable."""
cfg = FakeConfig()
history_label = BalConfig(
cfg, "bal_history_label", "BitcoinAfterLife inheritance transaction - {willexecutor}"
)
assert history_label.get() == (
"BitcoinAfterLife inheritance transaction - {willexecutor}"
)
assert "{willexecutor}" in history_label.get()
def test_history_label_can_be_changed_and_read_back():
cfg = FakeConfig()
history_label = BalConfig(
cfg, "bal_history_label", "BitcoinAfterLife inheritance transaction - {willexecutor}"
)
history_label.set("My custom label for {willexecutor}")
assert BalConfig(
cfg, "bal_history_label", "BitcoinAfterLife inheritance transaction - {willexecutor}"
).get() == "My custom label for {willexecutor}"
# ------------------------------------------------------------------ #
# C4b - Reset to defaults
# ------------------------------------------------------------------ #
def _reset_to_defaults(configs):
"""Reproduce the dialog's Reset logic: set each config back to its default.
This mirrors ``on_reset_defaults`` in ``bal.gui.qt.plugin`` (which also
refreshes the Qt widgets). Here we only verify the persistence side: every
config is reset to ``BalConfig.default``.
"""
for cfg in configs:
cfg.set(cfg.default)
def test_reset_restores_all_dialog_settings():
"""C4b: Reset restores every dialog setting to its factory default.
The dialog exposes nine settings: the original six, the Group C
"Editable dates" checkbox, and the Group H "Save inheritance transactions
in history" checkbox + "History label" field, which the Reset button must
also restore.
"""
cfg = FakeConfig()
# The settings exposed by the dialog, with their real defaults.
hide_replaced = BalConfig(cfg, "bal_hide_replaced", True)
hide_invalidated = BalConfig(cfg, "bal_hide_invalidated", True)
auto_sign = BalConfig(cfg, "bal_auto_sign", True)
editable_dates = BalConfig(cfg, "bal_editable_dates", False)
calendar_app = BalConfig(cfg, "bal_open_app", "xdg-open")
event_summary = BalConfig(
cfg, "bal_event_summary", "BAL -Will execution of $wallet_name"
)
event_description = BalConfig(
cfg,
"bal_event_description",
"BAL will execution of $wallet_name\r\n heirs list: \r\n$heirs_complete",
)
save_history = BalConfig(cfg, "bal_save_history", True)
history_label = BalConfig(
cfg, "bal_history_label", "BitcoinAfterLife inheritance transaction - {willexecutor}"
)
settings = [
hide_replaced,
hide_invalidated,
auto_sign,
editable_dates,
calendar_app,
event_summary,
event_description,
save_history,
history_label,
]
# Mutate every setting away from its default.
hide_replaced.set(False)
hide_invalidated.set(False)
auto_sign.set(False)
editable_dates.set(True)
calendar_app.set("/custom/app")
event_summary.set("custom summary")
event_description.set("custom description")
save_history.set(False)
history_label.set("custom label")
# Sanity: the values really changed.
assert hide_replaced.get() is False
assert editable_dates.get() is True
assert calendar_app.get() == "/custom/app"
assert save_history.get() is False
assert history_label.get() == "custom label"
# Reset and verify each one is back to its declared default.
_reset_to_defaults(settings)
for s in settings:
assert s.get() == s.default
# In particular the "Editable dates" flag is back OFF.
assert editable_dates.get() is False
# And the history persistence flag is back ON with the default template.
assert save_history.get() is True
assert history_label.get() == (
"BitcoinAfterLife inheritance transaction - {willexecutor}"
)
def test_reset_does_not_touch_unrelated_settings():
"""C4b: Reset only changes the listed settings, nothing else.
A will / will-executor style key that is NOT part of the dialog list must
keep its value after a reset of the six dialog settings.
"""
cfg = FakeConfig()
unrelated = BalConfig(cfg, "bal_will_settings", {"x": 1})
unrelated.set({"custom": "value"})
dialog_settings = [
BalConfig(cfg, "bal_hide_replaced", True),
BalConfig(cfg, "bal_auto_sign", True),
]
for s in dialog_settings:
s.set(False)
_reset_to_defaults(dialog_settings)
# The unrelated key is untouched by the dialog reset.
assert unrelated.get() == {"custom": "value"}