"""Unit tests for session content metadata store."""
import pytest
import navi.content_store as content_store
from tests.conftest_factory import FakeConnection, FakePool
class TestEnsureTables:
async def test_creates_session_content_table_and_indexes(self, monkeypatch):
conn = FakeConnection()
async def fake_pool():
return FakePool(conn)
monkeypatch.setattr(content_store, "_get_db_pool", fake_pool)
await content_store.ensure_tables()
executed = "\n".join(call[1] for call in conn.calls if call[0] == "execute")
assert "CREATE TABLE IF NOT EXISTS session_content" in executed
assert "idx_session_content_session" in executed
assert "CREATE UNIQUE INDEX IF NOT EXISTS idx_session_content_file" in executed
assert "ON session_content (session_id, filename)" in executed
async def test_ensure_tables_is_idempotent(self, monkeypatch):
conn = FakeConnection()
async def fake_pool():
return FakePool(conn)
monkeypatch.setattr(content_store, "_get_db_pool", fake_pool)
await content_store.ensure_tables()
await content_store.ensure_tables()
unique_index_calls = [
call for call in conn.calls
if call[0] == "execute" and "idx_session_content_file" in call[1]
]
assert len(unique_index_calls) == 2
assert all("IF NOT EXISTS" in call[1] for call in unique_index_calls)
class TestPublish:
@pytest.fixture(autouse=True)
def _session_dir(self, monkeypatch, tmp_path):
monkeypatch.setattr(content_store.settings, "session_files_dir", str(tmp_path / "sessions"))
monkeypatch.setattr(content_store.settings, "public_url", "http://localhost:8000")
async def test_upserts_by_session_and_filename(self, monkeypatch, tmp_path):
conn = FakeConnection()
conn.enqueue("INSERT 0 1")
async def fake_pool():
return FakePool(conn)
monkeypatch.setattr(content_store, "_get_db_pool", fake_pool)
sess_dir = tmp_path / "sessions" / "sess-1"
sess_dir.mkdir(parents=True)
(sess_dir / "logo.svg").write_text("<svg></svg>")
info = await content_store.publish(
session_id="sess-1",
filename="logo.svg",
title="Logo",
)
assert info["id"] == "sess-1_logo.svg"
assert info["url"] == "http://localhost:8000/sessions/sess-1/files/logo.svg"
call = conn.calls[0]
assert call[0] == "execute"
assert "ON CONFLICT (session_id, filename) DO UPDATE" in call[1]
assert call[2][1:5] == ("sess-1", "logo.svg", "svg", "Logo")
async def test_repeated_publish_uses_same_content_id_and_upsert(self, monkeypatch, tmp_path):
conn = FakeConnection()
conn.enqueue("INSERT 0 1")
conn.enqueue("INSERT 0 1")
async def fake_pool():
return FakePool(conn)
monkeypatch.setattr(content_store, "_get_db_pool", fake_pool)
sess_dir = tmp_path / "sessions" / "sess-1"
sess_dir.mkdir(parents=True)
(sess_dir / "logo.svg").write_text("<svg></svg>")
first = await content_store.publish(session_id="sess-1", filename="logo.svg", title="Logo")
second = await content_store.publish(session_id="sess-1", filename="logo.svg", title="Logo 2")
assert first["id"] == second["id"] == "sess-1_logo.svg"
execute_calls = [call for call in conn.calls if call[0] == "execute"]
assert len(execute_calls) == 2
assert all("ON CONFLICT (session_id, filename) DO UPDATE" in call[1] for call in execute_calls)
async def test_missing_file_raises(self, monkeypatch, tmp_path):
async def fake_pool():
return FakePool(FakeConnection())
monkeypatch.setattr(content_store, "_get_db_pool", fake_pool)
with pytest.raises(FileNotFoundError):
await content_store.publish(session_id="sess-1", filename="missing.svg")