unstuck / tests /test_store.py
art87able's picture
feat: similar-task recall via Nebius embeddings (keyless; recall degrades off without NEBIUS_API_KEY)
79e91df verified
Raw
History Blame Contribute Delete
4.48 kB
from __future__ import annotations
import json
from unstuck.schema import Step
from unstuck.store import Store
def test_store_roundtrips_task_steps_and_actual_records() -> None:
store = Store(":memory:")
task_id = store.add_task("write review", now=123.0)
assert task_id > 0
store.add_steps(
task_id,
[
Step(text="Open doc", category="admin", est_minutes=5),
Step(text="Draft notes", category="creative", est_minutes=15),
],
)
step_id = store.first_step_id(task_id)
store.record_actual(step_id, "admin", 5, 8, now=456.0)
assert store.get_records() == [
{"category": "admin", "est_minutes": 5, "actual_minutes": 8}
]
def test_export_json_includes_all_tables() -> None:
store = Store(":memory:")
task_id = store.add_task("clear inbox", now=123.0)
store.add_steps(
task_id,
[Step(text="Archive old messages", category="admin", est_minutes=10)],
)
step_id = store.first_step_id(task_id)
store.record_actual(step_id, "admin", 10, 12, now=456.0)
payload = json.loads(store.export_json())
assert len(payload["tasks"]) == 1
assert len(payload["steps"]) == 1
assert len(payload["records"]) == 1
assert payload["steps"][0]["category"] == "admin"
def test_import_json_restores_records_into_fresh_store() -> None:
source = Store(":memory:")
task_id = source.add_task("clear inbox", now=123.0)
source.add_steps(
task_id,
[Step(text="Archive old messages", category="admin", est_minutes=10)],
)
step_id = source.first_step_id(task_id)
source.record_actual(step_id, "admin", 10, 12, now=456.0)
restored = Store(":memory:")
result = restored.import_json(source.export_json())
assert result == {"imported": 1, "skipped": 0}
assert restored.get_records() == source.get_records()
def test_import_json_skips_duplicate_records() -> None:
source = Store(":memory:")
task_id = source.add_task("clear inbox", now=123.0)
source.add_steps(
task_id,
[Step(text="Archive old messages", category="admin", est_minutes=10)],
)
step_id = source.first_step_id(task_id)
source.record_actual(step_id, "admin", 10, 12, now=456.0)
payload = source.export_json()
restored = Store(":memory:")
assert restored.import_json(payload) == {"imported": 1, "skipped": 0}
assert restored.import_json(payload) == {"imported": 0, "skipped": 1}
assert restored.get_records() == source.get_records()
def test_import_json_malformed_json_raises_value_error() -> None:
store = Store(":memory:")
try:
store.import_json("{")
except ValueError as exc:
assert str(exc)
else:
raise AssertionError("expected ValueError")
def test_import_json_bad_record_rows_raise_value_error() -> None:
store = Store(":memory:")
payload = json.dumps(
{
"tasks": [],
"steps": [],
"records": [
{
"step_id": 1,
"category": "admin",
"est_minutes": 0,
"actual_minutes": 12,
"completed_at": 456.0,
}
],
}
)
try:
store.import_json(payload)
except ValueError as exc:
assert str(exc)
else:
raise AssertionError("expected ValueError")
def test_plan_snapshot_save_then_load_roundtrips_opaque_rows_json() -> None:
store = Store(":memory:")
rows_json = '[{"step_id": 1, "text": "Open doc"}]'
store.save_plan("Write review", rows_json)
assert store.load_plan() == ("Write review", rows_json)
def test_plan_snapshot_second_save_overwrites_single_row() -> None:
store = Store(":memory:")
store.save_plan("First task", '[{"step_id": 1}]')
store.save_plan("Second task", '[{"step_id": 2}]')
assert store.load_plan() == ("Second task", '[{"step_id": 2}]')
def test_plan_snapshot_fresh_store_returns_none() -> None:
store = Store(":memory:")
assert store.load_plan() is None
def test_plan_snapshot_clear_removes_saved_snapshot() -> None:
store = Store(":memory:")
store.save_plan("Write review", '[{"step_id": 1}]')
store.clear_plan()
assert store.load_plan() is None
def test_plan_snapshot_clear_on_fresh_store_does_not_raise() -> None:
store = Store(":memory:")
store.clear_plan()
assert store.load_plan() is None