94 lines
2.5 KiB
Python
94 lines
2.5 KiB
Python
from dataclasses import replace
|
|
from enum import StrEnum
|
|
from typing import cast
|
|
|
|
import pytest
|
|
|
|
from agentci.engine.model import Job, JobKind
|
|
from agentci.engine.run import JobRun
|
|
from agentci.workflows import dispatch as dispatch_module
|
|
from agentci.workflows.services import WorkflowServices
|
|
|
|
ROUTES = [
|
|
(JobKind.PLAN, "create_plan"),
|
|
(JobKind.DISCUSS, "discuss_plan"),
|
|
(JobKind.ITERATE_PLAN, "iterate_plan"),
|
|
(JobKind.IMPLEMENT, "implement"),
|
|
(JobKind.ITERATE_IMPLEMENT, "iterate_implementation"),
|
|
(JobKind.FIX, "fix_pull_request"),
|
|
]
|
|
|
|
|
|
def make_job(kind: JobKind | None) -> Job:
|
|
return Job(
|
|
id="job-1",
|
|
kind=kind,
|
|
target_key="org/repo:issue:7",
|
|
repo_owner="org",
|
|
repo_name="repo",
|
|
issue_number=7,
|
|
pr_number=None,
|
|
requester="alice",
|
|
comment_id=11,
|
|
delivery_id="delivery-1",
|
|
receive_sequence=1,
|
|
command_body="/agent plan",
|
|
message="request",
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(("kind", "expected_route"), ROUTES)
|
|
async def test_dispatch_routes_every_job_kind_and_returns_body(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
kind: JobKind,
|
|
expected_route: str,
|
|
) -> None:
|
|
calls: list[tuple[str, Job]] = []
|
|
|
|
def route(name: str):
|
|
async def invoke(job: Job, _run: JobRun, _services: WorkflowServices) -> str:
|
|
calls.append((name, job))
|
|
return f"body from {name}"
|
|
|
|
return invoke
|
|
|
|
for _, name in ROUTES:
|
|
monkeypatch.setattr(dispatch_module, name, route(name))
|
|
|
|
job = make_job(kind)
|
|
body = await dispatch_module.dispatch(
|
|
job,
|
|
cast(JobRun, object()),
|
|
cast(WorkflowServices, object()),
|
|
)
|
|
|
|
assert body == f"body from {expected_route}"
|
|
assert calls == [(expected_route, job)]
|
|
|
|
|
|
async def test_dispatch_rejects_unparsed_command() -> None:
|
|
with pytest.raises(RuntimeError, match="Cannot dispatch an unparsed command"):
|
|
await dispatch_module.dispatch(
|
|
make_job(None),
|
|
cast(JobRun, object()),
|
|
cast(WorkflowServices, object()),
|
|
)
|
|
|
|
|
|
class UnsupportedKind(StrEnum):
|
|
UNKNOWN = "unknown"
|
|
|
|
|
|
async def test_dispatch_rejects_unsupported_kind() -> None:
|
|
unsupported = UnsupportedKind.UNKNOWN
|
|
job = replace(make_job(JobKind.PLAN), kind=cast(JobKind, unsupported))
|
|
|
|
with pytest.raises(KeyError) as error:
|
|
await dispatch_module.dispatch(
|
|
job,
|
|
cast(JobRun, object()),
|
|
cast(WorkflowServices, object()),
|
|
)
|
|
|
|
assert error.value.args == (unsupported,)
|