Initial commit
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from opc.core.models import ExecutionCheckpoint, Task, TaskStatus
|
||||
from opc.plugins.cli_board.services.actions import BoardActions
|
||||
|
||||
|
||||
class _StubStore:
|
||||
def __init__(self) -> None:
|
||||
self.tasks: dict[str, Task] = {}
|
||||
self.checkpoints: list[ExecutionCheckpoint] = []
|
||||
self.resolved: list[tuple[str, str]] = []
|
||||
|
||||
async def save_task(self, task: Task) -> None:
|
||||
self.tasks[task.id] = task
|
||||
|
||||
async def get_task(self, task_id: str) -> Task | None:
|
||||
return self.tasks.get(task_id)
|
||||
|
||||
async def get_tasks(self, **_kw):
|
||||
return list(self.tasks.values())
|
||||
|
||||
async def get_pending_checkpoints(self, **_kw):
|
||||
return [checkpoint for checkpoint in self.checkpoints if checkpoint.status == "pending"]
|
||||
|
||||
async def resolve_execution_checkpoint(self, checkpoint_id: str, status: str = "resolved") -> None:
|
||||
self.resolved.append((checkpoint_id, status))
|
||||
for checkpoint in self.checkpoints:
|
||||
if checkpoint.checkpoint_id == checkpoint_id:
|
||||
checkpoint.status = status
|
||||
|
||||
|
||||
class _StubMemory:
|
||||
def __init__(self) -> None:
|
||||
self.ensure_session = AsyncMock()
|
||||
|
||||
|
||||
class _StubEngine:
|
||||
def __init__(self) -> None:
|
||||
self.store = _StubStore()
|
||||
self.memory = _StubMemory()
|
||||
self.process_message = AsyncMock(return_value="ok")
|
||||
|
||||
|
||||
class _StubFacade:
|
||||
def __init__(self, engine: _StubEngine) -> None:
|
||||
self.project_id = "demo"
|
||||
self._engine = engine
|
||||
|
||||
async def ensure_ready(self):
|
||||
return self._engine
|
||||
|
||||
|
||||
class BoardActionsTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_create_task_creates_session_backed_placeholder(self) -> None:
|
||||
engine = _StubEngine()
|
||||
actions = BoardActions(_StubFacade(engine), project_id="demo")
|
||||
|
||||
task = await actions.create_task(title="Draft feature", description="Initial plan")
|
||||
|
||||
self.assertIn(task.id, engine.store.tasks)
|
||||
engine.memory.ensure_session.assert_awaited()
|
||||
self.assertEqual(engine.store.tasks[task.id].title, "Draft feature")
|
||||
self.assertEqual(engine.store.tasks[task.id].metadata["source"], "cli_board")
|
||||
|
||||
async def test_send_session_message_routes_through_origin_task(self) -> None:
|
||||
engine = _StubEngine()
|
||||
task = Task(
|
||||
id="task-1",
|
||||
title="Feature task",
|
||||
description="Implement the feature",
|
||||
status=TaskStatus.PENDING,
|
||||
session_id="session-1",
|
||||
project_id="demo",
|
||||
)
|
||||
await engine.store.save_task(task)
|
||||
actions = BoardActions(_StubFacade(engine), project_id="demo")
|
||||
|
||||
response = await actions.send_session_message("task-1", "please continue")
|
||||
|
||||
self.assertEqual(response, "ok")
|
||||
engine.process_message.assert_awaited_once()
|
||||
kwargs = engine.process_message.await_args.kwargs
|
||||
self.assertEqual(kwargs["session_id"], "session-1")
|
||||
self.assertEqual(kwargs["origin_task_id"], "task-1")
|
||||
self.assertEqual(engine.store.tasks["task-1"].status, TaskStatus.IDLE)
|
||||
|
||||
async def test_cancel_task_marks_related_tasks_and_checkpoints_cancelled(self) -> None:
|
||||
engine = _StubEngine()
|
||||
root = Task(
|
||||
id="root",
|
||||
title="Root task",
|
||||
description="Run runtime",
|
||||
status=TaskStatus.RUNNING,
|
||||
session_id="session-root",
|
||||
project_id="demo",
|
||||
)
|
||||
linked = Task(
|
||||
id="child",
|
||||
title="Child task",
|
||||
description="Background child",
|
||||
status=TaskStatus.RUNNING,
|
||||
session_id="session-child",
|
||||
project_id="demo",
|
||||
metadata={"origin_task_id": "root"},
|
||||
)
|
||||
await engine.store.save_task(root)
|
||||
await engine.store.save_task(linked)
|
||||
engine.store.checkpoints.append(
|
||||
ExecutionCheckpoint(
|
||||
checkpoint_id="cp-root",
|
||||
project_id="demo",
|
||||
session_id="session-root",
|
||||
task_id="root",
|
||||
)
|
||||
)
|
||||
actions = BoardActions(_StubFacade(engine), project_id="demo")
|
||||
|
||||
await actions.cancel_task("root")
|
||||
|
||||
self.assertEqual(engine.store.tasks["root"].status, TaskStatus.CANCELLED)
|
||||
self.assertEqual(engine.store.tasks["child"].status, TaskStatus.CANCELLED)
|
||||
self.assertEqual(engine.store.resolved, [("cp-root", "cancelled")])
|
||||
|
||||
Reference in New Issue
Block a user