Files
jobtrackingapp/tools/summarizer/tests/test_cv_grounding.py
T

108 lines
5.5 KiB
Python

from fastapi.testclient import TestClient
import pytest
from test_app import load_app_module
def test_cv_evaluation_has_structured_semantic_rules_and_requirements_only_context(monkeypatch):
module = load_app_module(monkeypatch, ollama_model="qwen2.5:7b", service_token="local-proof-token")
expected = {"verdict": "supported", "coverageComplete": True, "claims": [
{"text": "Utviklet API-er.", "verdict": "supported", "sourceQuotes": ["Built APIs."]}]}
def evaluate(prompt):
assert "faithful paraphrases, shortening" in prompt
assert "English/Bokmal translations" in prompt
assert "Job/context text describes requirements ONLY" in prompt
assert "Candidate source is the ONLY evidence" in prompt
assert "Assess ALL factual claims" in prompt
assert "coverage is complete and every entry is supported" in prompt
assert "Employer requires Kubernetes." in prompt
assert module._ai_task_type.get() == "cv-rewrite"
return expected
monkeypatch.setattr(module, "_ollama_generate_json", evaluate)
client = TestClient(module.app)
body = {"candidate_source": "Built APIs.", "proposal": "Utviklet API-er.", "context_only": "Employer requires Kubernetes."}
assert client.post("/cv/evaluate-rewrite", json=body).status_code == 401
response = client.post("/cv/evaluate-rewrite", json=body, headers={"X-Ai-Service-Token": "local-proof-token"})
assert response.status_code == 200
assert response.json() == {"assessment": expected}
@pytest.mark.parametrize("source,proposal,context", [
("", "Built APIs.", ""), (" ", "Built APIs.", ""), ("Built APIs.", "", ""),
("x" * 20000, "New proposal.", ""), ("Built APIs.", "Proposal.", "x" * 6001),
])
def test_cv_evaluation_rejects_empty_or_oversized_inputs_before_generation(monkeypatch, source, proposal, context):
module = load_app_module(monkeypatch)
monkeypatch.setattr(module, "_ollama_generate_json", lambda _: pytest.fail("Invalid input must not generate"))
response = TestClient(module.app).post("/cv/evaluate-rewrite", json={"candidate_source": source, "proposal": proposal, "context_only": context})
assert response.status_code == 422
def test_cv_evaluation_uses_existing_local_first_privacy_gate(monkeypatch):
monkeypatch.setenv("AI_PROVIDER", "groq")
monkeypatch.setenv("GROQ_API_KEY", "synthetic-test-key")
module = load_app_module(monkeypatch, ollama_model="qwen2.5:7b", external_ai_enabled=True)
providers = []
def generate(provider, prompt, **kwargs):
providers.append(provider)
assert kwargs["json_mode"] is True
if provider == "ollama":
raise module._ProviderFailure(provider, "provider_unavailable", 503)
return '{"verdict":"unknown","coverageComplete":false,"claims":[]}'
monkeypatch.setattr(module, "_generate_from_provider", generate)
client = TestClient(module.app)
body = {"candidate_source": "Built APIs.", "proposal": "Led engineers."}
assert client.post("/cv/evaluate-rewrite", json=body).status_code == 503
assert providers == ["ollama"]
providers.clear()
response = client.post("/cv/evaluate-rewrite", json=body, headers={"X-Ai-External-Allowed": "true"})
assert response.status_code == 200
assert providers == ["ollama", "groq"]
assert response.json()["assessment"]["verdict"] == "unknown"
def test_cv_evaluation_rejects_non_object_provider_assessment(monkeypatch):
module = load_app_module(monkeypatch)
monkeypatch.setattr(module, "_ollama_generate_json", lambda _: [])
response = TestClient(module.app).post("/cv/evaluate-rewrite", json={"candidate_source": "Built APIs.", "proposal": "Developed APIs."})
assert response.status_code == 502
@pytest.mark.parametrize("output_mode", [None, "text", "cv_blocks_json"])
def test_cv_rewrite_typed_format_preserves_legacy_text_and_document_json(monkeypatch, output_mode):
module = load_app_module(monkeypatch)
result = '[{"id":"section:summary","title":"Profile","items":["Developed APIs."]}]' if output_mode == "cv_blocks_json" else "Developed APIs."
def generate(prompt):
if output_mode == "cv_blocks_json":
assert "Return ONLY a valid JSON array" in prompt
assert "Preserve every original block id exactly once" in prompt
assert "same title, subtitle and items fields/types" in prompt
assert "No JSON." not in prompt
assert "Preferred whole-CV structure" not in prompt
assert "sensible headings and bullets" not in prompt
else:
assert "Return ONLY the final CV text" in prompt
assert "No JSON." in prompt
assert module._ai_task_type.get() == "cv-rewrite"
return result
monkeypatch.setattr(module, "_ollama_generate_text", generate)
body = {"instruction": "Improve clarity.", "text": "Built APIs."}
if output_mode is not None:
body["output_mode"] = output_mode
response = TestClient(module.app).post("/cv/rewrite", json=body)
assert response.status_code == 200
assert response.json() == {"rewritten_text": result}
def test_cv_rewrite_rejects_unknown_typed_output_mode_before_generation(monkeypatch):
module = load_app_module(monkeypatch)
monkeypatch.setattr(module, "_ollama_generate_text", lambda _: pytest.fail("Unknown mode must not generate"))
response = TestClient(module.app).post("/cv/rewrite", json={"instruction": "Improve", "text": "Built APIs.", "output_mode": "untrusted-mode"})
assert response.status_code == 422