File size: 3,263 Bytes
db0cec8
 
 
 
 
 
 
 
 
 
 
 
 
cc74dfc
 
 
 
db0cec8
 
 
 
 
 
 
 
 
 
3cc1867
db0cec8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b41b0f
 
 
db0cec8
7b41b0f
 
db0cec8
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
"""
Regression for the no-compromise 90%+ pipeline (fit expansion + auto-repair +
status). Uses a WORST-CASE stub LLM (the honest floor). Asserts:
  - in-domain PM JDs reach READY_90_PLUS (jd_match >= 90, readability >= 90)
  - a security-PM JD reaches 90 but is flagged REVIEW_RECOMMENDED (risky terms)
  - the candidate vault gets populated
"""
import os, sys, io, shutil
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
sys.path.insert(0, os.path.abspath("."))

from src.resume_customizer import ResumeCustomizer
from src.llm_client import LLMClient
import src.candidate_vault as _cv
_cv._VAULT_PATH = "data/_test_vault_90.json"
if os.path.exists(_cv._VAULT_PATH):
    os.remove(_cv._VAULT_PATH)

src_pdf = r"C:\Users\Nxtwave\Desktop\resume\Saiteja_Tirunagari_Resume A 26 - Copy.pdf"
dst = "data/resume/resume.pdf"
os.makedirs("data/resume", exist_ok=True)
if not os.path.exists(dst) and os.path.exists(src_pdf):
    shutil.copyfile(src_pdf, dst)
if os.path.exists("data/resume/_parsed.json"):
    os.remove("data/resume/_parsed.json")


def stub(self, cfg, resume_dict, jd_text, job_title, company, assessment, **kwargs):
    o = dict(resume_dict)
    o["summary"] = (f"Strong-fit candidate for {job_title} at {company}: "
                    + (resume_dict.get("summary") or "PM with 5+ years."))
    return o


LLMClient.tailor_resume_v4 = stub
rc = ResumeCustomizer.__new__(ResumeCustomizer)
rc.llm = LLMClient.__new__(LLMClient)
rc.resume_text = ""
rc.output_dir = "data/output/resumes/_v3_test"
os.makedirs(rc.output_dir, exist_ok=True)
rc.fast_model_cfg = {"model": "fake", "api_key": "fake", "base_url": "https://fake"}
rc._pending_summary_inject = []

JOBS = [("generic_pm_3_7yrs", "Generic"), ("airtel_pm", "Airtel"),
        ("edgeverve_pm", "EdgeVerve"), ("navi_pm", "Navi"),
        ("zenda_apm", "zenda"), ("aditya_birla_apm", "Aditya Birla"),
        ("sumo_logic_pm", "Sumo Logic")]

ok = True
print(f'{"JD":<16}{"STATUS":<34}{"jd":>4}{"read":>6}')
for jf, co in JOBS:
    jd = open(f"tests/fixtures/jds/{jf}.txt", encoding="utf-8").read()
    job = {"title": "Product Manager", "company": co, "description": jd, "_raw_assessment": {}}
    rc._generate_resume_v4(job, cfg=rc.fast_model_cfg,
                           filepath=os.path.join(rc.output_dir, f"{co}.docx"))
    rep = job.get("_v2_report", {}); sc = rep.get("estimated_scores", {})
    status = job.get("_v2_status", "")
    jd_m, rd = sc.get("jd_match", 0), sc.get("ats_readability", 0)
    print(f"{jf:<16}{status:<34}{jd_m:>4}{rd:>6}")
    # AUTO_AGGRESSIVE: a security PM JD reaches 90 on PM craft alone (security
    # tooling is HIGH-risk and not auto-claimed) → READY is fine; if PM craft
    # alone can't hit 90 it pauses as NEEDS_USER_INPUT. Either is acceptable.
    if jf == "sumo_logic_pm":
        ok = ok and (status in ("READY_90_PLUS", "READY_90_PLUS_REVIEW_RECOMMENDED",
                                 "NEEDS_USER_INPUT"))
    else:
        ok = ok and (jd_m >= 90 and rd >= 90 and status == "READY_90_PLUS")

from src.candidate_vault import load_vault
print("vault entries:", len(load_vault()))

print("\n" + ("✓ ALL PASS — every JD reaches 90%+ with correct status"
              if ok else "✗ SOME FAILED"))
sys.exit(0 if ok else 1)