HTML 82.1%
Python 14.6%
TypeScript 1.9%
CSS 1%
JavaScript 0.5%
1# =============================================================================2# Job·Ka — Groupe KA3# Auteur : Simon-Pierre Boucher4# Contact : contact@spboucher.ai5# Fichier : tests/test_enrich.py6# Rôle : Tests unitaires de l'enrichissement Phase 3 — exigences7# structurées (expérience, scolarité, langues) et séniorité8# Créé : 2026-08-25 Modifié : 2026-08-259# =============================================================================10from jobka.normalize import extract_benefits, extract_requirements, parse_seniority11from jobka.schema import JobPosting121314# --- exigences : années d'expérience ------------------------------------------1516def test_experience_range_fr():17 r = extract_requirements("Comptable", "Détenir 3 à 5 ans d'expérience en comptabilité.")18 assert r["experience_years"] == 3192021def test_experience_plus_en():22 r = extract_requirements("Developer", "5+ years of experience with Python required.")23 assert r["experience_years"] == 5242526def test_experience_minimum_de():27 r = extract_requirements("Technicien", "Expérience minimum de 2 ans dans un poste similaire.")28 assert r["experience_years"] == 2293031def test_experience_absente():32 r = extract_requirements("Cuisinier", "Préparer les plats du menu. Horaire de 35 heures.")33 assert "experience_years" not in r343536def test_experience_bornes():37 # 45 ans d'expérience = non plausible, on ne retient rien38 r = extract_requirements("Poste", "45 ans d'expérience exigée")39 assert "experience_years" not in r404142# --- exigences : scolarité ------------------------------------------------------4344def test_education_dec_avec_contexte():45 r = extract_requirements("Technicien", "Diplôme d'études collégiales (DEC) en informatique requis.")46 assert r["education"] == "DEC"474849def test_education_dec_sans_contexte_ignore():50 # « déc. » = décembre, pas un diplôme : sans contexte scolaire on ignore51 r = extract_requirements("Poste", "Entrée en fonction : déc. 2026. Aucun prérequis.")52 assert "education" not in r535455def test_education_bac():56 r = extract_requirements("Analyste", "Baccalauréat en administration des affaires.")57 assert r["education"] == "baccalauréat"585960def test_education_bachelor_en():61 r = extract_requirements("Analyst", "Bachelor's degree in Computer Science or equivalent.")62 assert r["education"] == "baccalauréat"636465def test_education_plus_bas_exige():66 # « bac ou maîtrise » -> l'exigence minimale est le bac67 r = extract_requirements("Poste", "Baccalauréat ou maîtrise en génie exigé.")68 assert r["education"] == "baccalauréat"697071def test_education_dep():72 r = extract_requirements("Mécanicien", "Détenir un DEP en mécanique automobile.")73 assert r["education"] == "DEP"747576# --- exigences : langues --------------------------------------------------------7778def test_langues_bilingue():79 r = extract_requirements("Poste", "Le candidat doit être bilingue (français/anglais).")80 assert r["languages"] == ["français", "anglais"]818283def test_langues_anglais_requis():84 r = extract_requirements("Poste", "Anglais fonctionnel requis pour ce poste.")85 assert r["languages"] == ["anglais"]868788def test_langues_fluent_english():89 r = extract_requirements("Role", "Fluent in English; French is an asset.")90 assert "anglais" in r["languages"]919293def test_langues_aucune_mention():94 r = extract_requirements("Poste", "Assembler des pièces sur la chaîne de production.")95 assert "languages" not in r969798# --- séniorité -------------------------------------------------------------------99100def test_seniority_titre_senior():101 assert parse_seniority("Développeur senior") == "senior"102103104def test_seniority_titre_junior():105 assert parse_seniority("Analyste junior") == "junior"106107108def test_seniority_titre_direction():109 assert parse_seniority("Directeur des finances") == "direction"110111112def test_seniority_stage_par_type():113 assert parse_seniority("Analyste TI", None, "stage") == "stage"114115116def test_seniority_label_ats():117 assert parse_seniority("Ingénieur", {"experience": "Mid-Senior Level"}) == "senior"118 assert parse_seniority("Ingénieur", {"experience": "Entry level"}) == "junior"119120121def test_seniority_annees_experience():122 assert parse_seniority("Comptable", {"experience_years": 1}) == "junior"123 assert parse_seniority("Comptable", {"experience_years": 4}) == "intermediaire"124 assert parse_seniority("Comptable", {"experience_years": 8}) == "senior"125126127def test_seniority_aucun_signal():128 assert parse_seniority("Préposé à l'entretien") is None129130131def test_seniority_not_applicable_ignore():132 assert parse_seniority("Poste", {"experience": "Not Applicable"}) is None133134135# --- avantages : en-têtes élargis -------------------------------------------------136137def test_benefits_ce_quon_offre():138 desc = ("Ce que nous vous offrons\n• Assurances collectives\n"139 "• REER avec cotisation de l'employeur\n• 4 semaines de vacances\n")140 assert len(extract_benefits(desc)) == 3141142143def test_benefits_whats_in_it_for_you():144 desc = ("What's in it for you\n- Health insurance\n- RRSP matching\n\nApply now.")145 assert extract_benefits(desc) == ["Health insurance", "RRSP matching"]146147148# --- intégration finalize() --------------------------------------------------------149150def test_finalize_remplit_exigences_et_seniorite():151 job = JobPosting(152 source="test", external_id="1", url="https://example.com/1",153 employer="Exemple inc.", title="Développeur senior",154 description=("Baccalauréat en informatique et 5 ans d'expérience "155 "exigés. Le candidat doit être bilingue."),156 ).finalize()157 assert job.requirements["experience_years"] == 5158 assert job.requirements["education"] == "baccalauréat"159 assert job.requirements["languages"] == ["français", "anglais"]160 assert job.seniority == "senior"161162163def test_finalize_ne_touche_pas_valeurs_ats():164 job = JobPosting(165 source="test", external_id="2", url="https://example.com/2",166 employer="Exemple inc.", title="Analyste",167 description="2 ans d'expérience demandés.",168 requirements={"experience_years": 7},169 seniority="junior",170 ).finalize()171 assert job.requirements["experience_years"] == 7 # valeur ATS conservée172 assert job.seniority == "junior"173