Files
hqt/tests/test_services.py
T
felixm 90944948f5 Initial commit: hqt — HQ Terminal TUI
TUI for orchestrating AI coding harness sessions (Claude Code, Codex,
Kiro, etc.) via tmux. Click CLI bootstraps a Textual TUI over
ProjectService/SessionService backed by SQLite, spawning harness
sessions as tmux windows through TmuxManager.

Includes recent fixes:
- Visible Tab focus highlight on dialog OK/Cancel buttons
- Auto-select first project on launch
- Auto-select first session + per-project session-selection memory
- tmux new-window targets an explicit free index, fixing
  "index N in use" failures (broken spawn/attach in attached sessions)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 17:06:57 -04:00

76 lines
2.5 KiB
Python

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