"""Golden path: seed → recalculate → diff → apply_from_master.""" from __future__ import annotations import json import unittest from app import create_app, db from app.lab.services.component_nutrients import upsert_from_api_dict from app.models import Component, Ingredient, Recipe from app.models.base import default_uuid from app.services.setup_state import mark_setup_complete from tests.helpers.zootech_test_helpers import ZootechTestConfig class LabGoldenPathTests(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) self.comp = Component( id=default_uuid(), name="Ячмень", type="Зерновые", dry_matter=86.0, protein=12.0, energy=12.5, price=15.0, ) db.session.add(self.comp) db.session.flush() upsert_from_api_dict(self.comp.id, {"Сыр. Протеин": 120, "СВ": 860}) self.recipe = Recipe( id=default_uuid(), name="Golden path", heads_per_trip=20, mixing_time=5, ration_type="BEEF", ) self.ingredient = Ingredient( id=default_uuid(), recipe_id=self.recipe.id, component_id=self.comp.id, name="Ячмень", amount=4.0, weight_per_head=4.0, dry_matter=86.0, order=0, ) db.session.add_all([self.recipe, self.ingredient]) db.session.commit() self.recipe_id = self.recipe.id self.client.post( "/api/auth/login", json={"login": "zootech-test-admin", "password": "zootech-test-secret"}, ) def tearDown(self) -> None: db.session.remove() db.drop_all() self.ctx.pop() def test_full_http_golden_path(self) -> None: r = self.client.post(f"/api/lab/rations/{self.recipe_id}/seed-from-execution") self.assertEqual(r.status_code, 200, r.get_data(as_text=True)) r = self.client.post(f"/api/lab/rations/{self.recipe_id}/recalculate") self.assertEqual(r.status_code, 200, r.get_data(as_text=True)) calc = r.get_json() self.assertTrue(calc.get("indicators")) r = self.client.get(f"/api/lab/rations/{self.recipe_id}") self.assertTrue(r.get_json()["exists"]) r = self.client.put( f"/api/lab/rations/{self.recipe_id}", json={ "lines": [ { "componentId": self.comp.id, "dailyKg": 100.0, "inRation": True, "inCompound": True, } ], "rationType": "BEEF", }, ) self.assertEqual(r.status_code, 200) r = self.client.get(f"/api/lab/rations/{self.recipe_id}/diff") self.assertEqual(r.status_code, 200) self.assertTrue(r.get_json()["hasChanges"]) r = self.client.post(f"/api/lab/rations/{self.recipe_id}/apply-from-master") self.assertEqual(r.status_code, 200) db.session.refresh(self.ingredient) self.assertAlmostEqual(float(self.ingredient.weight_per_head), 5.0, places=2) r = self.client.get(f"/api/lab/rations/diff?recipe_ids={self.recipe_id}") self.assertEqual(r.status_code, 200) batch = r.get_json()["results"] self.assertEqual(len(batch), 1) self.assertFalse(batch[0]["hasChanges"])