"""Tests for the role gate (title classification) and candidate logs.""" from datetime import date, timedelta from gimme_job.proactive import roles from gimme_job.proactive.plan import ProactivePlan from gimme_job.proactive.roles import ( NON_CLINICAL, OTHER_SPECIALTY, SUPPORT, TARGET, UNKNOWN, classify_role, effective_role_terms, is_role_excluded, normalize_title, prune_candidate_logs, read_role_candidates, record_role_candidate, ) # ── normalize ──────────────────────────────────────────────────────────────── def test_normalize_title_strips_prefix_company_location_ids(): assert ( normalize_title( "Job Application for Dental Assistant at Anthem Pediatric Dentistry " "at Specialty Dental Brands" ) == "Dental Assistant" ) assert normalize_title("Orthodontist - Phoenix, AZ") == "Orthodontist" assert normalize_title("Dentist | Requisition #12345") == "Dentist" assert normalize_title(" Orthodontist ") == "Orthodontist" # ── classify ───────────────────────────────────────────────────────────────── def test_target_titles(): for title in ( "Orthodontist", "Orthodontist Job in Phoenix, AZ at Smile Doctors", "Staff Dentist", "Dentist II (Orthodontics)", "Staff Dental Officer", "Specialty Dentist", "Dental Specialist", ): role, _ = classify_role(title) assert role == TARGET, title def test_support_titles(): for title in ( "Dental Assistant at Anthem Pediatric Dentistry", "Orthodontic Assistant", "Registered Dental Hygienist", "Orthodontic Technician", "Treatment Coordinator", "Front Desk Receptionist", "Orthodontic Clinician I", ): role, _ = classify_role(title) assert role == SUPPORT, title def test_non_clinical_titles(): for title in ( "Account Payable Specialist at Specialty Dental Brands", "Staff Accountant", "Payroll Clerk", "Director of Operations", "Regional Manager", "Marketing Manager", "HR Generalist", ): role, _ = classify_role(title) assert role == NON_CLINICAL, title def test_other_specialty_titles(): """Explicit non-ortho specialties are filtered even though they say "dentist".""" for title in ( "Job Application for Pediatric Dentist - Associate at Specialty Dental Brands", "Pediatric Dentist", "Pediatric Dentistry Associate", "Endodontist", "Periodontist", "Prosthodontist", "Oral Surgeon", "General Dentist", "Public Health Dentist", ): role, _ = classify_role(title) assert role == OTHER_SPECIALTY, title def test_orthodontist_variants_stay_target(): for title in ( "Pediatric Orthodontist", "Orthodontist", "Orthodontic Specialist", "Staff Dentist", "Dentist II (Orthodontics)", ): role, _ = classify_role(title) assert role == TARGET, title def test_unknown_titles(): for title in ("Clinical Lead", "Dental Program Specialist", ""): role, _ = classify_role(title) assert role == UNKNOWN, title def test_target_beats_support_on_compound_titles(): role, _ = classify_role("Orthodontist and Clinical Assistant") assert role == TARGET def test_is_role_excluded(): assert is_role_excluded("Dental Assistant")[0] == SUPPORT assert is_role_excluded("Payroll Clerk")[0] == NON_CLINICAL assert is_role_excluded("Pediatric Dentist")[0] == OTHER_SPECIALTY assert is_role_excluded("Orthodontist") is None assert is_role_excluded("Clinical Lead") is None def test_effective_role_terms_merges_plan_additions(): plan = ProactivePlan() plan.verification.role_terms = {"support": ["surgical tech"]} terms = effective_role_terms(plan) assert "surgical tech" in terms["support"] assert "assistant" in terms["support"] assert classify_role("Surgical Tech", plan)[0] == SUPPORT # ── candidate log ──────────────────────────────────────────────────────────── def test_record_read_and_prune_candidate_logs(): today = date(2026, 9, 12) record_role_candidate( "Dental Assistant", "https://x/j/1", "greenhouse", SUPPORT, "matched", run_date=today ) record_role_candidate( "Orthodontic Clinician", "https://x/j/2", "workday", UNKNOWN, "no keyword", run_date=today ) record_role_candidate( "Orthodontist", "https://x/j/3", "lever", TARGET, "target", run_date=today ) entries = read_role_candidates(today) assert len(entries) == 2 # target is not logged assert entries[0]["title"] == "Dental Assistant" assert entries[0]["role"] == SUPPORT old = today - timedelta(days=31) record_role_candidate("Old", "https://x/old", "lever", UNKNOWN, "old", run_date=old) removed = prune_candidate_logs(30, now=today) assert removed == 1 assert {e["title"] for e in read_role_candidates(today)} == { "Dental Assistant", "Orthodontic Clinician", } assert read_role_candidates(old) == [] def test_candidate_log_path_shape(): path = roles.candidates_log_path(date(2026, 1, 2)) assert path.name == "2026-01-02.roles.jsonl"