Codex round-1 SHOULD-FIX: the PR's only test change mocked the new write to a no-op. Add real-SessionDB tests proving generated-title persistence, manual-rename no-overwrite, and cli/gateway source preservation on ensure_session. Additive test-only; no behavior change to the contributor's fix. Co-authored-by: liuguangyong93 <liuguangyong93@users.noreply.github.com>
96 lines
3.5 KiB
Python
96 lines
3.5 KiB
Python
"""Direct coverage for api.state_sync.sync_session_title (#6892).
|
|
|
|
Codex round-1 SHOULD-FIX: the PR's only test change mocks sync_session_title to a
|
|
no-op, so the new state.db-writing path had no direct test proving it actually
|
|
persists a generated title AND preserves a manual rename. These tests exercise
|
|
the real function against a temporary hermes-agent SessionDB.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
|
|
def _make_db(tmp_path):
|
|
hermes_state = pytest.importorskip("hermes_state")
|
|
SessionDB = hermes_state.SessionDB
|
|
return SessionDB(db_path=tmp_path / "state.db")
|
|
|
|
|
|
@pytest.mark.requires_agent_modules
|
|
def test_sync_session_title_persists_generated_title(tmp_path, monkeypatch):
|
|
"""A generated title is written to state.db so `hermes sessions list` isn't blank."""
|
|
from api import state_sync
|
|
|
|
db = _make_db(tmp_path)
|
|
try:
|
|
# Route sync_session_title at the real temp DB (a fresh handle each call,
|
|
# mirroring production, but pointed at our tmp state.db).
|
|
monkeypatch.setattr(
|
|
state_sync,
|
|
"_get_state_db",
|
|
lambda profile=None: _make_db(tmp_path),
|
|
)
|
|
|
|
state_sync.sync_session_title("sess-gen", "Generated Title", profile="default")
|
|
|
|
assert db.get_session_title("sess-gen") == "Generated Title"
|
|
# Provenance is the automatic LLM source, not a user rename.
|
|
assert db.get_session_title_source("sess-gen") == db.TITLE_SOURCE_LLM
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@pytest.mark.requires_agent_modules
|
|
def test_sync_session_title_does_not_overwrite_manual_rename(tmp_path, monkeypatch):
|
|
"""A user rename (source=user) is never clobbered by a later title sync."""
|
|
from api import state_sync
|
|
|
|
db = _make_db(tmp_path)
|
|
try:
|
|
# Seed a manual rename first — this records `user` provenance.
|
|
db.ensure_session(session_id="sess-manual", source="cli")
|
|
db.set_session_title("sess-manual", "My Manual Name")
|
|
assert db.get_session_title_source("sess-manual") == db.TITLE_SOURCE_USER
|
|
|
|
monkeypatch.setattr(
|
|
state_sync,
|
|
"_get_state_db",
|
|
lambda profile=None: _make_db(tmp_path),
|
|
)
|
|
|
|
# A background generation now tries to sync an auto title — must be a no-op.
|
|
state_sync.sync_session_title("sess-manual", "Auto Generated", profile="default")
|
|
|
|
assert db.get_session_title("sess-manual") == "My Manual Name"
|
|
assert db.get_session_title_source("sess-manual") == db.TITLE_SOURCE_USER
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@pytest.mark.requires_agent_modules
|
|
def test_sync_session_title_preserves_existing_source_on_ensure(tmp_path, monkeypatch):
|
|
"""ensure_session(source='webui') must not clobber an existing cli/gateway row's source."""
|
|
from api import state_sync
|
|
|
|
db = _make_db(tmp_path)
|
|
try:
|
|
db.ensure_session(session_id="sess-cli", source="cli")
|
|
|
|
monkeypatch.setattr(
|
|
state_sync,
|
|
"_get_state_db",
|
|
lambda profile=None: _make_db(tmp_path),
|
|
)
|
|
|
|
# Sync (which calls ensure_session(source='webui')) on a pre-existing cli row.
|
|
state_sync.sync_session_title("sess-cli", "Some Title", profile="default")
|
|
|
|
# INSERT OR IGNORE semantics: the original source is preserved, the title lands.
|
|
assert db.get_session_title("sess-cli") == "Some Title"
|
|
with db._lock:
|
|
row = db._conn.execute(
|
|
"SELECT source FROM sessions WHERE id = ?", ("sess-cli",)
|
|
).fetchone()
|
|
assert row["source"] == "cli"
|
|
finally:
|
|
db.close()
|