"""Tests for the keyword-based session name derivation (YAKE, no LLM). A new session's display `name` is a 3-5 word Italian-keyword summary of the question, derived at the CLI layer (`tht session new`) with no LLM. `create_session` core keeps its `name=None` default; the policy lives in `new_cmd`. """ import json from typer.testing import CliRunner from tht.cli.session_cmd import session_app from tht.config import DatabaseConfig from tht.session.store import _extract_name, _summarize, load_session def _db(): return DatabaseConfig( database="testdb", user="u", password="p", schema="public", ) class _FakeCfg: def __init__(self, sessions): self.database = _db() self.paths = type("P", (), {"sessions": sessions})() def test_extract_name_is_a_3_to_5_word_italian_summary(): q = "Elenca i pazienti anziani con esiti gravi nell'ultimo periodo." name = _extract_name(q) words = name.split() assert 3 <= len(words) <= 5 # the generic query verb is dropped... assert "elenca" not in [w.lower() for w in words] # ...and the salient content survives lower = name.lower() assert "pazienti" in lower and "anziani" in lower # deterministic assert _extract_name(q) == name def test_extract_name_falls_back_to_summarize_on_failure(monkeypatch): from tht.session import store def boom(*a, **k): raise RuntimeError("yake down") monkeypatch.setattr(store.yake, "KeywordExtractor", boom) q = "Elenca i pazienti anziani con esiti gravi." assert _extract_name(q) == _summarize(q) def test_extract_name_empty_question_is_empty(): assert _extract_name("") == "" assert _extract_name(" ") == "" def test_new_cmd_autonames_when_no_name(tmp_path, monkeypatch): from tht.cli import session_cmd monkeypatch.setattr(session_cmd, "_load_config_or_exit", lambda _: _FakeCfg(tmp_path)) q = "Mostra i pazienti con interventi recenti e complicazioni rilevanti." res = CliRunner().invoke(session_app, ["new", q, "--json"]) assert res.exit_code == 0, res.output sid = json.loads(res.output)["id"] name = load_session(sid, tmp_path).name assert name == _extract_name(q) assert name and 3 <= len(name.split()) <= 5 def test_new_cmd_explicit_name_wins(tmp_path, monkeypatch): from tht.cli import session_cmd monkeypatch.setattr(session_cmd, "_load_config_or_exit", lambda _: _FakeCfg(tmp_path)) res = CliRunner().invoke( session_app, ["new", "Una domanda qualunque", "--name", "Mio nome", "--json"] ) assert res.exit_code == 0, res.output sid = json.loads(res.output)["id"] assert load_session(sid, tmp_path).name == "Mio nome"