122 lines
3.7 KiB
Python
122 lines
3.7 KiB
Python
"""Scaffold smoke tests — verify the package is importable and core models are correct.
|
|
|
|
No stage logic, no network calls, no heavy deps beyond pydantic/pydantic-settings.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
|
|
def test_package_version() -> None:
|
|
import jobsource
|
|
|
|
assert isinstance(jobsource.__version__, str)
|
|
assert jobsource.__version__ # non-empty
|
|
|
|
|
|
def test_cli_help_exits_zero() -> None:
|
|
from jobsource.main import build_parser
|
|
|
|
with pytest.raises(SystemExit) as exc_info:
|
|
build_parser().parse_args(["--help"])
|
|
assert exc_info.value.code == 0
|
|
|
|
|
|
def test_cli_parser_flags() -> None:
|
|
from jobsource.main import build_parser
|
|
|
|
parser = build_parser()
|
|
args = parser.parse_args(
|
|
["--batch-size", "10", "--search", "engineer", "--search", "pm",
|
|
"--location", "Remote", "--hours-old", "48"]
|
|
)
|
|
assert args.batch_size == 10
|
|
assert args.search == ["engineer", "pm"]
|
|
assert args.location == "Remote"
|
|
assert args.hours_old == 48
|
|
|
|
|
|
def test_job_status_enum() -> None:
|
|
from jobsource.models import JobStatus
|
|
|
|
assert JobStatus.new == "new"
|
|
assert JobStatus.position_found == "position_found"
|
|
assert JobStatus.needs_review == "needs_review"
|
|
# All six values defined
|
|
assert len(JobStatus) == 6
|
|
|
|
|
|
def test_raw_job_model() -> None:
|
|
from jobsource.models import RawJob
|
|
|
|
job = RawJob(
|
|
job_id="123456789",
|
|
company="Acme Corp",
|
|
linkedin_url="https://www.linkedin.com/jobs/view/123456789",
|
|
)
|
|
assert job.job_id == "123456789"
|
|
assert job.website is None
|
|
|
|
|
|
def test_job_result_from_raw_and_csv_row() -> None:
|
|
from jobsource.models import CSV_COLUMNS, JobResult, JobStatus, RawJob
|
|
|
|
raw = RawJob(
|
|
job_id="987",
|
|
company="Globex",
|
|
linkedin_url="https://www.linkedin.com/jobs/view/987",
|
|
website="https://globex.example.com",
|
|
title="Software Engineer",
|
|
location="Remote",
|
|
)
|
|
result = JobResult.from_raw(raw)
|
|
|
|
assert result.status == JobStatus.new
|
|
assert result.company_name == "Globex"
|
|
assert result.website == "https://globex.example.com"
|
|
assert not result.is_complete
|
|
|
|
row = result.to_csv_row()
|
|
assert set(row.keys()) == set(CSV_COLUMNS)
|
|
assert row["company_name"] == "Globex"
|
|
assert row["career_page_url"] == ""
|
|
assert row["open_position_url"] == ""
|
|
|
|
|
|
def test_job_result_is_complete() -> None:
|
|
from jobsource.models import JobResult, JobStatus
|
|
|
|
result = JobResult(
|
|
job_id="1",
|
|
company_name="Initech",
|
|
status=JobStatus.position_found,
|
|
career_page_url="https://initech.com/careers",
|
|
open_position_url="https://initech.com/careers/jobs/42",
|
|
)
|
|
assert result.is_complete
|
|
row = result.to_csv_row()
|
|
assert row["career_page_url"] == "https://initech.com/careers"
|
|
assert row["open_position_url"] == "https://initech.com/careers/jobs/42"
|
|
|
|
|
|
def test_settings_load_defaults() -> None:
|
|
from jobsource.config import Settings
|
|
|
|
# _env_file=None suppresses .env loading for this instance so we see the
|
|
# coded defaults, not whatever the operator has set in the real .env file.
|
|
s = Settings(_env_file=None)
|
|
assert s.job_source == "jobspy"
|
|
assert s.batch_size == 20
|
|
assert s.hours_old == 72
|
|
# Model IDs must remain as inert placeholders — never real identifiers.
|
|
assert s.classifier_model.startswith("PLACEHOLDER")
|
|
assert s.agent_model.startswith("PLACEHOLDER")
|
|
assert s.llm_api_key.startswith("PLACEHOLDER")
|
|
|
|
|
|
def test_csv_columns_constant() -> None:
|
|
from jobsource.models import CSV_COLUMNS
|
|
|
|
assert CSV_COLUMNS == ("company_name", "career_page_url", "open_position_url")
|
|
assert len(CSV_COLUMNS) == 3
|