"""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