Next-level improvements: 15 items across backend, frontend, and testing
Backend: - SQLiteStateBackend: persistent task/trace storage with SQLite - InMemoryStateBackend: in-memory impl of StateBackend interface - Redis cache backend (CacheBackend ABC + MemoryCacheBackend + RedisCacheBackend) - OpenAI adapter: async acomplete() with retry logic - Per-tenant + per-IP rate limiting in middleware Frontend: - State management: useStore + useAppState (zero-dep, context + reducer) - React Router integration: URL-based navigation (usePageNavigation) - WebSocket streaming: sendPrompt + StreamCallbacks for token-by-token updates - File preview: inline image/text/binary preview with expand/collapse - Sparkline charts + MetricCard + BarChart for dashboard visualization - Push notifications hook (useNotifications) with browser Notification API - i18n system: 6 locales (en, es, fr, de, ja, zh) with interpolation - 6 new Storybook stories (ChatMessage, Skeleton, Markdown, SearchFilter, Toast, FilePreview) Testing: - Playwright E2E config + 6 browser specs (desktop + mobile) - 18 new Python tests (SQLiteStateBackend, InMemoryStateBackend, cache backends) 570 Python tests + 45 frontend tests = 615 total, 0 ruff errors. Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
This commit is contained in:
79
tests/test_sqlite_backend.py
Normal file
79
tests/test_sqlite_backend.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""Tests for SQLiteStateBackend."""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import pytest
|
||||
|
||||
from fusionagi.core.sqlite_backend import SQLiteStateBackend
|
||||
from fusionagi.schemas.task import Task, TaskState
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def db_path():
|
||||
fd, path = tempfile.mkstemp(suffix=".db")
|
||||
os.close(fd)
|
||||
yield path
|
||||
os.unlink(path)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def backend(db_path):
|
||||
return SQLiteStateBackend(db_path=db_path)
|
||||
|
||||
|
||||
def test_set_and_get_task(backend):
|
||||
task = Task(task_id="t1", goal="test goal")
|
||||
backend.set_task(task)
|
||||
loaded = backend.get_task("t1")
|
||||
assert loaded is not None
|
||||
assert loaded.task_id == "t1"
|
||||
assert loaded.goal == "test goal"
|
||||
|
||||
|
||||
def test_get_missing_task(backend):
|
||||
assert backend.get_task("nonexistent") is None
|
||||
|
||||
|
||||
def test_task_state(backend):
|
||||
task = Task(task_id="t2", goal="state test")
|
||||
backend.set_task(task)
|
||||
assert backend.get_task_state("t2") == TaskState.PENDING
|
||||
backend.set_task_state("t2", TaskState.ACTIVE)
|
||||
assert backend.get_task_state("t2") == TaskState.ACTIVE
|
||||
|
||||
|
||||
def test_traces(backend):
|
||||
backend.set_task(Task(task_id="t3", goal="trace test"))
|
||||
backend.append_trace("t3", {"step": 1, "action": "start"})
|
||||
backend.append_trace("t3", {"step": 2, "action": "complete"})
|
||||
traces = backend.get_trace("t3")
|
||||
assert len(traces) == 2
|
||||
assert traces[0]["step"] == 1
|
||||
assert traces[1]["action"] == "complete"
|
||||
|
||||
|
||||
def test_list_tasks(backend):
|
||||
for i in range(5):
|
||||
t = Task(task_id=f"list-{i}", goal=f"goal {i}")
|
||||
if i >= 3:
|
||||
t = t.model_copy(update={"state": TaskState.ACTIVE})
|
||||
backend.set_task(t)
|
||||
all_tasks = backend.list_tasks()
|
||||
assert len(all_tasks) == 5
|
||||
active = backend.list_tasks(state=TaskState.ACTIVE)
|
||||
assert len(active) == 2
|
||||
|
||||
|
||||
def test_delete_task(backend):
|
||||
backend.set_task(Task(task_id="del-1", goal="delete me"))
|
||||
backend.append_trace("del-1", {"action": "trace"})
|
||||
assert backend.delete_task("del-1") is True
|
||||
assert backend.get_task("del-1") is None
|
||||
assert backend.get_trace("del-1") == []
|
||||
|
||||
|
||||
def test_count_tasks(backend):
|
||||
assert backend.count_tasks() == 0
|
||||
backend.set_task(Task(task_id="c1", goal="count"))
|
||||
assert backend.count_tasks() == 1
|
||||
Reference in New Issue
Block a user