"""The help chat's knowledge feed. The invariants here are all about honesty: the facts must be present, the shortcuts must be the user's real ones, and the prompt must forbid guessing. A help assistant that invents a menu item is the failure mode this whole feature exists to prevent, so the grounding rules are pinned by test rather than trusted to survive a future prompt edit. """ from fastapi.testclient import TestClient from backend.apps.help.help_topics import HELP_TOPICS from backend.apps.help.knowledge import ( build_knowledge_response, build_shortcuts, build_system_prompt, render_combo, ) from backend.apps.help.known_issues import KNOWN_ISSUES from backend.main import app def test_knowledge_endpoint_serves_topics_and_issues(): import backend.auth as auth_mod with TestClient(app, headers={"Authorization": f"Bearer {auth_mod.TOKEN}"}) as client: res = client.get("/api/help/knowledge") assert res.status_code == 200 body = res.json() assert len(body["topics"]) == len(HELP_TOPICS) assert len(body["known_issues"]) == len(KNOWN_ISSUES) assert body["system_prompt"] assert body["app_version"] def test_every_topic_is_self_contained(): """Kapa's rule: a chunk retrieved alone still has to make sense alone.""" for topic in HELP_TOPICS: assert topic.id and topic.title and topic.body assert topic.keywords, f"{topic.id} has no keywords, so local search can never find it" assert len(topic.body) > 40, f"{topic.id} body is too thin to answer anything" def test_topic_ids_are_unique(): ids = [t.id for t in HELP_TOPICS] assert len(ids) == len(set(ids)) def test_known_issues_never_carry_a_fix_date_or_eta(): """Bug status is the easiest thing to lie about, so the data itself must not invite it.""" for issue in KNOWN_ISSUES: assert issue.status in ("known", "mitigated", "fixed") assert issue.detail for banned in ("ETA", "next release", "soon", "will be fixed"): assert banned.lower() not in issue.detail.lower() def test_render_combo_matches_the_platform(): from backend.apps.help.knowledge import IS_MAC if IS_MAC: assert render_combo("Meta+l") == "⌘L" assert render_combo("Meta+Shift+d") == "⌘⇧D" else: assert render_combo("Meta+l") == "Ctrl+L" assert render_combo("Meta+Shift+d") == "Ctrl+Shift+D" def test_shortcuts_use_the_users_configured_combo_not_the_default(): shortcuts = build_shortcuts("Meta+Shift+j", "Alt+m") new_chat = next(s for s in shortcuts if s.action == "Open the new-chat composer") dictation = next(s for s in shortcuts if "dictation" in s.action) assert new_chat.keys == render_combo("Meta+Shift+j") assert dictation.keys == render_combo("Alt+m") def test_dictation_falls_back_to_the_platform_default_when_unset(): from backend.apps.help.knowledge import dictation_default_combo shortcuts = build_shortcuts("Meta+l", None) dictation = next(s for s in shortcuts if "dictation" in s.action) assert dictation.keys == render_combo(dictation_default_combo()) def test_prompt_forbids_guessing_and_permits_not_knowing(): prompt = build_knowledge_response().system_prompt assert "Never invent a button" in prompt assert "Never invent a bug status" in prompt assert "you don't know" in prompt.lower() # The refusal has to be framed as acceptable, or the model treats it as a last resort. assert "not a failure" in prompt def test_prompt_states_it_cannot_see_live_bug_reports(): prompt = build_knowledge_response().system_prompt assert "cannot see live bug reports" in prompt assert "no live view of" in prompt def test_prompt_carries_every_topic_and_issue(): prompt = build_system_prompt(build_shortcuts("Meta+l", None), "9.9.9") for topic in HELP_TOPICS: assert f"[{topic.id}]" in prompt for issue in KNOWN_ISSUES: assert f"[{issue.id}]" in prompt assert "9.9.9" in prompt def test_prompt_stays_within_a_sane_token_budget(): """It rides the cached prefix, but an unbounded knowledge blob still costs a cache write.""" prompt = build_knowledge_response().system_prompt assert len(prompt) < 24_000, "help knowledge is growing past its budget; tighten the topics"