from __future__ import annotations from types import SimpleNamespace from unittest.mock import patch from fastapi.testclient import TestClient from app.main import app from app.core.dependencies import get_current_user, get_db from app.api import matching as matching_module from app.models.models import Candidate, JobCriteria, User, UserRole class FakeQuery: def __init__(self, rows): self.rows = list(rows) def filter(self, *args, **kwargs): return self def order_by(self, *args, **kwargs): return self def all(self): return list(self.rows) def first(self): return self.rows[0] if self.rows else None class FakeSession: def __init__(self): self.recruiter = User( id=1, email="recruiter@example.com", hashed_password="x", full_name="Recruiter", role=UserRole.recruiter, ) self.criteria = JobCriteria( id=1, recruiter_id=1, title="Senior Python Developer", description="Build APIs with FastAPI and SQL", ) self.candidate = Candidate( id=10, full_name="Alice Smith", email="alice@example.com", raw_text="Python FastAPI Docker", ) def query(self, model): if model is User: return FakeQuery([self.recruiter]) if model is JobCriteria: return FakeQuery([self.criteria]) if model is Candidate: return FakeQuery([self.candidate]) return FakeQuery([]) class FakeUser(SimpleNamespace): pass class TestMatchingGenerationRoutes: def setup_method(self): self.fake_session = FakeSession() app.dependency_overrides[get_db] = lambda: self.fake_session app.dependency_overrides[get_current_user] = lambda: FakeUser(id=1, role=UserRole.recruiter) def teardown_method(self): app.dependency_overrides.clear() def test_generate_and_match_route_returns_results(self): with patch.object(matching_module, "_generate_profile_payload", return_value={"ideal_skills": [{"name": "Python", "weight": 100}]}), \ patch.object(matching_module, "calculate_match_score", return_value=(88.0, {"details": "Strong fit"})): with TestClient(app) as client: response = client.post( "/api/matching/generate-and-match", json={"job_title": "Senior Python Developer", "description": "Looking for Python and FastAPI"}, ) assert response.status_code == 200 payload = response.json() assert payload["ideal_profile"]["ideal_skills"] assert len(payload["matches"]) == 1 assert payload["matches"][0]["candidate_id"] == 10 assert payload["matches"][0]["match_score"] == 88.0 def test_matching_results_route_handles_numeric_ids(self): with patch.object(matching_module, "_score_all_candidates", return_value=[]), \ patch.object(matching_module, "_persist_match_results", return_value=[]): with TestClient(app) as client: response = client.post("/api/matching/1/results") assert response.status_code == 200 assert response.json() == []