86 lines
3.1 KiB
Python
86 lines
3.1 KiB
Python
from datetime import UTC, datetime, timedelta
|
|
from types import SimpleNamespace
|
|
from typing import Any, cast
|
|
|
|
from test_conversations import StubFrontend, World, world
|
|
|
|
from beaver_gateway.jobs.job import Job, JobRun
|
|
from beaver_gateway.storage.models import Conversation
|
|
|
|
__all__ = ["world"]
|
|
|
|
|
|
async def _noop(_: JobRun) -> None:
|
|
return None
|
|
|
|
|
|
def _run(world: World) -> JobRun:
|
|
return JobRun(
|
|
job=Job("test", _noop),
|
|
trigger="test",
|
|
payload={},
|
|
scheduler=cast("Any", SimpleNamespace(conversations=world.conversations)),
|
|
)
|
|
|
|
|
|
async def _quiet_since(world: World, conv: Conversation, ago: timedelta) -> None:
|
|
async def apply(row: Conversation) -> None:
|
|
row.last_activity_at = datetime.now(UTC) - ago
|
|
|
|
await world.conversations._update(conv, apply) # noqa: SLF001
|
|
|
|
|
|
async def test_close_quiet_closes_and_marks_only_idle_branches(world: World) -> None:
|
|
marked: list[tuple[str, str]] = []
|
|
|
|
class MarkingFrontend(StubFrontend):
|
|
async def mark_closed(self, conv: Conversation) -> bool:
|
|
marked.append((conv.external_id, conv.status))
|
|
return True
|
|
|
|
tg = MarkingFrontend("tg", ("master", "branch"))
|
|
tg.conversations = world.conversations
|
|
world.conversations._frontends = [tg] # noqa: SLF001
|
|
convs = world.conversations
|
|
master = await convs.create(kind="master", agent="a", session_id="m")
|
|
idle = await convs.create(kind="branch", agent="a", parent=master, session_id="1")
|
|
fresh = await convs.create(kind="branch", agent="a", parent=master, session_id="2")
|
|
waiting = await convs.create(
|
|
kind="branch", agent="a", parent=master, session_id="3"
|
|
)
|
|
await _quiet_since(world, idle, timedelta(days=4))
|
|
await _quiet_since(world, fresh, timedelta(days=1))
|
|
await _quiet_since(world, waiting, timedelta(days=4))
|
|
await convs.queue.push(
|
|
conversation_id=cast("int", waiting.id),
|
|
priority="normal",
|
|
origin="cron",
|
|
text="later",
|
|
)
|
|
|
|
closed = await _run(world).close_quiet(kind="branch", days=3)
|
|
|
|
assert [c.external_id for c in closed] == [idle.external_id]
|
|
assert marked == [(idle.external_id, "closed")]
|
|
assert (await convs.get(fresh.external_id)).status == "open"
|
|
assert (await convs.get(waiting.external_id)).status == "open"
|
|
|
|
|
|
async def test_inject_into_falls_back_to_the_master(world: World) -> None:
|
|
convs = world.conversations
|
|
master = await convs.create(kind="master", agent="a", session_id="m")
|
|
branch = await convs.create(kind="branch", agent="a", parent=master)
|
|
gone = await convs.create(kind="branch", agent="a", parent=master)
|
|
await convs.set_status(gone, "closed")
|
|
run = _run(world)
|
|
|
|
assert await run.inject_into(branch.external_id, "to branch", urgency="normal")
|
|
assert await run.inject_into(gone.external_id, "to closed", urgency="normal")
|
|
assert await run.inject_into(None, "to nobody", urgency="normal")
|
|
|
|
assert [i.text for i in await convs.queue.pending(branch.id)] == ["to branch"]
|
|
assert [i.text for i in await convs.queue.pending(master.id)] == [
|
|
"to closed",
|
|
"to nobody",
|
|
]
|