"""Preprocess validate stage + pipeline — integrity/graded checks, flag-never-drop, contract columns.""" from __future__ import annotations import copy from pathlib import Path import orjson from preprocess import DATASET_AS_OF, FLAG_COLUMNS, load_candidates, run_preprocess, validate def _clean_record() -> dict: """A coherent candidate that should trip no checks.""" return { "candidate_id": "CAND_0000001", "profile": {"years_of_experience": 5.0, "current_title": "AI Engineer"}, "career_history": [ {"start_date": "2018-01-01", "end_date": "2023-01-01", "duration_months": 60, "is_current": False, "company": "X", "title": "Eng", "industry": "Tech", "company_size": "51-200", "description": "built things"} ], "skills": [{"name": "Python", "proficiency": "advanced", "endorsements": 5, "duration_months": 36}], "redrob_signals": { "signup_date": "2023-01-01", "last_active_date": "2024-01-01", "expected_salary_range_inr_lpa": {"min": 10, "max": 20}, "verified_email": True, "verified_phone": True, "linkedin_connected": True, }, } def _validate_records(tmp_path: Path, records: list[dict]): path = tmp_path / "c.jsonl" path.write_bytes(b"\n".join(orjson.dumps(r) for r in records)) return validate(load_candidates(path), DATASET_AS_OF) def test_clean_record_trips_no_checks(tmp_path: Path) -> None: row = _validate_records(tmp_path, [_clean_record()]).row(0, named=True) assert row["validation_failed"] is False assert row["incoherence_score"] == 0.0 assert row["trust_score"] == 3 assert row["active_validated"] == 1 and row["experience_validated"] == 1 def test_expert_zero_is_integrity_failure(tmp_path: Path) -> None: record = _clean_record() record["skills"] = [{"name": "Rust", "proficiency": "expert", "endorsements": 1, "duration_months": 0}] row = _validate_records(tmp_path, [record]).row(0, named=True) assert row["chk_expert_zero"] is True assert row["validation_failed"] is True # any integrity hit hard-fails def test_career_dates_inverted_is_integrity_failure(tmp_path: Path) -> None: record = _clean_record() record["career_history"][0]["start_date"] = "2023-01-01" record["career_history"][0]["end_date"] = "2020-01-01" row = _validate_records(tmp_path, [record]).row(0, named=True) assert row["chk_career_dates_invalid"] is True and row["validation_failed"] is True def test_impossible_yoe_is_integrity_failure(tmp_path: Path) -> None: record = _clean_record() record["profile"]["years_of_experience"] = 50.0 # vs a ~8yr career span row = _validate_records(tmp_path, [record]).row(0, named=True) assert row["chk_yoe_impossible"] is True and row["validation_failed"] is True def test_salary_incoherence_is_graded_not_hard_fail(tmp_path: Path) -> None: record = _clean_record() record["redrob_signals"]["expected_salary_range_inr_lpa"] = {"min": 30, "max": 10} row = _validate_records(tmp_path, [record]).row(0, named=True) assert row["chk_salary_incoherent"] is True assert row["validation_failed"] is False # graded → penalty, not a hard fail assert abs(row["incoherence_score"] - 0.10) < 1e-6 assert row["salary_range_ok"] == 0 def test_date_order_is_graded(tmp_path: Path) -> None: record = _clean_record() record["redrob_signals"]["signup_date"] = "2024-06-01" record["redrob_signals"]["last_active_date"] = "2024-01-01" row = _validate_records(tmp_path, [record]).row(0, named=True) assert row["chk_date_order_invalid"] is True assert abs(row["incoherence_score"] - 0.15) < 1e-6 assert row["date_order_ok"] == 0 and row["active_validated"] == 0 def test_validate_never_drops_and_emits_every_flag_column(tmp_path: Path) -> None: validated = _validate_records(tmp_path, [_clean_record(), _clean_record()]) assert validated.height == 2 # flag, never drop for flag_column in FLAG_COLUMNS: assert flag_column in validated.columns, f"missing flag column {flag_column}" def test_run_preprocess_returns_frame_and_reference_date(tmp_path: Path) -> None: path = tmp_path / "c.jsonl" records = [_clean_record(), copy.deepcopy(_clean_record())] records[1]["candidate_id"] = "CAND_0000002" path.write_bytes(b"\n".join(orjson.dumps(r) for r in records)) frame, as_of = run_preprocess(path) assert as_of == DATASET_AS_OF assert frame.height == 2 assert "validation_failed" in frame.columns