Интегрирован wesp в сайт
CI / quality (push) Canceled after 0s

This commit is contained in:
влад
2026-07-17 12:57:18 +03:00
parent 5dfa06ddbe
commit 355c0ef9f1
883 changed files with 194576 additions and 177 deletions
@@ -0,0 +1,145 @@
"""Замена компонентов в плане на день."""
from __future__ import annotations
import unittest
from app import create_app, db
from app.models import Component
from app.services.daily_plan.builder import build_daily_plan
from app.services.daily_plan.replacements import replace_ingredient
from app.services.setup_state import mark_setup_complete
from tests.helpers.dispenser_recipe_fixtures import (
E2E_DISP_COMP,
E2E_DISP_ID,
E2E_DISP_RECIPE_1,
seed_dispenser_period_recipes,
)
from tests.helpers.zootech_test_helpers import ZootechTestConfig
class DailyPlanReplacementTests(unittest.TestCase):
def setUp(self) -> None:
self.app = create_app(ZootechTestConfig)
self.client = self.app.test_client()
self.ctx = self.app.app_context()
self.ctx.push()
db.create_all()
mark_setup_complete(self.app)
seed_dispenser_period_recipes()
self.client.post(
"/api/auth/login",
json={"login": "zootech-test-admin", "password": "zootech-test-secret"},
)
alt = Component(
id="e2e-disp-comp-alt",
name="Alt Silo",
type="silage",
dry_matter=35.0,
protein=3.0,
energy=6.0,
price=0.0,
)
db.session.add(alt)
db.session.commit()
def tearDown(self) -> None:
db.session.remove()
db.drop_all()
self.ctx.pop()
def test_replace_ingredient_shows_in_plan_and_totals(self) -> None:
replace_ingredient(
E2E_DISP_RECIPE_1,
"e2e-disp-ing-1",
"e2e-disp-comp-alt",
"2026-06-07",
)
plan = build_daily_plan(dispenser_id=E2E_DISP_ID, plan_date="2026-06-07")
trip = plan["periods"][0]["trips"][0]
ing = trip["ingredients"][0]
self.assertTrue(ing["replacedToday"])
self.assertIn("Alt Silo", ing["name"])
totals = {row["name"]: row["totalKg"] for row in plan["ingredientTotals"]}
self.assertEqual(totals["Alt Silo"], 20.0)
self.assertEqual(plan["ingredientGrandTotalKg"], 50.0)
def test_replace_recalculates_by_dry_matter_when_locked(self) -> None:
from app.models import Recipe
recipe = db.session.get(Recipe, E2E_DISP_RECIPE_1)
recipe.dry_matter_locked = True
db.session.commit()
replace_ingredient(
E2E_DISP_RECIPE_1,
"e2e-disp-ing-1",
"e2e-disp-comp-alt",
"2026-06-07",
)
plan = build_daily_plan(dispenser_id=E2E_DISP_ID, plan_date="2026-06-07")
ing = plan["periods"][0]["trips"][0]["ingredients"][0]
self.assertEqual(ing["recalculationMode"], "dry_matter")
self.assertAlmostEqual(ing["weightPerHead"], 1.57, places=2)
self.assertAlmostEqual(ing["totalKg"], 31.4, places=1)
totals = {row["name"]: row["totalKg"] for row in plan["ingredientTotals"]}
self.assertAlmostEqual(totals["Alt Silo"], 31.4, places=1)
self.assertAlmostEqual(plan["ingredientGrandTotalKg"], 61.4, places=1)
def test_component_alternatives_api(self) -> None:
resp = self.client.get(
f"/api/daily-plan/component-alternatives?component_id={E2E_DISP_COMP}"
)
self.assertEqual(resp.status_code, 200, resp.get_data(as_text=True))
body = resp.get_json()
self.assertIn("similar", body)
self.assertIn("results", body)
self.assertTrue(body["results"])
def test_replace_component_in_all_plan_recipes(self) -> None:
created = self.client.post(
"/api/daily-plan/replacements/components",
json={
"componentId": E2E_DISP_COMP,
"replacementComponentId": "e2e-disp-comp-alt",
"dispenserId": E2E_DISP_ID,
"date": "2026-06-09",
},
)
self.assertEqual(created.status_code, 200, created.get_data(as_text=True))
body = created.get_json()
self.assertEqual(body.get("count"), 2)
plan = build_daily_plan(dispenser_id=E2E_DISP_ID, plan_date="2026-06-09")
replaced = 0
for period in plan["periods"]:
for trip in period["trips"]:
for ing in trip["ingredients"]:
if ing.get("originalComponentId") == E2E_DISP_COMP:
self.assertTrue(ing["replacedToday"])
self.assertIn("Alt Silo", ing["name"])
replaced += 1
self.assertEqual(replaced, 2)
def test_post_and_delete_replacement(self) -> None:
created = self.client.post(
"/api/daily-plan/replacements/ingredients",
json={
"recipeId": E2E_DISP_RECIPE_1,
"ingredientId": "e2e-disp-ing-1",
"replacementComponentId": "e2e-disp-comp-alt",
"date": "2026-06-08",
},
)
self.assertEqual(created.status_code, 200, created.get_data(as_text=True))
listed = self.client.get("/api/notifications?category=daily_plan").get_json()
self.assertTrue(any("" in x.get("title", "") for x in listed["items"]))
deleted = self.client.delete(
"/api/daily-plan/replacements/ingredients"
f"?recipe_id={E2E_DISP_RECIPE_1}&ingredient_id=e2e-disp-ing-1&date=2026-06-08"
)
self.assertEqual(deleted.status_code, 200)
listed2 = self.client.get("/api/notifications?category=daily_plan").get_json()
self.assertTrue(any("снова в плане" in x.get("title", "") for x in listed2["items"]))
if __name__ == "__main__":
unittest.main()