"""matching/ranking.py — the shared tier-1 ranker. Two things are being protected here: 1. Find Talent's numbers did not change when relevance_score moved out of talent/plugins.py. The scoring tiers were tuned against live LinkedIn pools, so a silent shift would be a regression nobody would notice until the ordering looked wrong. 2. A banked CV maps onto the same profile shape and therefore scores the same as the equivalent sourced profile. """ import pytest from matching.ranking import bank_row_as_profile, rank_bank_row, rank_profile from talent.plugins import relevance_score JOB = { "title": "Backend Engineer", "requirements": ["Python", "FastAPI", "PostgreSQL"], "optional_skills": ["Docker"], } class FakeBankRow: """The columns bank_row_as_profile reads. Not a SQLModel — this test must not need a database to check arithmetic.""" def __init__(self, *, current_position="", current_company="", skills=None, full_text=""): self.current_position = current_position self.current_company = current_company self.skills = skills or [] self.full_text = full_text # -------------------------------------------------------------------------- # Find Talent parity # -------------------------------------------------------------------------- def test_relevance_score_is_the_shared_ranker(): """talent/plugins.py re-exports rather than reimplements.""" assert relevance_score is rank_profile @pytest.mark.parametrize( "profile", [ {"current_title": "Backend Engineer", "headline": "", "skills": [], "summary": None}, {"current_title": "", "headline": "Backend Engineer | Python", "skills": [], "summary": None}, {"current_title": "", "headline": "", "skills": ["Python", "FastAPI"], "summary": None}, {"current_title": "Senior Backend Engineer", "headline": "", "skills": ["Python"], "summary": None}, {"current_title": None, "headline": None, "skills": None, "summary": None}, ], ) def test_find_talent_call_shape_still_works(profile): """The old call site passes exactly this shape, including Nones.""" score = relevance_score(JOB, profile) assert isinstance(score, int) assert 0 <= score <= 100 def test_title_containment_beats_headline_phrase(): """The tuned tier order: title containment 55 > headline phrase 45 > overlap. This is the rule the live pool forced (a keyword-stuffed headline must not outrank someone whose title IS the job title), so it is the one most worth pinning. """ own_title = rank_profile(JOB, {"current_title": "Senior Backend Engineer", "headline": "", "skills": [], "summary": None}) stuffed = rank_profile(JOB, {"current_title": "", "headline": "Backend Engineer | AI | ML", "skills": [], "summary": None}) assert own_title > stuffed def test_unrelated_profile_scores_low(): score = rank_profile(JOB, { "current_title": "Pastry Chef", "headline": "Baking and patisserie", "skills": ["Sourdough"], "summary": None, }) assert score < 20 def test_empty_job_does_not_crash_or_credit(): assert rank_profile({}, {"current_title": "Backend Engineer", "skills": ["Python"]}) == 0 # -------------------------------------------------------------------------- # Banked CVs score identically to the equivalent sourced profile # -------------------------------------------------------------------------- def test_bank_row_scores_the_same_as_the_equivalent_profile(): row = FakeBankRow( current_position="Backend Engineer", current_company="Acme", skills=["Python", "FastAPI", "PostgreSQL"], full_text="Built services at Acme.", ) equivalent = { "current_title": "Backend Engineer", "headline": "Acme", "skills": ["Python", "FastAPI", "PostgreSQL"], "summary": "Built services at Acme.", } assert rank_bank_row(JOB, row) == rank_profile(JOB, equivalent) def test_bank_mapping_uses_company_as_the_headline(): """A resume has no headline; the employer is the nearest equivalent.""" profile = bank_row_as_profile(FakeBankRow(current_position="Engineer", current_company="Acme")) assert profile["current_title"] == "Engineer" assert profile["headline"] == "Acme" def test_bank_mapping_truncates_full_text(): """Feeding a whole resume to the token overlap would flatten every score.""" from matching.ranking import RESUME_EXCERPT_CHARS profile = bank_row_as_profile(FakeBankRow(full_text="x" * (RESUME_EXCERPT_CHARS + 500))) assert len(profile["summary"]) == RESUME_EXCERPT_CHARS def test_bank_mapping_survives_missing_columns(): """A CV banked before extraction existed has no skills and no title.""" profile = bank_row_as_profile(FakeBankRow()) assert profile == {"current_title": "", "headline": "", "skills": [], "summary": ""} assert rank_bank_row(JOB, FakeBankRow()) == 0 def test_skills_only_bank_row_still_ranks(): """Extraction is what makes an untitled CV rankable at all.""" row = FakeBankRow(skills=["Python", "FastAPI", "PostgreSQL", "Docker"]) assert rank_bank_row(JOB, row) > 0