- Updated README.md to clarify the conditions for `last_applied_treatment` and its integration into the advice JSON structure. - Refactored job.py to utilize a new `TreatmentHistory` class for managing treatment data, improving clarity and efficiency in treatment retrieval. - Enhanced advice_context.py to conditionally include `last_applied_treatment` based on the treatment history, ensuring no redundant queries are made. - Modified products.py to implement logic for excluding active ingredients based on the latest treatment's interval, refining the product prefiltering process. - Updated vector.py to ensure the SQL allowlist is applied correctly, improving the efficiency of product searches. - Added unit tests to validate the new treatment history functionality and product filtering logic.
97 lines
3.6 KiB
Python
97 lines
3.6 KiB
Python
"""Unit tests for TreatmentHistory window slicing and the single 25-day load."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
from datetime import date
|
|
from types import SimpleNamespace
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from pipeline.stages.treatments import TreatmentHistory, load_treatment_history
|
|
|
|
_AS_OF = date(2026, 4, 16)
|
|
_FIELD_ID = 7216
|
|
_SPRAY_DATE = date(2026, 4, 10) # as_of-6
|
|
|
|
|
|
class TreatmentHistorySliceTests(unittest.TestCase):
|
|
def test_latest_picks_newest_day_and_keeps_tank_mix_order(self) -> None:
|
|
history = TreatmentHistory(
|
|
as_of=_AS_OF,
|
|
by_day={
|
|
date(2026, 3, 22): ["OLD"],
|
|
_SPRAY_DATE: ["LIETO", "TWINGO"],
|
|
},
|
|
)
|
|
self.assertEqual(history.latest(), (_SPRAY_DATE, ["LIETO", "TWINGO"]))
|
|
|
|
def test_latest_prefers_a_spray_inside_the_recent_window(self) -> None:
|
|
history = TreatmentHistory(
|
|
as_of=_AS_OF,
|
|
by_day={
|
|
_SPRAY_DATE: ["OLD"],
|
|
_AS_OF: ["TODAY"],
|
|
},
|
|
)
|
|
self.assertEqual(history.latest(), (_AS_OF, ["TODAY"]))
|
|
self.assertEqual(history.latest_before_recent(), (_SPRAY_DATE, ["OLD"]))
|
|
|
|
def test_recent_drops_days_older_than_five(self) -> None:
|
|
history = TreatmentHistory(
|
|
as_of=_AS_OF,
|
|
by_day={
|
|
_SPRAY_DATE: ["OLD"],
|
|
date(2026, 4, 11): ["RECENT"],
|
|
_AS_OF: ["TODAY"],
|
|
},
|
|
)
|
|
self.assertEqual(
|
|
history.recent(),
|
|
{date(2026, 4, 11): ["RECENT"], _AS_OF: ["TODAY"]},
|
|
)
|
|
|
|
def test_latest_before_recent_matches_as_of_minus_25_to_minus_6(self) -> None:
|
|
history = TreatmentHistory(
|
|
as_of=_AS_OF,
|
|
by_day={
|
|
date(2026, 3, 22): ["OLD"],
|
|
_SPRAY_DATE: ["LIETO"],
|
|
date(2026, 4, 11): ["RECENT"],
|
|
},
|
|
)
|
|
self.assertEqual(history.latest_before_recent(), (_SPRAY_DATE, ["LIETO"]))
|
|
|
|
def test_latest_and_latest_before_recent_return_none_when_empty(self) -> None:
|
|
history = TreatmentHistory(as_of=_AS_OF, by_day={})
|
|
self.assertIsNone(history.latest())
|
|
self.assertIsNone(history.latest_before_recent())
|
|
self.assertEqual(history.recent(), {})
|
|
|
|
|
|
class LoadTreatmentHistoryTests(unittest.TestCase):
|
|
def test_queries_as_of_minus_25_through_as_of(self) -> None:
|
|
rows = [
|
|
SimpleNamespace(rilop_date=date(2026, 3, 22), prodgov_name="OLD"),
|
|
SimpleNamespace(rilop_date=_SPRAY_DATE, prodgov_name="LIETO"),
|
|
SimpleNamespace(rilop_date=_SPRAY_DATE, prodgov_name="TWINGO"),
|
|
SimpleNamespace(rilop_date=_SPRAY_DATE, prodgov_name="LIETO"),
|
|
]
|
|
with patch("pipeline.stages.treatments.fetch_all", return_value=rows) as fetch:
|
|
history = load_treatment_history(MagicMock(), _FIELD_ID, _AS_OF)
|
|
params = fetch.call_args[0][2]
|
|
self.assertEqual(params[1], date(2026, 3, 22)) # as_of-25
|
|
self.assertEqual(params[2], _AS_OF)
|
|
self.assertEqual(history.latest(), (_SPRAY_DATE, ["LIETO", "TWINGO"]))
|
|
self.assertEqual(history.latest_before_recent(), (_SPRAY_DATE, ["LIETO", "TWINGO"]))
|
|
self.assertEqual(history.recent(), {})
|
|
|
|
def test_returns_empty_history_when_no_rows(self) -> None:
|
|
with patch("pipeline.stages.treatments.fetch_all", return_value=[]):
|
|
history = load_treatment_history(MagicMock(), _FIELD_ID, _AS_OF)
|
|
self.assertEqual(history.by_day, {})
|
|
self.assertIsNone(history.latest())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|