Files
fast-next-template/backend/tests/crud/syndarix/conftest.py
Felipe Cardoso 742ce4c9c8 fix: Comprehensive validation and bug fixes
Infrastructure:
- Add Redis and Celery workers to all docker-compose files
- Fix celery migration race condition in entrypoint.sh
- Add healthchecks and resource limits to dev compose
- Update .env.template with Redis/Celery variables

Backend Models & Schemas:
- Rename Sprint.completed_points to velocity (per requirements)
- Add AgentInstance.name as required field
- Rename Issue external tracker fields for consistency
- Add IssueSource and TrackerType enums
- Add Project.default_tracker_type field

Backend Fixes:
- Add Celery retry configuration with exponential backoff
- Remove unused sequence counter from EventBus
- Add mypy overrides for test dependencies
- Fix test file using wrong schema (UserUpdate -> dict)

Frontend Fixes:
- Fix memory leak in useProjectEvents (proper cleanup)
- Fix race condition with stale closure in reconnection
- Sync TokenWithUser type with regenerated API client
- Fix expires_in null handling in useAuth
- Clean up unused imports in prototype pages
- Add ESLint relaxed rules for prototype files

CI/CD:
- Add E2E testing stage with Testcontainers
- Add security scanning with Trivy and pip-audit
- Add dependency caching for faster builds

Tests:
- Update all tests to use renamed fields (velocity, name, etc.)
- Fix 14 schema test failures
- All 1500 tests pass with 91% coverage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 10:35:30 +01:00

216 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,
)
from app.models.user import User
from app.schemas.syndarix import (
AgentTypeCreate,
ProjectCreate,
)
@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,
"velocity": 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,
name="TestAgent",
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