Files
site/WESP_REL/tests/test_daily_plan_ingredient_weights.py
T
2026-07-17 12:57:18 +03:00

125 lines
5.0 KiB
Python

"""Unit-тесты пересчёта весов при замене компонента в плане."""
from __future__ import annotations
import unittest
from app.models import Component, Ingredient, Recipe
from app.services.daily_plan.ingredient_weights import resolve_plan_ingredient_weights
class PlanIngredientWeightsTests(unittest.TestCase):
def _make(self, *, locked: bool, wph: float, dm_pct: float, repl_dm: float, dm_ph=None):
recipe = Recipe(id="r1", name="R", dry_matter_locked=locked, content_hash="")
ing = Ingredient(
id="i1",
name="Ing",
weight_per_head=wph,
amount=0.0,
dry_matter=dm_pct,
dry_matter_per_head=dm_ph,
order=1,
recipe_id="r1",
component_id="c1",
created_by="system",
updated_by="system",
)
components = {
"c1": Component(id="c1", name="A", type="grain", dry_matter=dm_pct),
"c2": Component(id="c2", name="B", type="silage", dry_matter=repl_dm),
}
return ing, recipe, components
def test_weight_mode_keeps_kg_per_head(self) -> None:
ing, recipe, components = self._make(locked=False, wph=2.0, dm_pct=55.0, repl_dm=35.0)
out = resolve_plan_ingredient_weights(
ing, recipe, heads=10, components_by_id=components, replacement_component_id="c2"
)
self.assertEqual(out["recalculationMode"], "weight")
self.assertEqual(out["weightPerHead"], 2.0)
self.assertEqual(out["totalKg"], 20.0)
self.assertEqual(out["dryMatterPct"], 35.0)
self.assertAlmostEqual(out["dryMatterPerHead"], 0.7, places=4)
def test_dry_matter_mode_keeps_dm_per_head(self) -> None:
ing, recipe, components = self._make(
locked=True, wph=1.0, dm_pct=55.0, repl_dm=35.0, dm_ph=0.55
)
out = resolve_plan_ingredient_weights(
ing, recipe, heads=20, components_by_id=components, replacement_component_id="c2"
)
self.assertEqual(out["recalculationMode"], "dry_matter")
self.assertAlmostEqual(out["weightPerHead"], 1.57, places=2)
self.assertAlmostEqual(out["totalKg"], 31.4, places=1)
self.assertAlmostEqual(out["dryMatterPerHead"], 0.55, places=4)
def test_dry_matter_pct_adjustment_locked(self) -> None:
ing, recipe, components = self._make(
locked=True, wph=1.0, dm_pct=55.0, repl_dm=35.0, dm_ph=0.55
)
out = resolve_plan_ingredient_weights(
ing,
recipe,
heads=10,
components_by_id=components,
component_adjustment={
"dry_matter": 40.0,
"dry_matter_locked": True,
"weight_per_head": None,
"dry_matter_per_head": None,
},
)
self.assertTrue(out["adjustedToday"])
self.assertEqual(out["dryMatterPct"], 40.0)
self.assertAlmostEqual(out["dryMatterPerHead"], 0.55, places=4)
self.assertAlmostEqual(out["weightPerHead"], 1.38, places=2)
def test_dry_matter_pct_adjustment(self) -> None:
ing, recipe, components = self._make(locked=False, wph=2.0, dm_pct=55.0, repl_dm=35.0)
out = resolve_plan_ingredient_weights(
ing,
recipe,
heads=10,
components_by_id=components,
component_adjustment={"dry_matter": 40.0, "weight_per_head": None, "dry_matter_per_head": None},
)
self.assertTrue(out["adjustedToday"])
self.assertEqual(out["weightPerHead"], 2.0)
self.assertEqual(out["dryMatterPct"], 40.0)
self.assertAlmostEqual(out["dryMatterPerHead"], 0.8, places=4)
self.assertEqual(out["originalWeightPerHead"], 2.0)
self.assertEqual(out["originalDryMatterPct"], 55.0)
def test_weight_mode_adjustment(self) -> None:
ing, recipe, components = self._make(locked=False, wph=2.0, dm_pct=55.0, repl_dm=35.0)
out = resolve_plan_ingredient_weights(
ing,
recipe,
heads=10,
components_by_id=components,
component_adjustment={"weight_per_head": 3.0, "dry_matter_per_head": None},
)
self.assertTrue(out["adjustedToday"])
self.assertEqual(out["weightPerHead"], 3.0)
self.assertAlmostEqual(out["dryMatterPerHead"], 1.65, places=4)
self.assertEqual(out["originalWeightPerHead"], 2.0)
def test_dry_matter_mode_adjustment(self) -> None:
ing, recipe, components = self._make(
locked=True, wph=1.0, dm_pct=55.0, repl_dm=35.0, dm_ph=0.55
)
out = resolve_plan_ingredient_weights(
ing,
recipe,
heads=20,
components_by_id=components,
component_adjustment={"weight_per_head": None, "dry_matter_per_head": 0.7},
)
self.assertTrue(out["adjustedToday"])
self.assertAlmostEqual(out["dryMatterPerHead"], 0.7, places=4)
self.assertAlmostEqual(out["weightPerHead"], 1.27, places=2)
if __name__ == "__main__":
unittest.main()