from pathlib import Path import sys import pytest from fastapi import HTTPException sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from app.modules.sag.backend import solutions def test_solution_payload_normalizes_legacy_quick_action_values(): payload = solutions._normalize_payload({ "title": " Outlook virker igen ", "solution_type": "standard", "result": "resolved", "visibility": "general", "tags": ["Outlook", " outlook ", "Microsoft 365"], }) assert payload["title"] == "Outlook virker igen" assert payload["solution_type"] == "Support" assert payload["result"] == "Løst" assert payload["tags"] == ["Outlook", "Microsoft 365"] def test_solution_payload_rejects_empty_title(): with pytest.raises(HTTPException) as exc: solutions._normalize_payload({"title": " "}) assert exc.value.status_code == 422 def test_solution_payload_rejects_unknown_visibility(): with pytest.raises(HTTPException) as exc: solutions._normalize_payload({"visibility": "public-internet"}) assert exc.value.status_code == 422 def test_ai_context_redacts_credentials_before_processing(): cleaned, warnings = solutions._redact_sensitive( "Login til router: password=SuperSecret og Authorization: Bearer abc.def.ghi" ) assert "SuperSecret" not in cleaned assert "abc.def.ghi" not in cleaned assert len(warnings) == 2 def test_knowledge_tokens_are_stable_and_remove_fill_words(): assert solutions._knowledge_tokens("Outlook kan ikke synkronisere Outlook med Microsoft 365") == [ "outlook", "synkronisere", "microsoft", "365" ] def test_ai_source_references_accept_common_model_variants(): refs = solutions._normalize_source_refs( "[Sag #135], Kommentar #12; Artikel 4", {"Sag 135", "Kommentar 12", "Artikel 4"}, 135, ) assert refs == ["Sag 135", "Kommentar 12", "Artikel 4"] def test_customer_articles_are_excluded_without_customer_scope(monkeypatch): captured = [] def fake_single(query, params=None): captured.append((query, params)) return {"total": 0} monkeypatch.setattr(solutions, "execute_query_single", fake_single) monkeypatch.setattr(solutions, "execute_query", lambda query, params=None: []) import asyncio result = asyncio.run(solutions.search_knowledge_articles(q="vpn", customer_id=None, _current_user={"id": 1})) assert result["total"] == 0 assert "ka.visibility IN ('general','internal')" in captured[0][0] assert "visibility='customer'" not in captured[0][0]