mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
140 lines
4.4 KiB
Python
140 lines
4.4 KiB
Python
"""DOCS_SYNC_SOURCE + list_open_docs_sync_tasks — the dedupe + open-cap basis.
|
|||
|
|
|
||
|
|
Open docs_sync tasks count toward the cap and block a duplicate per release
|
||
|
|
version; terminal ones and tasks from other sources do not.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import TYPE_CHECKING, cast
|
||
|
|
from uuid import UUID, uuid4
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
from roboco.db.tables import AgentTable, ProjectTable
|
||
|
|
from roboco.foundation import identity as _foundation
|
||
|
|
from roboco.foundation.policy.content import markers
|
||
|
|
from roboco.models.base import (
|
||
|
|
AgentRole,
|
||
|
|
AgentStatus,
|
||
|
|
Complexity,
|
||
|
|
TaskNature,
|
||
|
|
TaskStatus,
|
||
|
|
TaskType,
|
||
|
|
Team,
|
||
|
|
)
|
||
|
|
from roboco.models.task import TaskCreateRequest
|
||
|
|
from roboco.services.task import DOCS_SYNC_SOURCE, get_task_service
|
||
|
|
|
||
|
|
if TYPE_CHECKING:
|
||
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
|
|
||
|
|
SYSTEM_UUID = _foundation.AGENTS["system"].uuid
|
||
|
|
MAIN_PM_UUID = _foundation.AGENTS["main-pm"].uuid
|
||
|
|
_VERSION = "0.23.0"
|
||
|
|
_TWO = 2
|
||
|
|
_ONE = 1
|
||
|
|
|
||
|
|
|
||
|
|
async def _get_or_create_agent(
|
||
|
|
db: AsyncSession, agent_id: object, role: AgentRole, slug: str
|
||
|
|
) -> None:
|
||
|
|
if await db.get(AgentTable, agent_id) is None:
|
||
|
|
db.add(
|
||
|
|
AgentTable(
|
||
|
|
id=agent_id,
|
||
|
|
name=slug,
|
||
|
|
slug=f"{slug}-{uuid4().hex[:8]}",
|
||
|
|
role=role,
|
||
|
|
team=None,
|
||
|
|
status=AgentStatus.ACTIVE,
|
||
|
|
model_config={},
|
||
|
|
system_prompt="x",
|
||
|
|
capabilities=[],
|
||
|
|
permissions={},
|
||
|
|
metrics={},
|
||
|
|
)
|
||
|
|
)
|
||
|
|
await db.flush()
|
||
|
|
|
||
|
|
|
||
|
|
async def _seed_project(db: AsyncSession) -> ProjectTable:
|
||
|
|
project = ProjectTable(
|
||
|
|
id=uuid4(),
|
||
|
|
name="RoboCo Website",
|
||
|
|
slug=f"website-{uuid4().hex[:8]}",
|
||
|
|
git_url="https://github.com/rennf93/roboco-website.git",
|
||
|
|
assigned_cell=Team.BACKEND,
|
||
|
|
created_by=SYSTEM_UUID,
|
||
|
|
)
|
||
|
|
db.add(project)
|
||
|
|
await db.flush()
|
||
|
|
return project
|
||
|
|
|
||
|
|
|
||
|
|
async def _make_task(
|
||
|
|
db: AsyncSession,
|
||
|
|
project: ProjectTable,
|
||
|
|
*,
|
||
|
|
source: str = DOCS_SYNC_SOURCE,
|
||
|
|
terminal: bool = False,
|
||
|
|
version: str | None = None,
|
||
|
|
) -> None:
|
||
|
|
markers_dict: dict[str, object] = {}
|
||
|
|
if version is not None:
|
||
|
|
markers_dict[markers.DOCS_SYNC_RELEASE_VERSION] = version
|
||
|
|
task = await get_task_service(db).create(
|
||
|
|
TaskCreateRequest(
|
||
|
|
title=f"Update docs for v{version or 'unknown'}",
|
||
|
|
description="Refresh published docs to match the shipped release.",
|
||
|
|
acceptance_criteria=["docs refreshed", "gate green"],
|
||
|
|
team=Team.MAIN_PM,
|
||
|
|
assigned_to=MAIN_PM_UUID,
|
||
|
|
created_by=SYSTEM_UUID,
|
||
|
|
task_type=TaskType.PLANNING,
|
||
|
|
nature=TaskNature.TECHNICAL,
|
||
|
|
estimated_complexity=Complexity.MEDIUM,
|
||
|
|
project_id=cast("UUID", project.id),
|
||
|
|
status=TaskStatus.PENDING,
|
||
|
|
source=source,
|
||
|
|
confirmed_by_human=True,
|
||
|
|
)
|
||
|
|
)
|
||
|
|
if markers_dict:
|
||
|
|
task.orchestration_markers = markers_dict
|
||
|
|
if terminal:
|
||
|
|
task.status = TaskStatus.COMPLETED
|
||
|
|
await db.flush()
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture(autouse=True)
|
||
|
|
async def _agents(db_session: AsyncSession) -> None:
|
||
|
|
await _get_or_create_agent(db_session, SYSTEM_UUID, AgentRole.SYSTEM, "system")
|
||
|
|
await _get_or_create_agent(db_session, MAIN_PM_UUID, AgentRole.MAIN_PM, "main-pm")
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_lists_only_open_docs_sync_tasks(db_session: AsyncSession) -> None:
|
||
|
|
proj = await _seed_project(db_session)
|
||
|
|
await _make_task(db_session, proj, version=_VERSION)
|
||
|
|
await _make_task(db_session, proj, terminal=True, version=_VERSION)
|
||
|
|
await _make_task(db_session, proj, source="manual", version=_VERSION)
|
||
|
|
|
||
|
|
open_tasks = await get_task_service(db_session).list_open_docs_sync_tasks()
|
||
|
|
|
||
|
|
assert len(open_tasks) == _ONE
|
||
|
|
assert open_tasks[0].source == DOCS_SYNC_SOURCE
|
||
|
|
assert open_tasks[0].status != TaskStatus.COMPLETED
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_version_scoping(db_session: AsyncSession) -> None:
|
||
|
|
proj = await _seed_project(db_session)
|
||
|
|
await _make_task(db_session, proj, version="0.23.0")
|
||
|
|
await _make_task(db_session, proj, version="0.24.0")
|
||
|
|
|
||
|
|
svc = get_task_service(db_session)
|
||
|
|
assert len(await svc.list_open_docs_sync_tasks()) == _TWO
|
||
|
|
scoped = await svc.list_open_docs_sync_tasks(version="0.23.0")
|
||
|
|
assert len(scoped) == _ONE
|
||
|
|
assert markers.get_docs_sync_release_version(scoped[0]) == "0.23.0"
|