feat: publish CodexPi contest snapshot
Some checks are pending
Qualité / tests (push) Waiting to run
Some checks are pending
Qualité / tests (push) Waiting to run
This commit is contained in:
94
tests/test_activity_duck.py
Normal file
94
tests/test_activity_duck.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
|
||||
def make_conversation(app, projects, owner):
|
||||
root = projects / "duck"
|
||||
root.mkdir()
|
||||
project_id = str(uuid.uuid4())
|
||||
app.state.db.execute(
|
||||
"INSERT INTO projects(id,name,path,owner_id,created_at) VALUES(?,?,?,?,?)",
|
||||
(project_id, "Duck project", str(root), owner, "2026-01-01"),
|
||||
)
|
||||
conversation = app.state.codex.create_conversation(project_id, "Long task", user_id=owner)
|
||||
return project_id, conversation
|
||||
|
||||
|
||||
def test_duck_repeated_failures_and_long_task_are_deduplicated(logged_in):
|
||||
client, app, projects, _, _ = logged_in
|
||||
owner = app.state.db.one("SELECT id FROM users LIMIT 1")["id"]
|
||||
_, conversation = make_conversation(app, projects, owner)
|
||||
for index in range(3):
|
||||
app.state.db.execute(
|
||||
"INSERT INTO prompt_queue(id,conversation_id,content,status,attachment_ids,created_at,finished_at,error,requested_by) VALUES(?,?,?,?,?,?,?,?,?)",
|
||||
(str(uuid.uuid4()), conversation["id"], "try", "failed", "[]", f"2026-01-0{index+1}", f"2026-01-0{index+1}", f"pytest failed in test_widget line {40+index}", owner),
|
||||
)
|
||||
started = (datetime.now(UTC) - timedelta(minutes=45)).isoformat()
|
||||
running_id = str(uuid.uuid4())
|
||||
app.state.db.execute(
|
||||
"INSERT INTO prompt_queue(id,conversation_id,content,status,attachment_ids,created_at,started_at,requested_by) VALUES(?,?,?,?,?,?,?,?)",
|
||||
(running_id, conversation["id"], "long", "running", "[]", started, started, owner),
|
||||
)
|
||||
app.state.db.execute("UPDATE conversations SET status='running',updated_at=? WHERE id=?", (started, conversation["id"]))
|
||||
|
||||
first = client.get("/api/activity")
|
||||
second = client.get("/api/activity")
|
||||
|
||||
assert first.status_code == second.status_code == 200
|
||||
signals = app.state.db.all("SELECT * FROM duck_signals WHERE conversation_id=?", (conversation["id"],))
|
||||
assert {item["kind"] for item in signals} == {"repeated_failure", "long_running"}
|
||||
assert len(signals) == 2
|
||||
card = next(item for item in second.json()["cards"] if item["id"] == conversation["id"])
|
||||
assert card["state"] == "running"
|
||||
assert len(card["signals"]) == 2
|
||||
|
||||
|
||||
def test_duck_signal_is_private_and_can_be_dismissed(logged_in):
|
||||
client, app, projects, _, headers = logged_in
|
||||
owner = app.state.db.one("SELECT id FROM users LIMIT 1")["id"]
|
||||
_, conversation = make_conversation(app, projects, owner)
|
||||
signal_id = str(uuid.uuid4())
|
||||
now = datetime.now(UTC).isoformat()
|
||||
app.state.db.execute(
|
||||
"INSERT INTO duck_signals(id,conversation_id,kind,fingerprint,status,created_at,updated_at) VALUES(?,?,?,?,?,?,?)",
|
||||
(signal_id, conversation["id"], "long_running", "fixture", "open", now, now),
|
||||
)
|
||||
response = client.post(f"/api/duck-signals/{signal_id}/action", headers=headers, json={"action": "dismiss"})
|
||||
assert response.status_code == 200
|
||||
assert app.state.db.one("SELECT status FROM duck_signals WHERE id=?", (signal_id,))["status"] == "dismissed"
|
||||
|
||||
|
||||
def test_project_duration_budget_warns_without_stopping_active_agent(logged_in):
|
||||
client, app, projects, _, _ = logged_in
|
||||
owner = app.state.db.one("SELECT id FROM users LIMIT 1")["id"]
|
||||
project_id, conversation = make_conversation(app, projects, owner)
|
||||
now = datetime.now(UTC).isoformat()
|
||||
app.state.db.execute(
|
||||
"INSERT INTO user_preferences(user_id,auto_compact_context,duck_enabled,updated_at) VALUES(?,?,?,?) "
|
||||
"ON CONFLICT(user_id) DO UPDATE SET duck_enabled=excluded.duck_enabled",
|
||||
(owner, 0, 0, now),
|
||||
)
|
||||
app.state.db.execute(
|
||||
"INSERT INTO agent_project_policies(project_id,priority,max_runtime_minutes,updated_at) VALUES(?,?,?,?)",
|
||||
(project_id, "normal", 5, now),
|
||||
)
|
||||
started = (datetime.now(UTC) - timedelta(minutes=10)).isoformat()
|
||||
queue_id = str(uuid.uuid4())
|
||||
app.state.db.execute(
|
||||
"INSERT INTO prompt_queue(id,conversation_id,content,status,attachment_ids,created_at,started_at,requested_by) "
|
||||
"VALUES(?,?,?,?,?,?,?,?)",
|
||||
(queue_id, conversation["id"], "long", "running", "[]", started, started, owner),
|
||||
)
|
||||
app.state.db.execute(
|
||||
"UPDATE conversations SET status='running',updated_at=? WHERE id=?", (started, conversation["id"]),
|
||||
)
|
||||
|
||||
assert client.get("/api/activity").status_code == 200
|
||||
|
||||
signal = app.state.db.one(
|
||||
"SELECT * FROM duck_signals WHERE conversation_id=? AND kind='long_running'", (conversation["id"],),
|
||||
)
|
||||
assert signal and signal["queue_id"] == queue_id
|
||||
assert app.state.db.one("SELECT status FROM prompt_queue WHERE id=?", (queue_id,))["status"] == "running"
|
||||
Reference in New Issue
Block a user