fix(plugin): missed-update fixes, server re-check, and bold Building Will results (v0.3.2)
Revert the v0.3.1 double-invalidation change (it caused an inheritance-list regression: stale/invalidated wills lingered and heir/date updates became incoherent) and add several targeted missed-update fixes plus a UI refinement. Revert (v0.3.1 -> v0.3.2): - Remove Will.mark_invalidated_by_tx() and its call in loop_broadcast_invalidating. core/will.py and gui/qt/dialogs.py are restored to the working v0.3.0 behaviour. The postpone double-invalidation issue is intentionally left open, to be addressed without touching the shared broadcast path. FIX 1 - detect heir removal on Check / Electrum close: - core/will.py (check_willexecutors_and_heirs): the else-branch now raises HeirNotFoundException when a will still carries an heir that is no longer in the current heirs set (heir removed), mirroring the existing 'heir added' path. Rebuild therefore triggers on Check and on_close (same build_will_task path), as decided by the user (manual update only, no auto-rebuild). FIX 2 - Check queries servers for already-sent wills: - core/will.py: new Will.needs_server_check(w) returns True for any VALID will with a will-executor that is not yet CHECKED (no longer limited to PUSHED). - gui/qt/lists.py (PreviewList.check): use needs_server_check so wills stuck on 'New / Not sent' are re-checked instead of reporting 'nothing to do'. FIX 3 - Settings-dialog hide toggles refresh the list: - core/plugin_base.py: new sync_hide_filters() re-reads the cached _hide_invalidated / _hide_replaced flags from the persisted config. - gui/qt/window.py (update_all): call sync_hide_filters() before refreshing, so toggling 'Hide Invalidated' / 'Hide Replaced' in the Settings dialog (which writes the config directly) updates the transaction list immediately instead of requiring an Electrum restart. UI - bold results in the Building Will dialog: - gui/qt/dialogs.py (BalBuildWillDialog): render the right-side results in bold (Ok, Ko, Nothing to do, Skipped, Wait, Timeout, ...) keeping the left-side state labels in normal weight. Centralised in msg_ok/msg_error/msg_warning/ msg_set_status, plus the will-executor push/check rows now show Ok/Ko and True/False in bold + colour (green/red). Tests/tooling: - tests/test_core_will.py: add test_check_heirs_unchanged_is_coherent, test_check_heir_removed_triggers_rebuild, test_check_heir_added_triggers_rebuild, test_needs_server_check. - tests/sim_update_flows.py: real-world update-scenario simulation. - tests/preview_build_will_dialog.py, tests/preview_we_rows.py: GUI-only before/after previews of the bold formatting. - Bump version to 0.3.2 (VERSION, manifest.json, __init__.py, plugin_base.py). 186 tests pass; smoke test, external-zip test and update-flow simulation OK; ruff reports only pre-existing star-import false positives.
This commit is contained in:
committed by
steal
parent
e477c5aa5b
commit
365824767b
105
tests/preview_we_rows.py
Normal file
105
tests/preview_we_rows.py
Normal file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Visual PREVIEW focused on the WILL-EXECUTOR rows of the Building Will dialog.
|
||||
|
||||
Reproduces faithfully the three real variants built in dialogs.py:
|
||||
|
||||
1. Broadcasting (push) result -> line 774: "{url} : {Ok|Ko}" (plain, no color today)
|
||||
2. Timeout -> line 783: "{url} : <font red>Timeout - no answer</font>"
|
||||
3. Checking already-present -> line 825/834:
|
||||
"checking {url} - {wid} : Waiting"
|
||||
"checked {url} - {wid} : True/False" (plain, no color today)
|
||||
|
||||
Shows BEFORE (current) vs AFTER (proposed: result in bold, keeping label as-is).
|
||||
|
||||
Run:
|
||||
QT_QPA_PLATFORM=offscreen python3 tests/preview_we_rows.py
|
||||
Writes preview_we_before.png / preview_we_after.png in the repo root.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
|
||||
|
||||
from PyQt6.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout
|
||||
from PyQt6.QtCore import Qt
|
||||
|
||||
COLOR_ERROR = "#ff0000"
|
||||
COLOR_OK = "#05ad05"
|
||||
|
||||
URL1 = "https://executor.example.org"
|
||||
URL2 = "https://other-executor.net"
|
||||
WID = "a1b2c3"
|
||||
|
||||
|
||||
def err(e):
|
||||
return "<font color='{}'>{}</font>".format(COLOR_ERROR, e)
|
||||
|
||||
|
||||
# ---------------- BEFORE: exactly as the code builds today -----------------
|
||||
def rows_before():
|
||||
return [
|
||||
# 1. push results (plain text, no color/bold today)
|
||||
"{} : {}".format(URL1, "Ok"),
|
||||
"{} : {}".format(URL2, "Ko"),
|
||||
# 2. timeout (already red, not bold)
|
||||
"{} : {}".format(URL1, err("Timeout - no answer")),
|
||||
# 3. already-present check
|
||||
"checking {} - {} : {}".format(URL1, WID, "Waiting"),
|
||||
"checked {} - {} : {}".format(URL1, WID, "True"),
|
||||
"checked {} - {} : {}".format(URL2, WID, "False"),
|
||||
]
|
||||
|
||||
|
||||
# ---------------- AFTER: result portion in bold, label unchanged -----------
|
||||
def err_after(e):
|
||||
return "<font color='{}'><b>{}</b></font>".format(COLOR_ERROR, e)
|
||||
|
||||
|
||||
def rows_after():
|
||||
return [
|
||||
# 1. push results: color + bold the Ok / Ko outcome
|
||||
"{} : <font color='{}'><b>{}</b></font>".format(URL1, COLOR_OK, "Ok"),
|
||||
"{} : <font color='{}'><b>{}</b></font>".format(URL2, COLOR_ERROR, "Ko"),
|
||||
# 2. timeout: bold the red message
|
||||
"{} : {}".format(URL1, err_after("Timeout - no answer")),
|
||||
# 3. already-present check: bold the result
|
||||
"checking {} - {} : <b>{}</b>".format(URL1, WID, "Waiting"),
|
||||
"checked {} - {} : <font color='{}'><b>{}</b></font>".format(
|
||||
URL1, WID, COLOR_OK, "True"
|
||||
),
|
||||
"checked {} - {} : <font color='{}'><b>{}</b></font>".format(
|
||||
URL2, WID, COLOR_ERROR, "False"
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def render(rows, title, path):
|
||||
full_text = "<br><br>".join(rows).replace("\n", "<br>")
|
||||
w = QWidget()
|
||||
w.setStyleSheet("background:#2b2b2b;")
|
||||
lay = QVBoxLayout(w)
|
||||
t = QLabel(title)
|
||||
t.setStyleSheet("color:#ffffff; font-size:15px; font-weight:bold;")
|
||||
lbl = QLabel(full_text)
|
||||
lbl.setTextFormat(Qt.TextFormat.RichText)
|
||||
lbl.setStyleSheet("color:#dddddd;")
|
||||
f = lbl.font()
|
||||
f.setPointSize(11)
|
||||
lbl.setFont(f)
|
||||
lay.addWidget(t)
|
||||
lay.addWidget(lbl)
|
||||
w.resize(560, 320)
|
||||
w.show()
|
||||
app.processEvents()
|
||||
w.grab().save(path)
|
||||
print(f"saved -> {path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
here = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
render(rows_before(), "Will-Executor rows — BEFORE",
|
||||
os.path.join(here, "preview_we_before.png"))
|
||||
render(rows_after(), "Will-Executor rows — AFTER",
|
||||
os.path.join(here, "preview_we_after.png"))
|
||||
Reference in New Issue
Block a user