bmc_hub/tests/test_sag_solution_knowledge.py
Christian 1cfe5aee76 feat(migrations): add AI benchmark and vTiger archive tables
- Created tables for AI benchmark runs and results to facilitate model evaluation.
- Added expected answers column to benchmark results.
- Introduced tables for internet connection change cases and vTiger archive management, including records, relations, and checkpoints.
- Implemented triggers to enforce append-only behavior for vTiger archive records and files.
- Enhanced solution management with soft delete capabilities for sag_solutions and knowledge_articles.

feat(scripts): add CRM benchmarking script for Ollama models

- Developed a Python script to benchmark CRM models exposed through Ollama, including various test cases and scoring mechanisms.

test(tests): add comprehensive tests for new features

- Implemented tests for internet change case service, vTiger archive functionality, and sag solution knowledge management.
- Ensured coverage for edge cases and error handling in the new features.
2026-08-31 13:01:35 +02:00

77 lines
2.6 KiB
Python

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]