From fedd0c352a588b8508c05b5530ff8bfe3bbd6d3a Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Fri, 18 Jul 2025 22:56:20 -0400 Subject: [PATCH] test: cover new gui entry types --- src/tests/test_gui_features.py | 40 +++++++++++++++- src/tests/test_gui_headless.py | 85 ++++++++++++++++++++++++++++++++-- 2 files changed, 118 insertions(+), 7 deletions(-) diff --git a/src/tests/test_gui_features.py b/src/tests/test_gui_features.py index 13769a5..7eb4b6a 100644 --- a/src/tests/test_gui_features.py +++ b/src/tests/test_gui_features.py @@ -8,6 +8,7 @@ pytestmark = pytest.mark.desktop from seedpass.core.pubsub import bus from seedpass_gui.app import MainWindow, RelayManagerDialog +import seedpass_gui.app class DummyNostr: @@ -25,12 +26,24 @@ class DummyNostr: class DummyEntries: - def list_entries(self): - return [] + def __init__(self): + self.data = [(1, "Example", None, None, False)] + self.code = "111111" + + def list_entries(self, sort_by="index", filter_kind=None, include_archived=False): + if filter_kind: + return [(idx, label, None, None, False) for idx, label, *_ in self.data] + return self.data def search_entries(self, q): return [] + def retrieve_entry(self, idx): + return {"period": 30} + + def get_totp_code(self, idx): + return self.code + class DummyController: def __init__(self): @@ -76,3 +89,26 @@ def test_status_bar_updates_and_lock(): bus.publish("vault_locked") assert getattr(ctrl, "locked", False) assert ctrl.main_window is None + + +def test_totp_viewer_refresh_on_sync(monkeypatch): + toga.App("T3", "o3") + ctrl = DummyController() + nostr = DummyNostr() + entries = DummyEntries() + win = MainWindow(ctrl, None, entries, nostr) + ctrl.main_window = win + ctrl.loop = types.SimpleNamespace(create_task=lambda c: None) + + # prevent background loop from running + monkeypatch.setattr( + seedpass_gui.app.TotpViewerWindow, "_update_loop", lambda self: None + ) + + viewer = seedpass_gui.app.TotpViewerWindow(ctrl, entries) + bus.subscribe("sync_finished", viewer.refresh_codes) + + assert viewer.table.data[0][1] == "111111" + entries.code = "222222" + bus.publish("sync_finished") + assert viewer.table.data[0][1] == "222222" diff --git a/src/tests/test_gui_headless.py b/src/tests/test_gui_headless.py index ef5977b..cf371e8 100644 --- a/src/tests/test_gui_headless.py +++ b/src/tests/test_gui_headless.py @@ -2,6 +2,9 @@ import os from types import SimpleNamespace import toga +import pytest + +from seedpass.core.entry_types import EntryType from seedpass_gui.app import LockScreenWindow, MainWindow, EntryDialog @@ -26,11 +29,39 @@ class FakeEntries: return [] def add_entry(self, label, length, username=None, url=None): - self.added.append((label, length, username, url)) + self.added.append(("password", label, length, username, url)) return 1 - def modify_entry(self, entry_id, username=None, url=None, label=None): - self.modified.append((entry_id, username, url, label)) + def add_totp(self, label): + self.added.append(("totp", label)) + return 1 + + def add_ssh_key(self, label): + self.added.append(("ssh", label)) + return 1 + + def add_seed(self, label): + self.added.append(("seed", label)) + return 1 + + def add_pgp_key(self, label): + self.added.append(("pgp", label)) + return 1 + + def add_nostr_key(self, label): + self.added.append(("nostr", label)) + return 1 + + def add_key_value(self, label, value): + self.added.append(("key_value", label, value)) + return 1 + + def add_managed_account(self, label): + self.added.append(("managed_account", label)) + return 1 + + def modify_entry(self, entry_id, username=None, url=None, label=None, value=None): + self.modified.append((entry_id, username, url, label, value)) def setup_module(module): @@ -65,16 +96,60 @@ def test_unlock_creates_main_window(): controller.main_window.cleanup() -def test_entrydialog_add_calls_service(): +@pytest.mark.parametrize( + "kind,expect", + [ + (EntryType.PASSWORD.value, ("password", "L", 12, "u", "x")), + (EntryType.TOTP.value, ("totp", "L")), + (EntryType.SSH.value, ("ssh", "L")), + (EntryType.SEED.value, ("seed", "L")), + (EntryType.PGP.value, ("pgp", "L")), + (EntryType.NOSTR.value, ("nostr", "L")), + (EntryType.KEY_VALUE.value, ("key_value", "L", "val")), + (EntryType.MANAGED_ACCOUNT.value, ("managed_account", "L")), + ], +) +def test_entrydialog_add_calls_service(kind, expect): toga.App("Test2", "org.example2") entries = FakeEntries() main = SimpleNamespace(entries=entries, refresh_entries=lambda: None) dlg = EntryDialog(main, None) dlg.label_input.value = "L" + dlg.kind_input.value = kind dlg.username_input.value = "u" dlg.url_input.value = "x" dlg.length_input.value = 12 + dlg.value_input.value = "val" dlg.save(None) - assert entries.added == [("L", 12, "u", "x")] + assert entries.added[-1] == expect + + +@pytest.mark.parametrize( + "kind,expected", + [ + (EntryType.PASSWORD.value, (1, "newu", "newx", "New", None)), + (EntryType.KEY_VALUE.value, (1, None, None, "New", "val2")), + (EntryType.TOTP.value, (1, None, None, "New", None)), + ], +) +def test_entrydialog_edit_calls_service(kind, expected): + toga.App("Edit", "org.edit") + entries = FakeEntries() + + def retrieve(_id): + return {"kind": kind} + + entries.retrieve_entry = retrieve + + main = SimpleNamespace(entries=entries, refresh_entries=lambda: None) + dlg = EntryDialog(main, 1) + dlg.label_input.value = "New" + dlg.kind_input.value = kind + dlg.username_input.value = "newu" + dlg.url_input.value = "newx" + dlg.value_input.value = "val2" + dlg.save(None) + + assert entries.modified[-1] == expected