mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
+ tests
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
"""Sessions API route coverage."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from fastapi import FastAPI
|
||||
from httpx import ASGITransport, AsyncClient
|
||||
from roboco.api.deps import get_current_agent_id, get_db
|
||||
from roboco.api.routes.sessions import router as sessions_router
|
||||
from roboco.db.tables import (
|
||||
AgentTable,
|
||||
ChannelTable,
|
||||
GroupTable,
|
||||
ProjectTable,
|
||||
SessionTable,
|
||||
TaskTable,
|
||||
)
|
||||
from roboco.models import AgentRole, AgentStatus, Team
|
||||
from roboco.models.base import (
|
||||
ChannelType,
|
||||
SessionStatus,
|
||||
TaskNature,
|
||||
TaskStatus,
|
||||
TaskType,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import AsyncIterator
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def session_client(
|
||||
db_session: AsyncSession,
|
||||
) -> AsyncIterator[dict]:
|
||||
pm = AgentTable(
|
||||
id=uuid4(),
|
||||
name="MainPM",
|
||||
slug=f"main-pm-{uuid4().hex[:8]}",
|
||||
role=AgentRole.MAIN_PM,
|
||||
team=None,
|
||||
status=AgentStatus.ACTIVE,
|
||||
model_config={},
|
||||
system_prompt="pm",
|
||||
capabilities=[],
|
||||
permissions={},
|
||||
metrics={},
|
||||
)
|
||||
db_session.add(pm)
|
||||
await db_session.flush()
|
||||
|
||||
channel = ChannelTable(
|
||||
id=uuid4(),
|
||||
name="ch",
|
||||
slug=f"ch-{uuid4().hex[:6]}",
|
||||
type=ChannelType.CELL,
|
||||
members=[pm.id],
|
||||
writers=[pm.id],
|
||||
)
|
||||
db_session.add(channel)
|
||||
await db_session.flush()
|
||||
|
||||
group = GroupTable(
|
||||
id=uuid4(),
|
||||
name="g1",
|
||||
channel_id=channel.id,
|
||||
members=[pm.id],
|
||||
hierarchy_level=4,
|
||||
)
|
||||
db_session.add(group)
|
||||
await db_session.flush()
|
||||
|
||||
project = ProjectTable(
|
||||
id=uuid4(),
|
||||
name="S-Proj",
|
||||
slug=f"s-proj-{uuid4().hex[:6]}",
|
||||
git_url="https://example.com/r.git",
|
||||
assigned_cell=Team.BACKEND,
|
||||
created_by=pm.id,
|
||||
)
|
||||
db_session.add(project)
|
||||
await db_session.flush()
|
||||
|
||||
task = TaskTable(
|
||||
id=uuid4(),
|
||||
title="t",
|
||||
description="d",
|
||||
acceptance_criteria=["ac"],
|
||||
status=TaskStatus.PENDING,
|
||||
priority=2,
|
||||
task_type=TaskType.CODE,
|
||||
nature=TaskNature.TECHNICAL,
|
||||
project_id=project.id,
|
||||
created_by=pm.id,
|
||||
team=Team.BACKEND,
|
||||
)
|
||||
db_session.add(task)
|
||||
await db_session.flush()
|
||||
|
||||
app = FastAPI()
|
||||
app.include_router(sessions_router, prefix="/api/sessions")
|
||||
|
||||
async def _override_db():
|
||||
yield db_session
|
||||
|
||||
async def _override_agent_id() -> UUID:
|
||||
return pm.id
|
||||
|
||||
app.dependency_overrides[get_db] = _override_db
|
||||
app.dependency_overrides[get_current_agent_id] = _override_agent_id
|
||||
|
||||
transport = ASGITransport(app=app)
|
||||
async with AsyncClient(transport=transport, base_url="http://test") as client:
|
||||
yield {
|
||||
"client": client,
|
||||
"pm": pm,
|
||||
"channel": channel,
|
||||
"group": group,
|
||||
"task": task,
|
||||
}
|
||||
app.dependency_overrides.clear()
|
||||
|
||||
|
||||
_HDR = {"X-Agent-ID": str(uuid4()), "X-Agent-Role": "main_pm"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_sessions_empty(session_client: dict) -> None:
|
||||
client = session_client["client"]
|
||||
response = await client.get(
|
||||
f"/api/sessions?group_id={session_client['group'].id}",
|
||||
headers=_HDR,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_sessions_unknown_group_returns_404(
|
||||
session_client: dict,
|
||||
) -> None:
|
||||
client = session_client["client"]
|
||||
response = await client.get(
|
||||
f"/api/sessions?group_id={uuid4()}",
|
||||
headers=_HDR,
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_session(session_client: dict) -> None:
|
||||
client = session_client["client"]
|
||||
response = await client.post(
|
||||
"/api/sessions",
|
||||
json={"group_id": str(session_client["group"].id)},
|
||||
headers=_HDR,
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_session_not_found(session_client: dict) -> None:
|
||||
client = session_client["client"]
|
||||
response = await client.get(
|
||||
f"/api/sessions/{uuid4()}", headers=_HDR
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_session_by_id(
|
||||
session_client: dict, db_session: AsyncSession
|
||||
) -> None:
|
||||
client = session_client["client"]
|
||||
sess = SessionTable(
|
||||
id=uuid4(),
|
||||
group_id=session_client["group"].id,
|
||||
status=SessionStatus.ACTIVE,
|
||||
scope="task",
|
||||
)
|
||||
db_session.add(sess)
|
||||
await db_session.flush()
|
||||
response = await client.get(f"/api/sessions/{sess.id}", headers=_HDR)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_close_session_not_found(session_client: dict) -> None:
|
||||
client = session_client["client"]
|
||||
response = await client.post(
|
||||
f"/api/sessions/{uuid4()}/close", headers=_HDR
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_sessions_for_task(session_client: dict) -> None:
|
||||
client = session_client["client"]
|
||||
response = await client.get(
|
||||
f"/api/sessions/for-task/{session_client['task'].id}", headers=_HDR
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert isinstance(response.json(), list)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_session_for_tasks(session_client: dict) -> None:
|
||||
client = session_client["client"]
|
||||
response = await client.post(
|
||||
"/api/sessions/for-tasks",
|
||||
json={
|
||||
"task_ids": [str(session_client["task"].id)],
|
||||
"channel_slug": session_client["channel"].slug,
|
||||
},
|
||||
headers=_HDR,
|
||||
)
|
||||
# Either 201 success or some validation issue — just check it's not a server error.
|
||||
assert response.status_code < 500
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_session_for_tasks_unknown_channel(
|
||||
session_client: dict,
|
||||
) -> None:
|
||||
client = session_client["client"]
|
||||
response = await client.post(
|
||||
"/api/sessions/for-tasks",
|
||||
json={
|
||||
"task_ids": [str(session_client["task"].id)],
|
||||
"channel_slug": "ghost-channel",
|
||||
},
|
||||
headers=_HDR,
|
||||
)
|
||||
assert response.status_code == 404
|
||||
Reference in New Issue
Block a user