import pytest from sqlalchemy import create_engine from sqlalchemy.orm import Session from hqt.db.models import Base from hqt.mcp.service import McpService from hqt.projects.service import ProjectService @pytest.fixture def db(): engine = create_engine("sqlite:///:memory:") Base.metadata.create_all(engine) with Session(engine) as session: yield session class TestProjectService: def test_create_and_get(self, db): svc = ProjectService(db) p = svc.create("test", "/tmp/test") assert p.id is not None assert svc.get(p.id).name == "test" def test_list_excludes_archived(self, db): svc = ProjectService(db) svc.create("a", "/a") p2 = svc.create("b", "/b") svc.archive(p2.id) assert len(svc.list_all()) == 1 assert len(svc.list_all(include_archived=True)) == 2 def test_update_name_and_path(self, db): svc = ProjectService(db) p = svc.create("old", "/old/path") updated = svc.update(p.id, "new", "/new/path") assert updated.name == "new" assert updated.path == "/new/path" assert svc.get(p.id).path == "/new/path" def test_update_duplicate_path_raises(self, db): svc = ProjectService(db) svc.create("a", "/a") p2 = svc.create("b", "/b") with pytest.raises(ValueError, match="already uses path"): svc.update(p2.id, "b", "/a") # DB session must remain usable after rollback, values unchanged assert svc.get(p2.id).path == "/b" assert svc.get(p2.id).name == "b" def test_update_unknown_id_raises(self, db): svc = ProjectService(db) with pytest.raises(ValueError, match="not found"): svc.update(9999, "x", "/x") class TestMcpService: def test_crud(self, db): svc = McpService(db) server = svc.create("test-mcp", "stdio", command="node", args=["server.js"]) assert server.id is not None assert svc.get("test-mcp") is not None assert len(svc.list_all()) == 1 svc.delete("test-mcp") assert svc.get("test-mcp") is None def test_bind_unbind(self, db): psvc = ProjectService(db) msvc = McpService(db) project = psvc.create("proj", "/proj") server = msvc.create("s1", "stdio", command="cmd") msvc.bind_to_project(project.id, server.id) assert len(msvc.get_project_mcps(project.id)) == 1 msvc.unbind_from_project(project.id, server.id) assert len(msvc.get_project_mcps(project.id)) == 0