Files
matchmaking-v2/tests/test_coverage.py
raulgupta b1e9cdd182 Engine v2: embeddings sift + Opus curator + Postgres feed persistence
- A1: fire the hard filter (Apify is precise); embedding vibe-ranker (embed.py)
  blends with the floor-free white-box (rank.py) to sift ~90 -> top 18
- A2: Opus curator (curate.py) reads the 18 -> honest <=count + Gemini-voiced
  report cards; graceful fallback to the white-box + templated cards
- LLM via opencode.ai/zen gateway (llm.py): Opus chat + direct-OpenAI embeddings
- Run LLM work off the event loop (asyncio.to_thread) so the Redis response publishes
- C1: dedicated Postgres (app/db/) persists the per-user feed; get_scout_feed
  replays it so matches survive navigation/refresh
- match contract + report-card fields (schema.py); skills.py; tests/
2026-06-19 15:51:16 +05:30

50 lines
2.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Phase 1 — the floor-free + coverage-aware invariants (the v1-collapse guardrails).
This is the test that would have caught the old engine: every factor is float-or-`None`
(no constant floors), and a sparse profile must NOT collapse all jobs to one neutral score.
"""
from app.engine import rank as R
_JOBS = [
{"title": "Product Manager", "seniority_level": "senior", "location_city": "New Delhi",
"location_country": "India", "salary_lpa": 30,
"details": {"skills": ["Product Management", "SQL"], "industry": "Fintech",
"description": "product manager roadmap stakeholders"}},
{"title": "Sales Lead", "seniority_level": "lead", "location_city": "Mumbai",
"location_country": "India", "salary_lpa": None,
"details": {"skills": ["Sales", "CRM"], "industry": "SaaS", "description": "sales quota targets"}},
{"title": "Product Manager", "seniority_level": "mid", "location_mode": "remote",
"location_city": "Remote", "details": {"skills": ["Product Management"], "description": "product manager"}},
{"title": "Designer", "seniority_level": None, "location_city": None, "salary_lpa": None, "details": {}},
]
def test_every_factor_returns_float_or_none():
p_full = R.profile_from({"title": "Product Manager", "location": ["New Delhi · India"],
"industry": ["Fintech"], "experience": ["Senior"], "years": 9,
"role": ["Product"], "targetComp": "₹2530L"})
p_sparse = R.profile_from({"title": "Product Manager"})
for p in (p_full, p_sparse):
for job in _JOBS:
for name, fn in R.FACTORS.items():
v = fn(p, job)
assert v is None or (isinstance(v, float) and 0.0 <= v <= 1.0), f"{name}{v!r}"
def test_sparse_profile_does_not_collapse():
# The v1 bug: sparse profile → everyone ~60. Assert real score variance across varied jobs.
p = R.profile_from({"title": "Product Manager", "location": ["New Delhi · India"]})
us = [u for u in (R.utility(p, j)[0] for j in _JOBS) if u is not None]
assert len(us) >= 2 and (max(us) - min(us)) > 0.1, f"collapsed to a flat band: {us}"
def test_absent_factor_redistributes_weight_not_floors():
# A job missing salary/industry/skills must still score on what IS present (no 60 injected).
p = R.profile_from({"title": "Product Manager", "location": ["New Delhi · India"]})
bare = {"title": "Product Manager", "location_city": "New Delhi", "location_country": "India",
"details": {"description": "product manager"}}
U, factors = R.utility(p, bare)
assert U is not None
assert factors["salary"] is None and factors["skill"] is None # absent
assert factors["location"] == 1.0 # present, real