Spaces:
Running on Zero
Running on Zero
| 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 | |