- Add Project model with slug, description, autonomy level, and settings - Add AgentType model for agent templates with model config and failover - Add AgentInstance model for running agents with status and memory - Add Issue model with external tracker sync (Gitea/GitHub/GitLab) - Add Sprint model with velocity tracking and lifecycle management - Add comprehensive Pydantic schemas with validation - Add full CRUD operations for all models with filtering/sorting - Add 280+ tests for models, schemas, and CRUD operations Implements #23, #24, #25, #26, #27 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
219 lines
7.0 KiB
Python
219 lines
7.0 KiB
Python
# tests/crud/syndarix/conftest.py
|
|
"""
|
|
Shared fixtures for Syndarix CRUD tests.
|
|
"""
|
|
|
|
import uuid
|
|
from datetime import date, timedelta
|
|
from decimal import Decimal
|
|
|
|
import pytest
|
|
import pytest_asyncio
|
|
|
|
from app.models.syndarix import (
|
|
AgentInstance,
|
|
AgentStatus,
|
|
AgentType,
|
|
AutonomyLevel,
|
|
Issue,
|
|
IssuePriority,
|
|
IssueStatus,
|
|
Project,
|
|
ProjectStatus,
|
|
Sprint,
|
|
SprintStatus,
|
|
SyncStatus,
|
|
)
|
|
from app.models.user import User
|
|
from app.schemas.syndarix import (
|
|
AgentInstanceCreate,
|
|
AgentTypeCreate,
|
|
IssueCreate,
|
|
ProjectCreate,
|
|
SprintCreate,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def project_create_data():
|
|
"""Return data for creating a project via schema."""
|
|
return ProjectCreate(
|
|
name="Test Project",
|
|
slug="test-project-crud",
|
|
description="A test project for CRUD testing",
|
|
autonomy_level=AutonomyLevel.MILESTONE,
|
|
status=ProjectStatus.ACTIVE,
|
|
settings={"mcp_servers": ["gitea"]},
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def agent_type_create_data():
|
|
"""Return data for creating an agent type via schema."""
|
|
return AgentTypeCreate(
|
|
name="Backend Engineer",
|
|
slug="backend-engineer-crud",
|
|
description="Specialized in backend development",
|
|
expertise=["python", "fastapi", "postgresql"],
|
|
personality_prompt="You are an expert backend engineer with deep knowledge of Python and FastAPI.",
|
|
primary_model="claude-opus-4-5-20251101",
|
|
fallback_models=["claude-sonnet-4-20250514"],
|
|
model_params={"temperature": 0.7, "max_tokens": 4096},
|
|
mcp_servers=["gitea", "file-system"],
|
|
tool_permissions={"allowed": ["*"], "denied": []},
|
|
is_active=True,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sprint_create_data():
|
|
"""Return data for creating a sprint via schema."""
|
|
today = date.today()
|
|
return {
|
|
"name": "Sprint 1",
|
|
"number": 1,
|
|
"goal": "Complete initial setup and core features",
|
|
"start_date": today,
|
|
"end_date": today + timedelta(days=14),
|
|
"status": SprintStatus.PLANNED,
|
|
"planned_points": 21,
|
|
"completed_points": 0,
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def issue_create_data():
|
|
"""Return data for creating an issue via schema."""
|
|
return {
|
|
"title": "Implement user authentication",
|
|
"body": "As a user, I want to log in securely so that I can access my account.",
|
|
"status": IssueStatus.OPEN,
|
|
"priority": IssuePriority.HIGH,
|
|
"labels": ["backend", "security"],
|
|
"story_points": 5,
|
|
}
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def test_owner_crud(async_test_db):
|
|
"""Create a test user to be used as project owner in CRUD tests."""
|
|
from app.core.auth import get_password_hash
|
|
|
|
_test_engine, AsyncTestingSessionLocal = async_test_db
|
|
async with AsyncTestingSessionLocal() as session:
|
|
user = User(
|
|
id=uuid.uuid4(),
|
|
email="crud-owner@example.com",
|
|
password_hash=get_password_hash("TestPassword123!"),
|
|
first_name="CRUD",
|
|
last_name="Owner",
|
|
is_active=True,
|
|
is_superuser=False,
|
|
)
|
|
session.add(user)
|
|
await session.commit()
|
|
await session.refresh(user)
|
|
return user
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def test_project_crud(async_test_db, test_owner_crud, project_create_data):
|
|
"""Create a test project in the database for CRUD tests."""
|
|
_test_engine, AsyncTestingSessionLocal = async_test_db
|
|
async with AsyncTestingSessionLocal() as session:
|
|
project = Project(
|
|
id=uuid.uuid4(),
|
|
name=project_create_data.name,
|
|
slug=project_create_data.slug,
|
|
description=project_create_data.description,
|
|
autonomy_level=project_create_data.autonomy_level,
|
|
status=project_create_data.status,
|
|
settings=project_create_data.settings,
|
|
owner_id=test_owner_crud.id,
|
|
)
|
|
session.add(project)
|
|
await session.commit()
|
|
await session.refresh(project)
|
|
return project
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def test_agent_type_crud(async_test_db, agent_type_create_data):
|
|
"""Create a test agent type in the database for CRUD tests."""
|
|
_test_engine, AsyncTestingSessionLocal = async_test_db
|
|
async with AsyncTestingSessionLocal() as session:
|
|
agent_type = AgentType(
|
|
id=uuid.uuid4(),
|
|
name=agent_type_create_data.name,
|
|
slug=agent_type_create_data.slug,
|
|
description=agent_type_create_data.description,
|
|
expertise=agent_type_create_data.expertise,
|
|
personality_prompt=agent_type_create_data.personality_prompt,
|
|
primary_model=agent_type_create_data.primary_model,
|
|
fallback_models=agent_type_create_data.fallback_models,
|
|
model_params=agent_type_create_data.model_params,
|
|
mcp_servers=agent_type_create_data.mcp_servers,
|
|
tool_permissions=agent_type_create_data.tool_permissions,
|
|
is_active=agent_type_create_data.is_active,
|
|
)
|
|
session.add(agent_type)
|
|
await session.commit()
|
|
await session.refresh(agent_type)
|
|
return agent_type
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def test_agent_instance_crud(async_test_db, test_project_crud, test_agent_type_crud):
|
|
"""Create a test agent instance in the database for CRUD tests."""
|
|
_test_engine, AsyncTestingSessionLocal = async_test_db
|
|
async with AsyncTestingSessionLocal() as session:
|
|
agent_instance = AgentInstance(
|
|
id=uuid.uuid4(),
|
|
agent_type_id=test_agent_type_crud.id,
|
|
project_id=test_project_crud.id,
|
|
status=AgentStatus.IDLE,
|
|
current_task=None,
|
|
short_term_memory={},
|
|
long_term_memory_ref=None,
|
|
session_id=None,
|
|
tasks_completed=0,
|
|
tokens_used=0,
|
|
cost_incurred=Decimal("0.0000"),
|
|
)
|
|
session.add(agent_instance)
|
|
await session.commit()
|
|
await session.refresh(agent_instance)
|
|
return agent_instance
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def test_sprint_crud(async_test_db, test_project_crud, sprint_create_data):
|
|
"""Create a test sprint in the database for CRUD tests."""
|
|
_test_engine, AsyncTestingSessionLocal = async_test_db
|
|
async with AsyncTestingSessionLocal() as session:
|
|
sprint = Sprint(
|
|
id=uuid.uuid4(),
|
|
project_id=test_project_crud.id,
|
|
**sprint_create_data,
|
|
)
|
|
session.add(sprint)
|
|
await session.commit()
|
|
await session.refresh(sprint)
|
|
return sprint
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def test_issue_crud(async_test_db, test_project_crud, issue_create_data):
|
|
"""Create a test issue in the database for CRUD tests."""
|
|
_test_engine, AsyncTestingSessionLocal = async_test_db
|
|
async with AsyncTestingSessionLocal() as session:
|
|
issue = Issue(
|
|
id=uuid.uuid4(),
|
|
project_id=test_project_crud.id,
|
|
**issue_create_data,
|
|
)
|
|
session.add(issue)
|
|
await session.commit()
|
|
await session.refresh(issue)
|
|
return issue
|