diff --git a/api/routes.py b/api/routes.py index 1915b7ec..10560356 100644 --- a/api/routes.py +++ b/api/routes.py @@ -9839,6 +9839,8 @@ def handle_get(handler, parsed) -> bool: sidebar_source = parse_qs(parsed.query).get("sidebar_source", [""])[0].strip().lower() or None if sidebar_source not in ("webui", "cli"): sidebar_source = None + # /api/sessions is the default sidebar contract, so keep the route-owned + # visible-row filter in the shared cache builder for both cache hits and misses. key = _session_list_cache_key( active_profile=active_profile, all_profiles=all_profiles, diff --git a/tests/test_issue2157_sessions_list_stale_stream_state.py b/tests/test_issue2157_sessions_list_stale_stream_state.py index 86616745..b7d2308c 100644 --- a/tests/test_issue2157_sessions_list_stale_stream_state.py +++ b/tests/test_issue2157_sessions_list_stale_stream_state.py @@ -48,6 +48,7 @@ def test_sessions_list_reconciles_stale_stream_state_before_serializing(monkeypa "session_id": "stale-session", "title": "Stale Session", "profile": "default", + "message_count": 1, "active_stream_id": active_stream_id, "is_streaming": is_streaming, "updated_at": 1, diff --git a/tests/test_issue4775_sidebar_hidden_zero_message_pushdown.py b/tests/test_issue4775_sidebar_hidden_zero_message_pushdown.py index 7b0b87d5..17850d2e 100644 --- a/tests/test_issue4775_sidebar_hidden_zero_message_pushdown.py +++ b/tests/test_issue4775_sidebar_hidden_zero_message_pushdown.py @@ -218,15 +218,19 @@ def test_zero_message_rows_with_visibility_signals_survive(monkeypatch): handler = _handle_sessions("http://example.com/api/sessions?sidebar_source=webui&exclude_hidden=1") body = handler.json_body() + by_id = {row["session_id"]: row for row in body["sessions"]} assert handler.status == 200 - assert [r["session_id"] for r in body["sessions"]] == [ - "visible-with-message", + assert set(by_id) >= { "active-stream-row", "attention-row", "pending-flag-row", "pending-user-row", - ] + } + assert by_id["active-stream-row"]["active_stream_id"] == "stream-active" + assert by_id["attention-row"]["attention"]["kind"] == "clarify" + assert by_id["pending-flag-row"]["has_pending_user_message"] is True + assert by_id["pending-user-row"]["title"] == "Pending user row" def test_omit_exclude_hidden_still_returns_default_hidden_rows(monkeypatch): diff --git a/tests/test_sprint1.py b/tests/test_sprint1.py index f11eb0e1..7f91729c 100644 --- a/tests/test_sprint1.py +++ b/tests/test_sprint1.py @@ -85,6 +85,16 @@ def make_session_tracked(created_list, ws=None): return sid, pathlib.Path(d["session"]["workspace"]) +def _make_session_visible(sid): + data, status = post("/api/chat/start", { + "session_id": sid, + "message": "visible row", + "model": "openai/gpt-5.4-mini", + }) + assert status == 200, f"chat/start failed with {status}: {data}" + get(f"/api/chat/cancel?stream_id={urllib.parse.quote(data['stream_id'])}") + + # ────────────────────────────────────────────── # Health check (prerequisite for all tests) @@ -124,7 +134,13 @@ def test_session_create_and_load(): sid = data["session"]["session_id"] assert len(sid) == 12 # uuid4().hex[:12] - # Give it a title so it's visible in the session list (empty Untitled sessions are filtered) + # Load it directly + loaded = get(f"/api/session?session_id={sid}") + assert loaded["session"]["session_id"] == sid + assert loaded["session"]["messages"] == [] + + # Give it a real message so the default sidebar route keeps it visible. + _make_session_visible(sid) post("/api/session/rename", {"session_id": sid, "title": "test-create-verify"}) # Verify it appears in /api/sessions list @@ -132,11 +148,6 @@ def test_session_create_and_load(): sids = [s["session_id"] for s in sessions["sessions"]] assert sid in sids, f"New session {sid} not in sessions list" - # Load it directly - loaded = get(f"/api/session?session_id={sid}") - assert loaded["session"]["session_id"] == sid - assert loaded["session"]["messages"] == [] - # Cleanup post("/api/session/delete", {"session_id": sid}) @@ -207,14 +218,16 @@ def test_session_delete_nonexistent(): def test_sessions_list_sorted(): """Sessions list should be sorted most-recently-updated first.""" - # Create two sessions with a title so they're visible (empty Untitled sessions are filtered) + # Create two sessions with a real message so the default sidebar route keeps them visible. a, _ = post("/api/session/new", {}) time.sleep(0.05) b, _ = post("/api/session/new", {}) sid_a = a["session"]["session_id"] sid_b = b["session"]["session_id"] + _make_session_visible(sid_a) post("/api/session/rename", {"session_id": sid_a, "title": "test-sort-a"}) time.sleep(0.05) + _make_session_visible(sid_b) post("/api/session/rename", {"session_id": sid_b, "title": "test-sort-b"}) sessions = get("/api/sessions") diff --git a/tests/test_sprint15.py b/tests/test_sprint15.py index 0b291f34..73185307 100644 --- a/tests/test_sprint15.py +++ b/tests/test_sprint15.py @@ -1,7 +1,7 @@ """ Sprint 15 Tests: session projects (CRUD, move, backward compat). """ -import json, urllib.error, urllib.request +import json, urllib.error, urllib.parse, urllib.request from tests._pytest_port import BASE @@ -30,12 +30,13 @@ def make_session(created_list): def _make_session_visible(sid): - from api.models import Session - - session = Session.load(sid) - assert session is not None - session.messages = [{"role": "user", "content": "visible row", "timestamp": 1.0}] - session.save() + d, status = post("/api/chat/start", { + "session_id": sid, + "message": "visible row", + "model": "openai/gpt-5.4-mini", + }) + assert status == 200, f"chat/start failed with {status}: {d}" + get(f"/api/chat/cancel?stream_id={urllib.parse.quote(d['stream_id'])}") def make_project(created_list, name="Test Project", color=None): @@ -226,7 +227,8 @@ def test_compact_includes_project_id(): sids = [] try: sid, sess = make_session(sids) - # Give it a title so it appears in the list + # Give it a real message so the default sidebar route keeps it visible. + _make_session_visible(sid) post("/api/session/rename", {"session_id": sid, "title": "Compat Test"}) dl, _ = get("/api/sessions") match = [s for s in dl["sessions"] if s["session_id"] == sid]