Include entry type in search results

This commit is contained in:
thePR0M3TH3AN
2025-08-02 16:26:52 -04:00
parent b4f792ad67
commit dcd095d1af
21 changed files with 106 additions and 63 deletions

View File

@@ -8,13 +8,16 @@ from fastapi.testclient import TestClient
sys.path.append(str(Path(__file__).resolve().parents[1]))
from seedpass import api
from seedpass.core.entry_types import EntryType
@pytest.fixture
def client(monkeypatch):
dummy = SimpleNamespace(
entry_manager=SimpleNamespace(
search_entries=lambda q: [(1, "Site", "user", "url", False)],
search_entries=lambda q: [
(1, "Site", "user", "url", False, EntryType.PASSWORD)
],
retrieve_entry=lambda i: {"label": "Site"},
add_entry=lambda *a, **k: 1,
modify_entry=lambda *a, **k: None,

View File

@@ -9,6 +9,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1]))
from seedpass.core.entry_management import EntryManager
from seedpass.core.backup import BackupManager
from seedpass.core.config_manager import ConfigManager
from seedpass.core.entry_types import EntryType
def setup_entry_mgr(tmp_path: Path) -> EntryManager:
@@ -26,7 +27,9 @@ def test_archive_nonpassword_list_search():
idx = em.search_entries("Example")[0][0]
assert em.list_entries() == [(idx, "Example", None, None, False)]
assert em.search_entries("Example") == [(idx, "Example", None, None, False)]
assert em.search_entries("Example") == [
(idx, "Example", None, None, False, EntryType.TOTP)
]
em.archive_entry(idx)
assert em.retrieve_entry(idx)["archived"] is True
@@ -34,9 +37,13 @@ def test_archive_nonpassword_list_search():
assert em.list_entries(include_archived=True) == [
(idx, "Example", None, None, True)
]
assert em.search_entries("Example") == [(idx, "Example", None, None, True)]
assert em.search_entries("Example") == [
(idx, "Example", None, None, True, EntryType.TOTP)
]
em.restore_entry(idx)
assert em.retrieve_entry(idx)["archived"] is False
assert em.list_entries() == [(idx, "Example", None, None, False)]
assert em.search_entries("Example") == [(idx, "Example", None, None, False)]
assert em.search_entries("Example") == [
(idx, "Example", None, None, False, EntryType.TOTP)
]

View File

@@ -14,6 +14,7 @@ from seedpass.core.entry_management import EntryManager
from seedpass.core.backup import BackupManager
from seedpass.core.config_manager import ConfigManager
from seedpass.core.manager import PasswordManager, EncryptionMode
from seedpass.core.entry_types import EntryType
def setup_entry_mgr(tmp_path: Path) -> EntryManager:
@@ -31,7 +32,7 @@ def test_archive_restore_affects_listing_and_search():
assert em.list_entries() == [(idx, "example.com", "alice", "", False)]
assert em.search_entries("example") == [
(idx, "example.com", "alice", "", False)
(idx, "example.com", "alice", "", False, EntryType.PASSWORD)
]
em.archive_entry(idx)
@@ -40,13 +41,15 @@ def test_archive_restore_affects_listing_and_search():
assert em.list_entries(include_archived=True) == [
(idx, "example.com", "alice", "", True)
]
assert em.search_entries("example") == [(idx, "example.com", "alice", "", True)]
assert em.search_entries("example") == [
(idx, "example.com", "alice", "", True, EntryType.PASSWORD)
]
em.restore_entry(idx)
assert em.retrieve_entry(idx)["archived"] is False
assert em.list_entries() == [(idx, "example.com", "alice", "", False)]
assert em.search_entries("example") == [
(idx, "example.com", "alice", "", False)
(idx, "example.com", "alice", "", False, EntryType.PASSWORD)
]

View File

@@ -5,6 +5,7 @@ from typer.testing import CliRunner
from seedpass import cli
from seedpass.cli import app
from seedpass.core.entry_types import EntryType
runner = CliRunner()
@@ -34,7 +35,7 @@ def test_cli_entry_add_search_sync(monkeypatch):
def search_entries(q, kinds=None):
calls["search"] = (q, kinds)
return [(1, "Label", None, None, False)]
return [(1, "Label", None, None, False, EntryType.PASSWORD)]
def start_background_vault_sync():
calls["sync"] = True

View File

@@ -17,7 +17,9 @@ class DummyPM:
list_entries=lambda sort_by="index", filter_kind=None, include_archived=False: [
(1, "Label", "user", "url", False)
],
search_entries=lambda q, kinds=None: [(1, "GitHub", "user", "", False)],
search_entries=lambda q, kinds=None: [
(1, "GitHub", "user", "", False, EntryType.PASSWORD)
],
retrieve_entry=lambda idx: {"type": EntryType.PASSWORD.value, "length": 8},
get_totp_code=lambda idx, seed: "123456",
add_entry=lambda label, length, username, url, **kwargs: 1,

View File

@@ -27,7 +27,7 @@ def make_pm(search_results, entry=None, totp_code="123456"):
def test_search_command(monkeypatch, capsys):
pm = make_pm([(0, "Example", "user", "", False)])
pm = make_pm([(0, "Example", "user", "", False, EntryType.PASSWORD)])
monkeypatch.setattr(main, "PasswordManager", lambda *a, **k: pm)
monkeypatch.setattr(main, "configure_logging", lambda: None)
monkeypatch.setattr(main, "initialize_app", lambda: None)
@@ -40,7 +40,7 @@ def test_search_command(monkeypatch, capsys):
def test_get_command(monkeypatch, capsys):
entry = {"type": EntryType.PASSWORD.value, "length": 8}
pm = make_pm([(0, "Example", "user", "", False)], entry=entry)
pm = make_pm([(0, "Example", "user", "", False, EntryType.PASSWORD)], entry=entry)
monkeypatch.setattr(main, "PasswordManager", lambda *a, **k: pm)
monkeypatch.setattr(main, "configure_logging", lambda: None)
monkeypatch.setattr(main, "initialize_app", lambda: None)
@@ -53,7 +53,7 @@ def test_get_command(monkeypatch, capsys):
def test_totp_command(monkeypatch, capsys):
entry = {"type": EntryType.TOTP.value, "period": 30, "index": 0}
pm = make_pm([(0, "Example", None, None, False)], entry=entry)
pm = make_pm([(0, "Example", None, None, False, EntryType.TOTP)], entry=entry)
called = {}
monkeypatch.setattr(main, "PasswordManager", lambda *a, **k: pm)
monkeypatch.setattr(main, "configure_logging", lambda: None)
@@ -83,7 +83,10 @@ def test_search_command_no_results(monkeypatch, capsys):
def test_get_command_multiple_matches(monkeypatch, capsys):
matches = [(0, "Example", "user", "", False), (1, "Ex2", "bob", "", False)]
matches = [
(0, "Example", "user", "", False, EntryType.PASSWORD),
(1, "Ex2", "bob", "", False, EntryType.PASSWORD),
]
pm = make_pm(matches)
monkeypatch.setattr(main, "PasswordManager", lambda *a, **k: pm)
monkeypatch.setattr(main, "configure_logging", lambda: None)
@@ -97,7 +100,7 @@ def test_get_command_multiple_matches(monkeypatch, capsys):
def test_get_command_wrong_type(monkeypatch, capsys):
entry = {"type": EntryType.TOTP.value}
pm = make_pm([(0, "Example", "user", "", False)], entry=entry)
pm = make_pm([(0, "Example", None, None, False, EntryType.TOTP)], entry=entry)
monkeypatch.setattr(main, "PasswordManager", lambda *a, **k: pm)
monkeypatch.setattr(main, "configure_logging", lambda: None)
monkeypatch.setattr(main, "initialize_app", lambda: None)
@@ -109,7 +112,10 @@ def test_get_command_wrong_type(monkeypatch, capsys):
def test_totp_command_multiple_matches(monkeypatch, capsys):
matches = [(0, "GH", None, None, False), (1, "Git", None, None, False)]
matches = [
(0, "GH", None, None, False, EntryType.TOTP),
(1, "Git", None, None, False, EntryType.TOTP),
]
pm = make_pm(matches)
monkeypatch.setattr(main, "PasswordManager", lambda *a, **k: pm)
monkeypatch.setattr(main, "configure_logging", lambda: None)
@@ -123,7 +129,7 @@ def test_totp_command_multiple_matches(monkeypatch, capsys):
def test_totp_command_wrong_type(monkeypatch, capsys):
entry = {"type": EntryType.PASSWORD.value, "length": 8}
pm = make_pm([(0, "Example", "user", "", False)], entry=entry)
pm = make_pm([(0, "Example", "user", "", False, EntryType.PASSWORD)], entry=entry)
monkeypatch.setattr(main, "PasswordManager", lambda *a, **k: pm)
monkeypatch.setattr(main, "configure_logging", lambda: None)
monkeypatch.setattr(main, "initialize_app", lambda: None)

View File

@@ -2,6 +2,7 @@ import types
from types import SimpleNamespace
from seedpass.core.api import VaultService, EntryService, SyncService, UnlockRequest
from seedpass.core.entry_types import EntryType
def test_vault_service_unlock():
@@ -27,7 +28,7 @@ def test_entry_service_add_entry_and_search():
def search_entries(q, kinds=None):
called["search"] = (q, kinds)
return [(5, "Example", username, url, False)]
return [(5, "Example", username, url, False, EntryType.PASSWORD)]
def start_background_vault_sync():
called["sync"] = True
@@ -47,7 +48,7 @@ def test_entry_service_add_entry_and_search():
assert called.get("sync") is True
results = service.search_entries("ex", kinds=["password"])
assert results == [(5, "Example", username, url, False)]
assert results == [(5, "Example", username, url, False, EntryType.PASSWORD)]
assert called["search"] == ("ex", ["password"])

View File

@@ -46,6 +46,6 @@ def test_search_entries_prompt_for_details(monkeypatch, capsys):
pm.handle_search_entries()
out = capsys.readouterr().out
assert "0. Example" in out
assert "0. Totp - Example" in out
assert "Label: Example" in out
assert "Period: 30s" in out

View File

@@ -28,7 +28,7 @@ def test_search_by_website():
entry_mgr.add_entry("Other.com", 8, "bob")
result = entry_mgr.search_entries("example")
assert result == [(idx0, "Example.com", "alice", "", False)]
assert result == [(idx0, "Example.com", "alice", "", False, EntryType.PASSWORD)]
def test_search_by_username():
@@ -40,7 +40,7 @@ def test_search_by_username():
idx1 = entry_mgr.add_entry("Test.com", 8, "Bob")
result = entry_mgr.search_entries("bob")
assert result == [(idx1, "Test.com", "Bob", "", False)]
assert result == [(idx1, "Test.com", "Bob", "", False, EntryType.PASSWORD)]
def test_search_by_url():
@@ -52,7 +52,9 @@ def test_search_by_url():
entry_mgr.add_entry("Other", 8)
result = entry_mgr.search_entries("login")
assert result == [(idx, "Example", "", "https://ex.com/login", False)]
assert result == [
(idx, "Example", "", "https://ex.com/login", False, EntryType.PASSWORD)
]
def test_search_by_notes_and_totp():
@@ -117,7 +119,7 @@ def test_search_by_tag_password():
idx = entry_mgr.add_entry("TaggedSite", 8, tags=["work"])
result = entry_mgr.search_entries("work")
assert result == [(idx, "TaggedSite", "", "", False)]
assert result == [(idx, "TaggedSite", "", "", False, EntryType.PASSWORD)]
def test_search_by_tag_totp():
@@ -129,7 +131,7 @@ def test_search_by_tag_totp():
idx = entry_mgr.search_entries("OTPAccount")[0][0]
result = entry_mgr.search_entries("mfa")
assert result == [(idx, "OTPAccount", None, None, False)]
assert result == [(idx, "OTPAccount", None, None, False, EntryType.TOTP)]
def test_search_with_kind_filter():
@@ -147,4 +149,4 @@ def test_search_with_kind_filter():
assert {r[0] for r in all_results} == {idx_pw, idx_totp}
only_pw = entry_mgr.search_entries("", kinds=[EntryType.PASSWORD.value])
assert only_pw == [(idx_pw, "Site", "", "", False)]
assert only_pw == [(idx_pw, "Site", "", "", False, EntryType.PASSWORD)]

View File

@@ -9,6 +9,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1]))
from seedpass.core.entry_management import EntryManager
from seedpass.core.backup import BackupManager
from seedpass.core.config_manager import ConfigManager
from seedpass.core.entry_types import EntryType
def setup_entry_manager(tmp_path: Path) -> EntryManager:
@@ -29,7 +30,7 @@ def test_tags_persist_on_new_entry():
entry_mgr = setup_entry_manager(tmp_path)
result = entry_mgr.search_entries("work")
assert result == [(idx, "Site", "", "", False)]
assert result == [(idx, "Site", "", "", False, EntryType.PASSWORD)]
def test_tags_persist_after_modify():
@@ -41,9 +42,11 @@ def test_tags_persist_after_modify():
entry_mgr.modify_entry(idx, tags=["personal"])
# Ensure tag searchable before reload
assert entry_mgr.search_entries("personal") == [(idx, "Site", "", "", False)]
assert entry_mgr.search_entries("personal") == [
(idx, "Site", "", "", False, EntryType.PASSWORD)
]
# Reinitialize to simulate application restart
entry_mgr = setup_entry_manager(tmp_path)
result = entry_mgr.search_entries("personal")
assert result == [(idx, "Site", "", "", False)]
assert result == [(idx, "Site", "", "", False, EntryType.PASSWORD)]

View File

@@ -34,19 +34,21 @@ def test_entry_list(monkeypatch):
def test_entry_search(monkeypatch):
pm = SimpleNamespace(
entry_manager=SimpleNamespace(
search_entries=lambda q, kinds=None: [(1, "L", None, None, False)]
search_entries=lambda q, kinds=None: [
(1, "L", None, None, False, EntryType.PASSWORD)
]
),
select_fingerprint=lambda fp: None,
)
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
result = runner.invoke(app, ["entry", "search", "l"])
assert result.exit_code == 0
assert "1: L" in result.stdout
assert "Password - L" in result.stdout
def test_entry_get_password(monkeypatch):
def search(q, kinds=None):
return [(2, "Example", "", "", False)]
return [(2, "Example", "", "", False, EntryType.PASSWORD)]
entry = {"type": EntryType.PASSWORD.value, "length": 8}
pm = SimpleNamespace(