"""Small regression cases from the follow-up review; no network or production writes.""" from __future__ import annotations import contextlib import copy import io import json from pathlib import Path import sys import tempfile import unittest from argparse import Namespace from unittest.mock import patch ROOT = Path(__file__).resolve().parents[1] sys.path[:0] = [str(ROOT / "resume_builder/helpers"), str(ROOT / "job_scout")] import application_records as records import application_tracker as tracker import package_manifest as manifest import page_metrics import scout import validate_resume_system as validator class ScannerRegressionTests(unittest.TestCase): def scan(self, body): with tempfile.TemporaryDirectory() as directory: path = Path(directory) / "resume.tex" path.write_text("dennis@thiessen.io +41 795 955 585\n" + body, encoding="utf-8") return validator.scan_document(path, validator.load_json(validator.CLAIMS_PATH)) def test_context_cannot_be_borrowed_or_confused_with_model_training(self): for body in ("Implemented production model training in PyTorch.", "Coursera certification: PyTorch. Built production models in PyTorch.", r"\skillline{Certificate}{Coursera, PyTorch}\skillline{Production}{PyTorch}"): with self.subTest(body=body): self.assertTrue(self.scan(body)) self.assertEqual([], self.scan("IBM AI Engineering certificate: PyTorch.")) def test_inline_markup_and_unrelated_negation_do_not_hide_claims(self): for body in (r"Built Lang\textbf{Chain} services.", "Delivered services without downtime using Terraform."): with self.subTest(body=body): self.assertTrue(self.scan(body)) self.assertEqual([], self.scan("I have no Terraform experience.")) def test_employer_name_is_not_a_skill_but_later_claim_still_is(self): self.assertEqual([], self.scan("Application to Snowflake for Senior Software Engineer.")) self.assertTrue(self.scan("Application to Snowflake. Built Snowflake pipelines.")) def test_missing_identity_invalid_period_and_empty_evidence_report_errors(self): original = validator.load_json(validator.CLAIMS_PATH) history = validator.load_json(validator.HISTORY_PATH) data = copy.deepcopy(original) data.pop("identity") self.assertTrue(validator.canonical_checks(data, history)[0]) data = copy.deepcopy(original) data["employment"][0]["start"] = "2035-99" data["claims"][0]["evidence"] = {"source": "missing/file.pdf"} errors = validator.canonical_checks(data, history)[0] for phrase in ("invalid start", "ownership", "does not exist"): self.assertTrue(any(phrase in error for error in errors), errors) class ScoutRegressionTests(unittest.TestCase): def test_explicit_country_and_exclusion_override_town_name(self): for location in ("Freiburg, Germany", "Baden, Austria", "Kastellaun, Germany", "Remote - Switzerland excluded"): with self.subTest(location=location): self.assertFalse(scout.location_eligibility(location)[0]) self.assertTrue(scout.location_eligibility("Baar")[0]) self.assertTrue(scout.location_eligibility("Wetzikon", country="CH")[0]) self.assertTrue(scout.location_eligibility("Aarhus, Denmark")[0]) self.assertTrue(scout.location_eligibility("Oslo, Norway", policy="norway_only")[0]) def test_smartrecruiters_preserves_country_through_matching(self): payload = {"content": [{"id": "1", "name": "Data Engineer", "location": {"city": "Wetzikon", "country": "CH"}}], "totalFound": 1} with patch.object(scout, "http_get_json", return_value=payload): jobs = scout.fetch_smartrecruiters({"company": "example"}) rows, _, _ = scout._process_company("example", "Example", {}, jobs, {}, "2026-09-11", {}) self.assertEqual(1, len(rows)) def test_related_requisition_stays_visible_when_hiding_decided(self): old = "https://jobs.ruag.ch/offene-stellen/data-engineer/11111111-1111-1111-1111-111111111111" new = "https://jobs.ruag.ch/offene-stellen/data-engineer/22222222-2222-2222-2222-222222222222" decisions = {old: {"decision": "skip", "date": "2026-09-01"}} row = dict(company="RUAG", title="Data Engineer", location="Thun", url=new, score=3, pos=[], neg=[], in_ch=True, remote=False, relocation=False, is_new=True, posted="") with tempfile.TemporaryDirectory() as directory, patch.object(scout, "_raw_decisions", return_value=decisions): path = Path(directory) / "report.md" scout.write_report(path, [row], [], False, True, decisions=scout.index_decisions(decisions), hide_decided=True) text = path.read_text(encoding="utf-8") self.assertIn(new, text) self.assertIn("RELATED", text) def test_new_only_commits_delivered_results_and_preserves_other_companies(self): job = dict(id="1", title="Data Engineer", location="Bern", url="https://example.com/1") with tempfile.TemporaryDirectory() as directory, contextlib.ExitStack() as stack: for name, value in {"ROOT": Path(directory), "REPORTS_DIR": Path(directory)/"reports", "COMPANIES": [("example", "Example", "fake", {})]}.items(): stack.enter_context(patch.object(scout, name, value)) stack.enter_context(patch.object(scout, "load_seen", return_value={"other": {"old": {"title": "Untouched"}}})) for name in ("load_decisions", "load_last_scrape"): stack.enter_context(patch.object(scout, name, return_value={})) stack.enter_context(patch.object(scout, "save_last_scrape")) saved = stack.enter_context(patch.object(scout, "save_seen")) stack.enter_context(patch.object(scout, "_close_browser")) stack.enter_context(patch.object(scout, "_fetch_company", return_value=("example", "Example", "fake", {}, [job], None, 0.0))) stack.enter_context(patch.object(sys, "argv", ["scout.py", "--new-only"])) stack.enter_context(contextlib.redirect_stdout(io.StringIO())) stack.enter_context(contextlib.redirect_stderr(io.StringIO())) scout.main() state = saved.call_args.args[0] self.assertIn("1", state["example"]) self.assertIn("old", state["other"]) def test_concurrent_scout_writer_is_rejected(self): with tempfile.TemporaryDirectory() as directory, patch.object(scout, "ROOT", Path(directory)): with scout.writer_lock(): with self.assertRaises(SystemExit), scout.writer_lock(): pass self.assertFalse((Path(directory)/"state/scout.lock").exists()) class ArtifactRegressionTests(unittest.TestCase): def test_manifest_detects_contents_but_allows_missing_local_pdf(self): with tempfile.TemporaryDirectory() as directory: root = Path(directory) folder = root / "example" folder.mkdir() source = folder/"resume.tex" source.write_text("\\documentclass{article}\nOriginal", encoding="utf-8") pdf = folder/"resume.pdf" pdf.write_bytes(b"first PDF") recorded = {"packages": {"example": manifest.describe(folder, record_pdfs=True)}} current = {"packages": {"example": manifest.describe(folder)}} self.assertEqual([], manifest.check_manifest(recorded, current, root)) pdf.unlink() self.assertEqual([], manifest.check_manifest(recorded, current, root)) pdf.write_bytes(b"changed PDF") self.assertTrue(manifest.check_manifest(recorded, current, root)) source.write_text("\\documentclass{article}\nChanged claims", encoding="utf-8") self.assertNotEqual(current["packages"]["example"], manifest.describe(folder)) def test_page_metric_matches_heading_not_summary_word(self): def bbox(args, **kwargs): Path(args[-1]).write_text('' 'Ten' 'experience' 'Professional' 'Experience') with patch.object(page_metrics.shutil, "which", return_value="pdftotext"), patch.object(page_metrics.subprocess, "run", side_effect=bbox): self.assertEqual(49.9, page_metrics.measure(Path("unused.pdf"))["experience_pct"]) def test_older_imported_event_cannot_reopen_withdrawn_application(self): data = records.load() row = next(row for row in data["applications"] if row["company"] == "SBB") args = Namespace(id=row["id"], date="2026-09-10", event=None, outcome="applied", note="older event", next_action=None) with self.assertRaises(ValueError): tracker.update_application(data, args)