"""Unit-тесты daily_plan/skips.py и фильтрации builder.""" from __future__ import annotations import unittest from app import create_app, db from app.services.daily_plan.builder import build_daily_plan from app.services.daily_plan.skips import ( get_skipped_recipe_ids, list_skips, skip_trip, unskip_trip, ) from app.services.setup_state import mark_setup_complete from tests.helpers.dispenser_recipe_fixtures import ( E2E_DISP_ID, E2E_DISP_RECIPE_1, E2E_PERIOD_A, seed_dispenser_period_recipes, ) from tests.helpers.zootech_test_helpers import ZootechTestConfig class DailyTripSkipServiceTests(unittest.TestCase): def setUp(self) -> None: self.app = create_app(ZootechTestConfig) self.ctx = self.app.app_context() self.ctx.push() db.create_all() mark_setup_complete(self.app) seed_dispenser_period_recipes() def tearDown(self) -> None: db.session.remove() db.drop_all() self.ctx.pop() def test_skip_and_unskip_trip(self) -> None: plan_date = "2026-06-07" row = skip_trip(E2E_DISP_RECIPE_1, plan_date, user="zootech") self.assertEqual(row.recipe_id, E2E_DISP_RECIPE_1) self.assertEqual(row.plan_date.isoformat(), plan_date) self.assertIn(E2E_DISP_RECIPE_1, get_skipped_recipe_ids(plan_date)) self.assertEqual(len(list_skips(plan_date)), 1) self.assertTrue(unskip_trip(E2E_DISP_RECIPE_1, plan_date)) self.assertNotIn(E2E_DISP_RECIPE_1, get_skipped_recipe_ids(plan_date)) def test_skip_is_idempotent(self) -> None: plan_date = "2026-06-08" first = skip_trip(E2E_DISP_RECIPE_1, plan_date) second = skip_trip(E2E_DISP_RECIPE_1, plan_date) self.assertEqual(first.id, second.id) self.assertEqual(len(list_skips(plan_date)), 1) def test_builder_excludes_skipped_trips(self) -> None: plan_date = "2026-06-09" skip_trip(E2E_DISP_RECIPE_1, plan_date) plan = build_daily_plan(dispenser_id=E2E_DISP_ID, plan_date=plan_date) morning = next(p for p in plan["periods"] if p["id"] == E2E_PERIOD_A) recipe_ids = {t["recipeId"] for t in morning["trips"]} self.assertNotIn(E2E_DISP_RECIPE_1, recipe_ids) skipped = plan["skippedTrips"] self.assertEqual(len(skipped), 1) self.assertEqual(skipped[0]["recipeId"], E2E_DISP_RECIPE_1) totals = {row["name"]: row["totalKg"] for row in plan["ingredientTotals"]} self.assertNotIn("Ing 1", totals) def test_skip_unknown_recipe_raises(self) -> None: with self.assertRaises(LookupError): skip_trip("missing-recipe", "2026-06-07") if __name__ == "__main__": unittest.main()