from sqlalchemy import create_engine from app.db import Base, create_session_factory from app.models.memory import MemoryEdge, MemoryGraph, MemoryNode from app.services.memory_repository import SqlAlchemyMemoryRepository def make_memory_session(): engine = create_engine("sqlite+pysqlite:///:memory:") Base.metadata.create_all(engine) return engine, create_session_factory(engine) def test_memory_repository_persists_graph_and_searches_structured_nodes(): engine, session_factory = make_memory_session() try: with session_factory() as session: repo = SqlAlchemyMemoryRepository(session, organization_id="org-a", graph_id="graph-a") graph = repo.create_graph(project_id="project-a", ontology={"entity_types": ["Person"]}) assert graph.id == "graph-a" alice = repo.upsert_node( canonical_name="Alice", labels=["Person"], aliases=["A. Example"], attributes={"role": "founder"}, summary="A founder mentioned in the source.", confidence=0.91, ) bob = repo.upsert_node(canonical_name="Bob", labels=["Person"]) edge = repo.upsert_edge( source_node_id=alice.id, target_node_id=bob.id, relation="KNOWS", fact="Alice knows Bob.", confidence=0.8, ) episode = repo.add_episode( source_type="document", source_ref="upload-1", normalized_text="Alice knows Bob.", summary="A relationship statement.", ) session.commit() assert edge.graph_id == graph.id assert episode.graph_id == graph.id results = repo.search("alice") assert [node.canonical_name for node in results.nodes] == ["Alice"] assert results.total_count == 1 assert repo.get_node(alice.id).attributes == {"role": "founder"} finally: engine.dispose() def test_memory_repository_fails_closed_for_wrong_organization_or_graph(): engine, session_factory = make_memory_session() try: with session_factory() as session: owner_repo = SqlAlchemyMemoryRepository(session, organization_id="org-a", graph_id="graph-a") owner_repo.create_graph(project_id="project-a") owner_node = owner_repo.upsert_node(canonical_name="Private Alice", labels=["Person"]) other_repo = SqlAlchemyMemoryRepository(session, organization_id="org-b", graph_id="graph-b") other_repo.create_graph(project_id="project-b") other_node = other_repo.upsert_node(canonical_name="Private Bob", labels=["Person"]) session.commit() wrong_org = SqlAlchemyMemoryRepository(session, organization_id="org-b", graph_id="graph-b") assert wrong_org.get_node(owner_node.id) is None assert wrong_org.search("alice").nodes == [] wrong_graph = SqlAlchemyMemoryRepository(session, organization_id="org-a", graph_id="graph-other") assert wrong_graph.get_node(owner_node.id) is None assert wrong_graph.get_node(other_node.id) is None finally: engine.dispose()