ghpsolutions/quadro
Quadro: team boards with roles, history and an MCP endpoint for Claude and ChatGPT
A remix template · 0 remixes · Remix ghpsolutions/quadro
tests/conftest.py
import os
import sys
from datetime import date
from pathlib import Path
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "app"))
from boards.application.use_cases import Boards # noqa: E402
from boards.domain.model import Person # noqa: E402
from boards.infrastructure.memory import MemoryBoards # noqa: E402
TODAY = date(2026, 11, 10)
OWNER, MEMBER, VIEWER, STRANGER = (Person(e) for e in (
"owner@ghp.test", "member@ghp.test", "viewer@ghp.test", "stranger@ghp.test"))
TABLES = ("boards", "memberships", "board_lists", "cards", "comments", "activity",
"card_embeddings")
class FakeAssistant:
def __init__(self, fail=False):
self.fail, self.calls = fail, []
def checklist(self, title, description):
self.calls.append(("checklist", title))
if self.fail:
raise RuntimeError("model down")
return ["Draft it", "Review it", "Send it"]
def summary(self, facts):
self.calls.append(("summary", facts))
if self.fail:
raise RuntimeError("model down")
return "Standup: " + facts.splitlines()[0]
def embed(self, texts):
if self.fail:
raise RuntimeError("model down")
# A tiny bag-of-topics vector: enough to make "similar" mean something in tests.
topics = ("invoice", "certificate", "backup", "release")
return [[1.0 if t in text.lower() else 0.0 for t in topics] + [0.01] for text in texts]
def _sql_repo():
url = os.environ.get("TEST_DATABASE_URL")
if not url:
pytest.skip("set TEST_DATABASE_URL to run the SQL repository against Postgres")
os.environ["DATABASE_URL"] = url
from boards.infrastructure.repository import SqlBoards
repo = SqlBoards(pool_size=4)
for t in TABLES:
repo._run(f"DROP TABLE IF EXISTS {t}")
repo.ensure_schema()
return repo
@pytest.fixture(params=["memory", "sql"])
def repo(request):
return MemoryBoards() if request.param == "memory" else _sql_repo()
@pytest.fixture
def assistant():
return FakeAssistant()
@pytest.fixture
def svc(repo, assistant):
return Boards(repo, assistant, today=lambda: TODAY)
@pytest.fixture
def ops(svc):
"""An 'Ops' board: owner, a member and a viewer."""
board = svc.create_board(OWNER, "Ops")
svc.invite_member(OWNER, board["id"], MEMBER.email, "member")
svc.invite_member(OWNER, board["id"], VIEWER.email, "viewer")
return board["id"]