79 lines
2.6 KiB
Python
79 lines
2.6 KiB
Python
"""Tests: session.resume finds LIVE lazy (never-persisted) sessions.
|
|
|
|
session.create intentionally writes no state.db row until the first prompt.
|
|
Bot Mode creates every fresh non-default bot's canonical Bot Chat exactly
|
|
that way (profile-scoped, lazy, hidden), then the open/send path resumes it
|
|
by stored key or pending title — which hard-404'd "session not found" for
|
|
every bot that had never spoken (community + Teknium repro, Aug 2026).
|
|
|
|
Contract:
|
|
- resume by stored session_key reattaches to the live in-memory record;
|
|
- resume by pending title reattaches likewise;
|
|
- the match is scoped to the SAME profile home — an unscoped resume of a
|
|
profile-scoped live session still fails closed (no cross-profile leaks);
|
|
- a genuinely unknown id still returns 4007.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
import tui_gateway.server as srv
|
|
|
|
|
|
@pytest.fixture
|
|
def home(tmp_path, monkeypatch):
|
|
h = tmp_path / ".hermes"
|
|
(h / "profiles" / "ops").mkdir(parents=True)
|
|
monkeypatch.setenv("HERMES_HOME", str(h))
|
|
return h
|
|
|
|
|
|
@pytest.fixture
|
|
def live_lazy_session(home):
|
|
"""A live registry record shaped like session.create's lazy output."""
|
|
sid = "live-lazy-1"
|
|
record = {
|
|
"history": [],
|
|
"last_active": 0.0,
|
|
"pending_title": "Bot Chat",
|
|
"pending_hidden": True,
|
|
"profile_home": str(home / "profiles" / "ops"),
|
|
"running": False,
|
|
"session_key": "20260823_000000_abc123",
|
|
"source": "desktop",
|
|
}
|
|
srv._sessions[sid] = record
|
|
yield sid, record
|
|
srv._sessions.pop(sid, None)
|
|
|
|
|
|
def _resume(params):
|
|
return srv._methods["session.resume"](1, params)
|
|
|
|
|
|
def test_resume_by_stored_key_reattaches(live_lazy_session):
|
|
sid, record = live_lazy_session
|
|
out = _resume({"profile": "ops", "session_id": record["session_key"], "omit_messages": True})
|
|
assert "error" not in out, out
|
|
assert out["result"]["session_id"] == sid
|
|
assert out["result"]["stored_session_id"] == record["session_key"]
|
|
|
|
|
|
def test_resume_by_pending_title_reattaches(live_lazy_session):
|
|
sid, _record = live_lazy_session
|
|
out = _resume({"profile": "ops", "session_id": "Bot Chat", "omit_messages": True})
|
|
assert "error" not in out, out
|
|
assert out["result"]["session_id"] == sid
|
|
|
|
|
|
def test_unscoped_resume_of_profile_session_fails_closed(live_lazy_session):
|
|
_sid, record = live_lazy_session
|
|
out = _resume({"session_id": record["session_key"], "omit_messages": True})
|
|
assert out.get("error", {}).get("code") == 4007
|
|
|
|
|
|
def test_unknown_id_still_404s(home):
|
|
out = _resume({"profile": "ops", "session_id": "ghost-9999", "omit_messages": True})
|
|
assert out.get("error", {}).get("code") == 4007
|