From 73245dbed1912ed0412ce8baa2dce521545867ba Mon Sep 17 00:00:00 2001 From: santastabber <204424800+santastabber@users.noreply.github.com> Date: Fri, 19 Jun 2026 06:34:29 +1000 Subject: [PATCH] test: cover webhook archive projection --- .../test_issue4385_cron_archive_reappears.py | 134 +++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/tests/test_issue4385_cron_archive_reappears.py b/tests/test_issue4385_cron_archive_reappears.py index 7db0524c..05c97c44 100644 --- a/tests/test_issue4385_cron_archive_reappears.py +++ b/tests/test_issue4385_cron_archive_reappears.py @@ -1,4 +1,4 @@ -"""Regression coverage for #4385: archived cron sessions reappearing.""" +"""Regression coverage for archived state.db-projected sessions reappearing.""" from __future__ import annotations @@ -133,6 +133,138 @@ def test_cron_state_projection_preserves_archived_sidecar(monkeypatch, tmp_path) assert rows[0]["archived"] is True +def test_webhook_state_projection_preserves_archived_sidecar(monkeypatch, tmp_path): + """Archived webhook sidecars must not reappear as unarchived state.db rows.""" + import api.models as models + + sid = "webhook_archive_20260618" + db_path = tmp_path / "state.db" + with sqlite3.connect(db_path) as conn: + conn.execute( + """ + CREATE TABLE sessions ( + id TEXT PRIMARY KEY, + title TEXT, + model TEXT, + message_count INTEGER, + started_at REAL, + source TEXT, + user_id TEXT + ) + """ + ) + conn.execute( + """ + CREATE TABLE messages ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + session_id TEXT NOT NULL, + role TEXT NOT NULL, + content TEXT, + timestamp REAL NOT NULL + ) + """ + ) + conn.execute( + """ + INSERT INTO sessions ( + id, title, model, message_count, started_at, source, user_id + ) VALUES (?, ?, ?, ?, ?, ?, ?) + """, + ( + sid, + None, + "test-model", + 2, + 20, + "webhook", + "webhook:read-later", + ), + ) + conn.execute( + """ + INSERT INTO messages (session_id, role, content, timestamp) + VALUES (?, 'user', 'payload', 21) + """, + (sid,), + ) + conn.execute( + """ + INSERT INTO messages (session_id, role, content, timestamp) + VALUES (?, 'assistant', 'done', 22) + """, + (sid,), + ) + + class ArchivedWebhookSidecar: + title = "Webhook Session" + archived = True + + monkeypatch.setattr( + models.Session, + "load_metadata_only", + staticmethod(lambda candidate: ArchivedWebhookSidecar() if candidate == sid else None), + ) + + rows = models._load_cli_sessions_uncached( + tmp_path, + db_path, + "default", + include_claude_code=False, + ) + + assert len(rows) == 1 + row = rows[0] + assert row["session_id"] == sid + assert row["title"] == "Webhook Session" + assert row["source_tag"] == "webhook" + assert row["raw_source"] == "webhook" + assert row["session_source"] == "other" + assert row["source_label"] == "Webhook" + assert row["is_cli_session"] is False + assert row["archived"] is True + + +def test_archived_webhook_projection_reaches_sidebar_payload(monkeypatch): + """The sidebar payload must preserve archived state for webhook projections.""" + import api.routes as routes + + sid = "webhook_archive_20260618" + raw_webhook_row = { + "session_id": sid, + "title": "Webhook Session", + "profile": "default", + "updated_at": 22, + "last_message_at": 22, + "message_count": 2, + "user_message_count": 1, + "archived": True, + "source_tag": "webhook", + "raw_source": "webhook", + "session_source": "other", + "source_label": "Webhook", + "is_cli_session": False, + } + + monkeypatch.setattr(routes, "all_sessions", lambda diag=None: []) + monkeypatch.setattr(routes, "get_cli_sessions", lambda source_filter=None, all_profiles=False: [raw_webhook_row]) + monkeypatch.setattr(routes, "_reconcile_stale_stream_state_for_session_rows", lambda _sessions: False) + + payload = routes._build_session_list_cache_payload( + active_profile="default", + all_profiles=False, + show_cli_sessions=True, + show_previous_messaging_sessions=False, + show_cron_sessions=False, + ) + + rows = payload["sessions"] + matching = [row for row in rows if row["session_id"] == sid] + assert len(matching) == 1 + assert matching[0]["archived"] is True + assert matching[0]["source_tag"] == "webhook" + assert matching[0]["is_cli_session"] is False + + def test_archived_cron_sidecar_suppresses_raw_unarchived_cron_row(monkeypatch): """An archived cron sidecar should keep the raw state.db cron row hidden.""" import api.routes as routes