Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/seedsigner/gui/screens/screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,7 @@ class ErrorScreen(WarningScreen):
title: str = _mft("Error")
status_icon_name: str = SeedSignerIconConstants.ERROR
status_color: str = GUIConstants.ERROR_COLOR
status_headline: str = None



Expand Down
4 changes: 4 additions & 0 deletions src/seedsigner/views/seed_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ def run(self):
self.run_screen(
WarningScreen,
title="No Secrets to Load",
status_headline=None,
text="No BIP39 Secrets to Load from Seedkeeper",
show_back_button=False,
)
Expand Down Expand Up @@ -550,6 +551,7 @@ def run(self):
self.run_screen(
WarningScreen,
title="Error",
status_headline=None,
text=str(e),
show_back_button=True,
)
Expand Down Expand Up @@ -1875,6 +1877,7 @@ def run(self):
self.run_screen(
WarningScreen,
title="No Secrets to Load",
status_headline=None,
text="No SLIP39 Shares on SeedKeeper",
show_back_button=False,
)
Expand Down Expand Up @@ -1914,6 +1917,7 @@ def run(self):
self.run_screen(
WarningScreen,
title="Error",
status_headline=None,
text=str(e),
show_back_button=True,
)
Expand Down
1 change: 1 addition & 0 deletions src/seedsigner/views/tools_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ def run(self):
self.run_screen(
WarningScreen,
title=_("microSD card not detected"),
status_headline=None,
text=_("Insert a microSD card to save the discharge log."),
button_data=[ButtonOption(_("Back"))],
)
Expand Down
105 changes: 105 additions & 0 deletions tests/test_status_headlines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import base # noqa: F401 -- ensure hardware mocks
from unittest.mock import Mock

from base import BaseTest
from seedsigner.gui.screens.screen import DireWarningScreen, ErrorScreen, WarningScreen
from seedsigner.hardware.battery_hat import BatteryHat
from seedsigner.views import seed_views, tools_views


class TestStatusHeadlines(BaseTest):
def test_error_screen_default_headline_is_none(self):
assert ErrorScreen.__dataclass_fields__["status_headline"].default is None
assert WarningScreen.__dataclass_fields__["status_headline"].default == "Privacy Leak!"
assert DireWarningScreen.__dataclass_fields__["status_headline"].default == "Classified Info!"

def test_seedkeeper_no_secrets_warning_omits_privacy_headline(self, monkeypatch):
class MockConnector:
def seedkeeper_list_secret_headers(self):
return []

monkeypatch.setattr(
seed_views.seedkeeper_utils,
"init_satochip",
lambda *args, **kwargs: MockConnector(),
)

view = seed_views.SeedKeeperSelectView()
view.run_screen = Mock(return_value=0)

view.run()

assert view.run_screen.call_args.args[0] is WarningScreen
assert view.run_screen.call_args.kwargs["status_headline"] is None

def test_seedkeeper_error_warning_omits_privacy_headline(self, monkeypatch):
class MockConnector:
def seedkeeper_list_secret_headers(self):
raise RuntimeError("Interrupted")

monkeypatch.setattr(
seed_views.seedkeeper_utils,
"init_satochip",
lambda *args, **kwargs: MockConnector(),
)

view = seed_views.SeedKeeperSelectView()
view.run_screen = Mock(return_value=0)

view.run()

assert view.run_screen.call_args.args[0] is WarningScreen
assert view.run_screen.call_args.kwargs["status_headline"] is None

def test_slip39_seedkeeper_no_secrets_warning_omits_privacy_headline(self, monkeypatch):
class MockConnector:
def seedkeeper_list_secret_headers(self):
return []

monkeypatch.setattr(
seed_views.seedkeeper_utils,
"init_satochip",
lambda *args, **kwargs: MockConnector(),
)

view = seed_views.SeedSlip39LoadFromSeedkeeperView()
view.run_screen = Mock(return_value=0)

view.run()

assert view.run_screen.call_args.args[0] is WarningScreen
assert view.run_screen.call_args.kwargs["status_headline"] is None

def test_slip39_seedkeeper_error_warning_omits_privacy_headline(self, monkeypatch):
class MockConnector:
def seedkeeper_list_secret_headers(self):
raise RuntimeError("Interrupted")

monkeypatch.setattr(
seed_views.seedkeeper_utils,
"init_satochip",
lambda *args, **kwargs: MockConnector(),
)

view = seed_views.SeedSlip39LoadFromSeedkeeperView()
view.run_screen = Mock(return_value=0)

view.run()

assert view.run_screen.call_args.args[0] is WarningScreen
assert view.run_screen.call_args.kwargs["status_headline"] is None

def test_battery_calibration_missing_sd_warning_omits_privacy_headline(self, monkeypatch):
battery_hat = Mock()
battery_hat.is_enabled.return_value = True
battery_hat.process_discharge_log.return_value = None
monkeypatch.setattr(BatteryHat, "get_instance", classmethod(lambda cls: battery_hat))
self.mock_microsd.is_inserted = False

view = tools_views.ToolsBatteryCalibrationView()
view.run_screen = Mock(return_value=0)

view.run()

assert view.run_screen.call_args.args[0] is WarningScreen
assert view.run_screen.call_args.kwargs["status_headline"] is None