216 lines
7.1 KiB
Python
216 lines
7.1 KiB
Python
from pathlib import Path
|
|
|
|
from apps.sources.adapters.ats import (
|
|
GreenhouseAdapter,
|
|
LeverAdapter,
|
|
RecruiteeAdapter,
|
|
SmartRecruitersAdapter,
|
|
WorkableAdapter,
|
|
)
|
|
|
|
|
|
def _load_fixture(name: str) -> str:
|
|
return Path(name).read_text(encoding="utf-8")
|
|
|
|
|
|
def _assert_evidence_fields(job, *, expected_keys):
|
|
evidence_fields = {item.field_name for item in job.evidence}
|
|
assert expected_keys.issubset(evidence_fields)
|
|
|
|
|
|
def test_greenhouse_adapter_listing_extracts_open_jobs_and_skips_closed():
|
|
adapter = GreenhouseAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/greenhouse-listing.json"),
|
|
url="https://boards.greenhouse.io/example",
|
|
)
|
|
|
|
assert result.parser_key == "ats-greenhouse"
|
|
assert len(result.jobs) == 2
|
|
assert {job.external_id for job in result.jobs} == {"gh-open-1", "gh-open-2"}
|
|
assert all("closed" not in result.warnings for _ in [0])
|
|
assert result.confidence >= 0.89
|
|
_assert_evidence_fields(
|
|
result.jobs[0],
|
|
expected_keys={"external_id", "url", "location_text", "date_posted", "employment_types"},
|
|
)
|
|
|
|
|
|
def test_greenhouse_adapter_detail_supports_changed_markup():
|
|
adapter = GreenhouseAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/greenhouse-detail.json"),
|
|
url="https://boards.greenhouse.io/example/jobs/senior-software-engineer",
|
|
)
|
|
|
|
assert len(result.jobs) == 1
|
|
job = result.jobs[0]
|
|
assert job.title == "Senior Software Engineer"
|
|
assert job.external_id == "gh-open-1"
|
|
assert job.url == "https://boards.greenhouse.io/example/jobs/senior-software-engineer"
|
|
assert job.description_html
|
|
_assert_evidence_fields(
|
|
job,
|
|
expected_keys={
|
|
"external_id",
|
|
"url",
|
|
"location_text",
|
|
"date_posted",
|
|
"valid_through",
|
|
"employment_types",
|
|
},
|
|
)
|
|
|
|
|
|
def test_lever_adapter_listing_extracts_open_jobs_and_skips_closed():
|
|
adapter = LeverAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/lever-listing.json"), url="https://jobs.lever.co/example"
|
|
)
|
|
|
|
assert result.parser_key == "ats-lever"
|
|
assert len(result.jobs) == 2
|
|
assert {job.external_id for job in result.jobs} == {"lv-open-1", "lv-open-2"}
|
|
assert result.confidence >= 0.89
|
|
|
|
|
|
def test_lever_adapter_detail_supports_changed_markup():
|
|
adapter = LeverAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/lever-detail.json"),
|
|
url="https://jobs.lever.co/example/platform-engineer",
|
|
)
|
|
|
|
assert len(result.jobs) == 1
|
|
job = result.jobs[0]
|
|
assert job.title == "Platform Engineer"
|
|
assert job.raw["position"]["workplaceType"] == "remote"
|
|
assert "work_type" in job.raw
|
|
assert job.location_text == "Aalst"
|
|
|
|
|
|
def test_lever_adapter_supports_documented_public_postings_api_shape():
|
|
adapter = LeverAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/lever-public-postings.json"),
|
|
url="https://api.lever.co/v0/postings/deliverect?mode=json",
|
|
)
|
|
|
|
assert len(result.jobs) == 1
|
|
job = result.jobs[0]
|
|
assert job.title == "Backend Engineer"
|
|
assert job.url == "https://jobs.lever.co/deliverect/deliverect-open-1"
|
|
assert job.location_text == "Ghent, Flemish Region"
|
|
assert job.employment_types == ["Full-time Permanent"]
|
|
assert job.workplace_type == "hybrid"
|
|
|
|
|
|
def test_recruitee_adapter_listing_extracts_open_jobs_and_skips_closed():
|
|
adapter = RecruiteeAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/recruitee-listing.json"), url="https://acme.recruitee.com/o/"
|
|
)
|
|
|
|
assert result.parser_key == "ats-recruitee"
|
|
assert len(result.jobs) == 2
|
|
assert {job.title for job in result.jobs} == {"System Engineer", "Network Engineer"}
|
|
|
|
|
|
def test_recruitee_adapter_detail_supports_changed_markup():
|
|
adapter = RecruiteeAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/recruitee-detail.json"),
|
|
url="https://acme.recruitee.com/o/system-engineer",
|
|
)
|
|
|
|
assert len(result.jobs) == 1
|
|
job = result.jobs[0]
|
|
assert job.external_id == "rc-open-1"
|
|
assert job.title == "System Engineer"
|
|
assert job.employment_types == ["permanent"]
|
|
|
|
|
|
def test_recruitee_adapter_supports_documented_public_offers_shape():
|
|
adapter = RecruiteeAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/recruitee-public-offers.json"),
|
|
url="https://vito.recruitee.com/api/offers/",
|
|
)
|
|
|
|
assert len(result.jobs) == 1
|
|
job = result.jobs[0]
|
|
assert job.title == "Research Software Engineer"
|
|
assert job.employer_name == "VITO"
|
|
assert job.url == "https://jobs.vito.be/o/research-software-engineer"
|
|
assert job.postal_code == "2400"
|
|
assert job.employment_types == ["fulltime_fixed_term"]
|
|
assert job.workplace_type == "hybrid"
|
|
|
|
|
|
def test_smartrecruiters_adapter_listing_extracts_open_jobs_and_skips_closed():
|
|
adapter = SmartRecruitersAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/smartrecruiters-listing.json"),
|
|
url="https://jobs.smartrecruiters.com/example",
|
|
)
|
|
|
|
assert result.parser_key == "ats-smartrecruiters"
|
|
assert len(result.jobs) == 2
|
|
assert "sr-closed-1" not in {job.external_id for job in result.jobs}
|
|
|
|
|
|
def test_smartrecruiters_adapter_detail_supports_changed_markup():
|
|
adapter = SmartRecruitersAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/smartrecruiters-detail.json"),
|
|
url="https://jobs.smartrecruiters.com/example/security-engineer",
|
|
)
|
|
|
|
assert len(result.jobs) == 1
|
|
job = result.jobs[0]
|
|
assert job.title == "Security Engineer"
|
|
assert job.workplace_type in {"remote", "hybrid", ""}
|
|
|
|
|
|
def test_smartrecruiters_adapter_supports_documented_public_postings_shape():
|
|
adapter = SmartRecruitersAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/smartrecruiters-public-postings.json"),
|
|
url=("https://api.smartrecruiters.com/v1/companies/ARHS/postings?limit=100&country=be"),
|
|
)
|
|
|
|
assert len(result.jobs) == 2
|
|
job = result.jobs[1]
|
|
assert job.title == "Cloud Engineer"
|
|
assert job.employer_name == "ARHS"
|
|
assert job.url == "https://jobs.smartrecruiters.com/ARHS/744000136173889"
|
|
assert job.location_text == "Leuven"
|
|
assert job.country == "be"
|
|
assert job.employment_types == ["Permanent"]
|
|
assert job.workplace_type == "remote"
|
|
|
|
|
|
def test_workable_adapter_listing_extracts_open_jobs_and_skips_closed():
|
|
adapter = WorkableAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/workable-listing.json"),
|
|
url="https://apply.workable.com/example",
|
|
)
|
|
|
|
assert result.parser_key == "ats-workable"
|
|
assert len(result.jobs) == 2
|
|
assert result.jobs[0].title == "Data Engineer"
|
|
|
|
|
|
def test_workable_adapter_detail_supports_changed_markup():
|
|
adapter = WorkableAdapter()
|
|
result = adapter.extract(
|
|
_load_fixture("fixtures/ats/workable-detail.json"),
|
|
url="https://apply.workable.com/example/data-engineer/",
|
|
)
|
|
|
|
assert len(result.jobs) == 1
|
|
job = result.jobs[0]
|
|
assert job.external_id == "wb-open-1"
|
|
assert job.location_text == "Brussel"
|