mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-11-06 21:02:04 +00:00
feat: wire semantic controls into legacy and tui v2 interfaces
This commit is contained in:
1 parent
165e2db204
commit
ec407c611a
7 files changed
+532
No files matched your search
@@ -358,3 +358,51 @@ def test_nostr_menu_dispatches_fresh_namespace(monkeypatch):
|
||||
with patch("builtins.input", side_effect=lambda *_: next(inputs)):
|
||||
main.handle_nostr_menu(pm)
|
||||
handler.assert_called_once_with(pm)
|
||||
|
||||
|
||||
def test_settings_menu_dispatches_semantic_submenu(monkeypatch):
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
tmp_path = Path(tmpdir)
|
||||
pm, _, _ = setup_pm(tmp_path, monkeypatch)
|
||||
inputs = iter(["18", ""])
|
||||
with patch("main.handle_semantic_index_menu") as handler:
|
||||
with patch("builtins.input", side_effect=lambda *_: next(inputs)):
|
||||
main.handle_settings(pm)
|
||||
handler.assert_called_once_with(pm)
|
||||
|
||||
|
||||
def test_semantic_submenu_search_flow(monkeypatch, capsys):
|
||||
class DummySemanticService:
|
||||
def __init__(self, _pm):
|
||||
self.last_query = None
|
||||
|
||||
def status(self):
|
||||
return {"enabled": False, "built": False, "records": 0}
|
||||
|
||||
def set_enabled(self, enabled: bool):
|
||||
return {"enabled": bool(enabled), "records": 0}
|
||||
|
||||
def build(self):
|
||||
return {"enabled": True, "built": True, "records": 2}
|
||||
|
||||
def rebuild(self):
|
||||
return {"enabled": True, "built": True, "records": 2}
|
||||
|
||||
def search(self, query: str, *, k: int = 10, kind: str | None = None):
|
||||
self.last_query = query
|
||||
return [{"entry_id": 1, "kind": "document", "label": "Doc", "score": 0.5}]
|
||||
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
tmp_path = Path(tmpdir)
|
||||
pm, _, _ = setup_pm(tmp_path, monkeypatch)
|
||||
monkeypatch.setattr(main, "SemanticIndexService", DummySemanticService)
|
||||
monkeypatch.setattr(main, "pause", lambda: None)
|
||||
inputs = iter(["1", "2", "4", "6", "relay docs", ""])
|
||||
with patch("builtins.input", side_effect=lambda *_: next(inputs)):
|
||||
main.handle_semantic_index_menu(pm)
|
||||
out = capsys.readouterr().out
|
||||
assert "Status: enabled=False, built=False, records=0" in out
|
||||
assert "Semantic index enabled" in out
|
||||
assert "Semantic index built with 2 records" in out
|
||||
assert "Semantic Matches:" in out
|
||||
assert "#1 [document] Doc" in out
|
||||
@@ -560,6 +560,12 @@ async def test_tui2_matrix_actions_palette_events_and_guards() -> None:
|
||||
app._run_palette_command("setting-timeout 300")
|
||||
app._run_palette_command("setting-kdf-iterations 100000")
|
||||
app._run_palette_command("setting-kdf-mode pbkdf2")
|
||||
app._run_palette_command("semantic-status")
|
||||
app._run_palette_command("semantic-enable now")
|
||||
app._run_palette_command("semantic-disable now")
|
||||
app._run_palette_command("semantic-build now")
|
||||
app._run_palette_command("semantic-rebuild now")
|
||||
app._run_palette_command("semantic-search")
|
||||
app._run_palette_command("relay-list")
|
||||
app._run_palette_command("npub")
|
||||
app._run_palette_command("relay-add wss://relay.example")
|
||||
@@ -601,6 +607,8 @@ async def test_tui2_matrix_actions_palette_events_and_guards() -> None:
|
||||
app._run_palette_command("lock")
|
||||
app._run_palette_command("unlock hunter2")
|
||||
app._run_palette_command("search Doc")
|
||||
app._run_palette_command("semantic-status")
|
||||
app._run_palette_command("semantic-search notes")
|
||||
app.action_focus_left()
|
||||
app._run_palette_command("profile-tree-next")
|
||||
app._run_palette_command("profile-tree-prev")
|
||||
|
||||
@@ -562,6 +562,49 @@ class FakeVaultService:
|
||||
return _Resp()
|
||||
|
||||
|
||||
class FakeSemanticService:
|
||||
def __init__(self) -> None:
|
||||
self.enabled = False
|
||||
self.built = False
|
||||
self.records = 0
|
||||
self.last_query: str | None = None
|
||||
|
||||
def status(self):
|
||||
return {
|
||||
"enabled": bool(self.enabled),
|
||||
"built": bool(self.built),
|
||||
"records": int(self.records),
|
||||
}
|
||||
|
||||
def set_enabled(self, enabled: bool):
|
||||
self.enabled = bool(enabled)
|
||||
return self.status()
|
||||
|
||||
def build(self):
|
||||
self.built = True
|
||||
self.records = 2
|
||||
return self.status()
|
||||
|
||||
def rebuild(self):
|
||||
self.built = True
|
||||
self.records = 2
|
||||
return self.status()
|
||||
|
||||
def search(self, query: str, *, k: int = 10, kind: str | None = None):
|
||||
self.last_query = str(query)
|
||||
if not query.strip():
|
||||
return []
|
||||
return [
|
||||
{
|
||||
"entry_id": 1,
|
||||
"kind": kind or "document",
|
||||
"label": "Doc",
|
||||
"score": 0.7,
|
||||
"excerpt": f"query={query} k={k}",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def _build_app(
|
||||
service: FakeEntryService,
|
||||
*,
|
||||
@@ -571,6 +614,7 @@ def _build_app(
|
||||
sync_service=None,
|
||||
utility_service=None,
|
||||
vault_service=None,
|
||||
semantic_service=None,
|
||||
):
|
||||
holder: dict[str, object] = {}
|
||||
|
||||
@@ -597,6 +641,9 @@ def _build_app(
|
||||
vault_service_factory=(
|
||||
(lambda: vault_service) if vault_service is not None else None
|
||||
),
|
||||
semantic_service_factory=(
|
||||
(lambda: semantic_service) if semantic_service is not None else None
|
||||
),
|
||||
app_hook=_hook,
|
||||
)
|
||||
assert launched is True
|
||||
@@ -1547,6 +1594,7 @@ async def test_tui2_textual_profiles_and_settings_palette_commands() -> None:
|
||||
sync = FakeSyncService()
|
||||
utility = FakeUtilityService()
|
||||
vault = FakeVaultService()
|
||||
semantic = FakeSemanticService()
|
||||
app = _build_app(
|
||||
service,
|
||||
profile_service=profiles,
|
||||
@@ -1555,6 +1603,7 @@ async def test_tui2_textual_profiles_and_settings_palette_commands() -> None:
|
||||
sync_service=sync,
|
||||
utility_service=utility,
|
||||
vault_service=vault,
|
||||
semantic_service=semantic,
|
||||
)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
@@ -1611,6 +1660,34 @@ async def test_tui2_textual_profiles_and_settings_palette_commands() -> None:
|
||||
assert config.kdf_mode == "argon2"
|
||||
assert "KDF mode set to argon2" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-status")
|
||||
await pilot.pause()
|
||||
assert "Displayed semantic index status" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-enable")
|
||||
await pilot.pause()
|
||||
assert semantic.enabled is True
|
||||
assert "Semantic index enabled" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-build")
|
||||
await pilot.pause()
|
||||
assert semantic.built is True
|
||||
assert "Semantic index built" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-search relay recovery")
|
||||
await pilot.pause()
|
||||
assert semantic.last_query == "relay recovery"
|
||||
assert "Semantic matches: 1 for 'relay recovery'" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-rebuild")
|
||||
await pilot.pause()
|
||||
assert "Semantic index rebuilt" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-disable")
|
||||
await pilot.pause()
|
||||
assert semantic.enabled is False
|
||||
assert "Semantic index disabled" in _status_text(app)
|
||||
|
||||
app._run_palette_command("profile-add")
|
||||
await pilot.pause()
|
||||
assert "Created profile fp-new-1" in _status_text(app)
|
||||
@@ -1763,6 +1840,10 @@ async def test_tui2_textual_profiles_and_settings_palette_validation() -> None:
|
||||
await pilot.pause()
|
||||
assert "Utility service unavailable" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-status")
|
||||
await pilot.pause()
|
||||
assert "Semantic service unavailable" in _status_text(app)
|
||||
|
||||
app._run_palette_command("db-export /tmp/x")
|
||||
await pilot.pause()
|
||||
assert "Vault service unavailable" in _status_text(app)
|
||||
@@ -1831,6 +1912,14 @@ async def test_tui2_textual_profiles_and_settings_palette_validation() -> None:
|
||||
await pilot.pause()
|
||||
assert "Nostr service unavailable" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-enable now")
|
||||
await pilot.pause()
|
||||
assert "Semantic service unavailable" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-search")
|
||||
await pilot.pause()
|
||||
assert "Semantic service unavailable" in _status_text(app)
|
||||
|
||||
app._run_palette_command("npub")
|
||||
await pilot.pause()
|
||||
assert "Nostr service unavailable" in _status_text(app)
|
||||
@@ -1855,6 +1944,7 @@ async def test_tui2_textual_profiles_and_settings_palette_validation() -> None:
|
||||
vault = FakeVaultService()
|
||||
nostr = FakeNostrService(["wss://r1"])
|
||||
sync = FakeSyncService()
|
||||
semantic = FakeSemanticService()
|
||||
app = _build_app(
|
||||
service,
|
||||
profile_service=profiles,
|
||||
@@ -1863,6 +1953,7 @@ async def test_tui2_textual_profiles_and_settings_palette_validation() -> None:
|
||||
vault_service=vault,
|
||||
nostr_service=nostr,
|
||||
sync_service=sync,
|
||||
semantic_service=semantic,
|
||||
)
|
||||
async with app.run_test() as pilot:
|
||||
await pilot.pause()
|
||||
@@ -1879,6 +1970,14 @@ async def test_tui2_textual_profiles_and_settings_palette_validation() -> None:
|
||||
await pilot.pause()
|
||||
assert "Usage: setting-kdf-mode <mode>" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-enable now")
|
||||
await pilot.pause()
|
||||
assert "Usage: semantic-enable" in _status_text(app)
|
||||
|
||||
app._run_palette_command("semantic-search")
|
||||
await pilot.pause()
|
||||
assert "Usage: semantic-search <query>" in _status_text(app)
|
||||
|
||||
app._run_palette_command("checksum-update nope")
|
||||
await pilot.pause()
|
||||
assert "Usage: checksum-update" in _status_text(app)
|
||||
|
||||
Reference in new issue
Block a user