"""Unit tests for database-driven worklist discovery.""" from __future__ import annotations import unittest from pathlib import Path from types import SimpleNamespace from unittest.mock import patch from pipeline.config import WorklistSettings from pipeline.vocab import load_crop_vocab, load_disease_vocab from pipeline.worklist import build_jobs _ROOT = Path(__file__).resolve().parent.parent _CROP_VOCAB = load_crop_vocab(_ROOT / "vocab" / "crops.yaml") _DISEASE_VOCAB = load_disease_vocab(_ROOT / "vocab" / "diseases.yaml") def _row(**overrides: object) -> SimpleNamespace: fields = { "cmplay_id": 4012, "cmplay_colture": 1, "cmplay_imp": 3, "cmplay_station": 7, "colture_name": "Vite", "anmod_id": 10, "anmod_model": "PERONOSPORA", } fields.update(overrides) return SimpleNamespace(**fields) def _build(rows: list[SimpleNamespace], allowlist: tuple[int, ...] = ()) -> tuple[list, str]: worklist = WorklistSettings(field_allowlist=allowlist) with patch("pipeline.worklist.fetch_all", return_value=rows) as fetch: jobs = build_jobs(object(), worklist, _CROP_VOCAB, _DISEASE_VOCAB) sql = fetch.call_args.args[1] return jobs, sql class BuildJobsTests(unittest.TestCase): def test_peronospora_on_grapevine_becomes_one_job(self) -> None: jobs, sql = _build([_row()]) self.assertEqual(len(jobs), 1) job = jobs[0] self.assertEqual(job.field_id, 4012) self.assertEqual(job.model_name, "PERONOSPORA") self.assertEqual(job.disease_english, "downy mildew") self.assertEqual(job.crop_english, "grapevine") self.assertEqual(job.crop_italian, "Vite") self.assertTrue(job.organic) self.assertEqual(job.station, 7) self.assertEqual(job.anmod_id, 10) self.assertIn("pat_mod_AI_model = 1", sql) self.assertIn("anmod_AI_advice = 1", sql) self.assertIn("anmod_cmplay", sql) def test_allowlist_drops_other_field_ids(self) -> None: jobs, _sql = _build( [_row(cmplay_id=4012), _row(cmplay_id=4085, anmod_id=11)], allowlist=(4085,), ) self.assertEqual([job.field_id for job in jobs], [4085]) def test_unmapped_disease_and_colture_are_skipped(self) -> None: jobs, _sql = _build([ _row(), _row(anmod_id=11, anmod_model="NOT_A_DISEASE"), _row(cmplay_id=4085, anmod_id=12, colture_name="Not A Crop"), ]) self.assertEqual([(job.field_id, job.anmod_id) for job in jobs], [(4012, 10)]) def test_blank_and_null_colture_are_skipped(self) -> None: jobs, _sql = _build([ _row(cmplay_id=1, anmod_id=1, colture_name=""), _row(cmplay_id=2, anmod_id=2, colture_name=None), _row(cmplay_id=3, anmod_id=3), ]) self.assertEqual([job.field_id for job in jobs], [3]) def test_same_english_disease_keeps_distinct_anmod_rows(self) -> None: jobs, _sql = _build([ _row(anmod_id=20, anmod_model="PERONOSPORA"), _row(anmod_id=11, anmod_model="Peronospora"), ]) self.assertEqual( [(job.anmod_id, job.model_name, job.disease_english) for job in jobs], [ (20, "PERONOSPORA", "downy mildew"), (11, "Peronospora", "downy mildew"), ], ) def test_imp_other_than_3_is_not_organic(self) -> None: jobs, _sql = _build([_row(cmplay_imp=1, cmplay_station=None)]) self.assertFalse(jobs[0].organic) self.assertIsNone(jobs[0].station) if __name__ == "__main__": unittest.main()