job-research/tests/apec/test_normalize.py
2026-06-05 12:58:56 +02:00

253 lines
7.8 KiB
Python

from job_research.apec.normalize import normalize_apec_listing
def test_normalize_apec_listing_extracts_minimal_shape() -> None:
html = """
<html>
<body>
<main class="container-details-offer">
<h1>Data Engineer F/H</h1>
<div class="card-offer">
<div class="ref-offre">Ref. Apec : 178554452W</div>
<ul class="details-offer-list mb-20">
<li>CLOUD TEMPLE</li>
<li>1 <span> CDI </span></li>
<li>Puteaux - 92</li>
</ul>
<p>Publiée le 20/04/2026 Actualisée le 02/06/2026</p>
</div>
<article class="card card-ents mb-20">
<div class="list-hzt mb-20">
<span class="ents-name">CLOUD TEMPLE</span>
</div>
</article>
<div class="details-post">
<h4>Salaire</h4>
<span>A partir de 70 k€ brut annuel</span>
</div>
<div class="details-post">
<h4>Prise de poste</h4>
<span>Dès que possible</span>
</div>
<div class="details-post">
<h4>Expérience</h4>
<span>Minimum 7 ans</span>
</div>
<div class="details-post">
<h4>Descriptif du poste</h4>
<p>Build pipelines</p>
<div class="nested-late-sections">
<h4>Profil recherché</h4>
<p>Python / SQL</p>
<h4>Compétences attendues</h4>
<p>Ignored</p>
<h4>Entreprise</h4>
<p>Ignored</p>
<div class="recruiter">Ignored recruiter info</div>
</div>
</div>
</main>
</body>
</html>
"""
listing = normalize_apec_listing(
url="https://example.test/job/123",
html=html,
fetched_at="2026-06-01T10:00:00Z",
source_job_id="job-123",
)
assert listing.source == "apec"
assert listing.source_job_id == "job-123"
assert listing.url == "https://example.test/job/123"
assert listing.title == "Data Engineer F/H"
assert listing.company == "CLOUD TEMPLE"
assert listing.location == "Puteaux - 92"
assert listing.contract_type == "CDI"
assert listing.description_text == "Build pipelines"
assert listing.published_at == "2026-04-20"
assert listing.refreshed_at == "2026-06-02"
assert listing.fetched_at == "2026-06-01T10:00:00Z"
def test_normalize_apec_listing_uses_details_offer_list_company_fallback() -> None:
html = """
<html>
<body>
<main class="container-details-offer">
<h1>Data Engineer F/H</h1>
<div class="card-offer">
<div class="ref-offre">Ref. Apec : 178554452W</div>
<ul class="details-offer-list mb-20">
<li>Fallback Company</li>
<li>1 <span> CDI </span></li>
<li>Puteaux - 92</li>
</ul>
<p>Publiée le 20/04/2026 Actualisée le 02/06/2026</p>
</div>
<div class="details-post">
<h4>Salaire</h4>
<span>A partir de 70 k€ brut annuel</span>
</div>
<div class="details-post">
<h4>Prise de poste</h4>
<span>Dès que possible</span>
</div>
<div class="details-post">
<h4>Expérience</h4>
<span>Minimum 7 ans</span>
</div>
<div class="details-post">
<h4>Descriptif du poste</h4>
<p>Build pipelines</p>
<div class="nested-late-sections">
<h4>Profil recherché</h4>
<p>Python / SQL</p>
<h4>Compétences attendues</h4>
<p>Ignored</p>
<h4>Entreprise</h4>
<p>Ignored</p>
<div class="recruiter">Ignored recruiter info</div>
</div>
</div>
</main>
</body>
</html>
"""
listing = normalize_apec_listing(
url="https://example.test/job/123",
html=html,
fetched_at="2026-06-01T10:00:00Z",
source_job_id=None,
)
assert listing.company == "Fallback Company"
assert listing.description_text == "Build pipelines"
assert listing.refreshed_at == "2026-06-02"
def test_normalize_apec_listing_records_warnings_for_fallback_and_missing_fields() -> None:
html = """
<html>
<body>
<main class="container-details-offer">
<div class="card-offer">
<div class="ref-offre">Ref. Apec : 178554452W</div>
<ul class="details-offer-list mb-20">
<li>Fallback Company</li>
<li>1 CDI</li>
</ul>
</div>
<article class="card card-ents mb-20">
<div class="list-hzt mb-20">
<span class="card-ents-quote">Fallback Company</span>
</div>
</article>
</main>
<h1>Fallback Title</h1>
</body>
</html>
"""
listing = normalize_apec_listing(
url="https://example.test/job/123",
html=html,
fetched_at="2026-06-01T10:00:00Z",
source_job_id=None,
)
assert [warning.field for warning in listing.warnings] == [
"title",
"location",
"contract_type",
"description_text",
"source_job_id",
"company",
"published_at",
]
def test_normalize_apec_listing_records_warnings_for_placeholder_text_values() -> None:
html = """
<html>
<body>
<main class="container-details-offer">
<h1> N/A </h1>
<div class="card-offer">
<div class="ref-offre">Ref. Apec : 178554452W</div>
<ul class="details-offer-list mb-20">
<li>Example Corp</li>
<li>1 <span> N/A </span></li>
<li> - </li>
</ul>
<p>Publiée le 20/04/2026 Actualisée le 02/06/2026</p>
</div>
<article class="card card-ents mb-20">
<div class="list-hzt mb-20">
<span class="ents-name">Example Corp</span>
</div>
</article>
<div class="details-post">
<h4>Descriptif du poste</h4>
<p>Build pipelines</p>
</div>
</main>
</body>
</html>
"""
listing = normalize_apec_listing(
url="https://example.test/job/123",
html=html,
fetched_at="2026-06-01T10:00:00Z",
source_job_id="178554452W",
)
assert listing.title is None
assert listing.location is None
assert listing.contract_type is None
assert [warning.field for warning in listing.warnings] == ["title", "location", "contract_type"]
def test_normalize_apec_listing_records_warning_for_placeholder_company() -> None:
html = """
<html>
<body>
<main class="container-details-offer">
<h1>Data Engineer F/H</h1>
<div class="card-offer">
<div class="ref-offre">Ref. Apec : 178554452W</div>
<ul class="details-offer-list mb-20">
<li>Example Corp</li>
<li>1 <span> CDI </span></li>
<li>Puteaux - 92</li>
</ul>
<p>Publiée le 20/04/2026 Actualisée le 02/06/2026</p>
</div>
<article class="card card-ents mb-20">
<div class="list-hzt mb-20">
<span class="ents-name">N/A</span>
</div>
</article>
<div class="details-post">
<h4>Descriptif du poste</h4>
<p>Build pipelines</p>
</div>
</main>
</body>
</html>
"""
listing = normalize_apec_listing(
url="https://example.test/job/123",
html=html,
fetched_at="2026-06-01T10:00:00Z",
source_job_id="178554452W",
)
assert listing.company is None
assert listing.refreshed_at == "2026-06-02"
assert [warning.field for warning in listing.warnings] == ["company"]