import importlib import sys from pathlib import Path from fastapi.testclient import TestClient ROOT = Path(__file__).resolve().parents[1] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) def load_app_module(monkeypatch, *, skip_model_load=True, ollama_model=None): if skip_model_load: monkeypatch.setenv("AI_SERVICE_SKIP_MODEL_LOAD", "1") else: monkeypatch.delenv("AI_SERVICE_SKIP_MODEL_LOAD", raising=False) monkeypatch.delenv("AI_SERVICE_EAGER_MODEL_LOAD", raising=False) if ollama_model is None: monkeypatch.delenv("OLLAMA_MODEL", raising=False) else: monkeypatch.setenv("OLLAMA_MODEL", ollama_model) if "app" in sys.modules: del sys.modules["app"] module = importlib.import_module("app") return importlib.reload(module) def test_health_reports_runtime_without_ollama_and_without_forcing_model_load(monkeypatch): module = load_app_module(monkeypatch) client = TestClient(module.app) response = client.get("/health") assert response.status_code == 200 payload = response.json() assert payload["ok"] is True assert payload["device"] == "cpu" assert payload["model_loaded"] is False assert payload["model_disabled"] is True assert payload["summarize_available"] is False assert "disabled" in payload["model_load_error"].lower() assert payload["ollama_configured"] is False assert payload["ollama_model"] is None assert payload["ollama_installed_models"] == [] assert payload["ollama_loaded_models"] == [] def test_summarize_returns_503_with_explicit_reason_when_model_loading_is_disabled(monkeypatch): module = load_app_module(monkeypatch) client = TestClient(module.app) response = client.post("/summarize", json={"text": "Platform engineering role with APIs and Python experience."}) assert response.status_code == 503 payload = response.json() assert "disabled" in payload["detail"].lower() def test_health_reports_ollama_unreachable_when_configured_but_not_available(monkeypatch): module = load_app_module(monkeypatch, ollama_model="qwen2.5:7b") def boom(path: str): raise OSError("connection refused") monkeypatch.setattr(module, "_ollama_json", boom) client = TestClient(module.app) response = client.get("/health") assert response.status_code == 200 payload = response.json() assert payload["ollama_configured"] is True assert payload["ollama_reachable"] is False assert payload["ollama_model"] == "qwen2.5:7b" assert payload["ollama_model_available"] is False def test_classify_block_returns_structured_json(monkeypatch): module = load_app_module(monkeypatch) def fake_generate_json(prompt: str): assert "Senior Platform Engineer" in prompt return { "section": "Work Experience", "confidence": 0.91, "reason": "job block", "title": "Senior Platform Engineer", "company": "Atlas Systems", "location": "Oslo", "start": "2019", "end": "Present", "bullets": ["Built event-driven APIs and migration tooling."], "summary": [], "skills": ["Python", "SQL"], } monkeypatch.setattr(module, "_ollama_generate_json", fake_generate_json) client = TestClient(module.app) response = client.post("/cv/classify-block", json={"block": "Senior Platform Engineer at Atlas Systems, Oslo, 2019 - Present. Built event-driven APIs and migration tooling."}) assert response.status_code == 200 payload = response.json() assert payload["section"] == "Work Experience" assert payload["title"] == "Senior Platform Engineer" assert payload["company"] == "Atlas Systems" assert payload["bullets"] == ["Built event-driven APIs and migration tooling."] assert payload["summary"] == [] assert payload["skills"] == ["Python", "SQL"] def test_classify_block_defaults_missing_section_to_other(monkeypatch): module = load_app_module(monkeypatch) monkeypatch.setattr(module, "_ollama_generate_json", lambda prompt: {"bullets": []}) client = TestClient(module.app) response = client.post("/cv/classify-block", json={"block": "Miscellaneous profile text"}) assert response.status_code == 200 payload = response.json() assert payload["section"] == "Other" assert payload["bullets"] == [] assert payload["summary"] == [] assert payload["skills"] == []