164 lines
5.4 KiB
Python
164 lines
5.4 KiB
Python
"""dry_matter_locked: серверный пересчёт весов при сохранении рецепта."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import tempfile
|
|
import unittest
|
|
|
|
from app import create_app, db
|
|
from app.models import Ingredient, Recipe
|
|
from app.services.recipe_calculator import calculate_recipe
|
|
from app.services.recipe_update_service import RecipeUpdateError, update_recipe_from_payload
|
|
from config import TestingConfig
|
|
from tests.helpers.mill_recipe_fixtures import (
|
|
create_component,
|
|
create_recipe_with_children,
|
|
ingredient_payload_from_row,
|
|
recipe_update_payload,
|
|
)
|
|
|
|
|
|
class RecipeDryMatterLockedConfig(TestingConfig):
|
|
_TMP_DIR = tempfile.mkdtemp(prefix="wesp-dm-lock-")
|
|
SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(_TMP_DIR, 'dm_lock_test.db')}"
|
|
SQLALCHEMY_BINDS = {"reports": f"sqlite:///{os.path.join(_TMP_DIR, 'reports_test.db')}"}
|
|
AUTH_LOGIN = "dm-lock-admin"
|
|
AUTH_PASSWORD = "dm-lock-secret"
|
|
|
|
|
|
SCENARIO_SAVE_DRY_MATTER_LOCKED = "SAVE_DRY_MATTER_LOCKED"
|
|
|
|
|
|
class RecipeDryMatterLockedTests(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.app = create_app(RecipeDryMatterLockedConfig)
|
|
self.client = self.app.test_client()
|
|
self.ctx = self.app.app_context()
|
|
self.ctx.push()
|
|
db.create_all()
|
|
self.client.post(
|
|
"/api/auth/login",
|
|
json={"login": "dm-lock-admin", "password": "dm-lock-secret"},
|
|
)
|
|
|
|
def tearDown(self) -> None:
|
|
db.session.remove()
|
|
db.drop_all()
|
|
self.ctx.pop()
|
|
|
|
def test_update_recipe_from_payload_recalculates_when_locked(self) -> None:
|
|
comp_id = create_component(dry_matter=50.0)
|
|
recipe_id, ing_ids, _ = create_recipe_with_children(
|
|
component_ids=[comp_id], heads=10, with_groups=False
|
|
)
|
|
recipe = db.session.get(Recipe, recipe_id)
|
|
recipe.dry_matter_locked = True
|
|
db.session.commit()
|
|
|
|
ing = db.session.get(Ingredient, ing_ids[0])
|
|
payload = recipe_update_payload(
|
|
recipe,
|
|
ingredients=[
|
|
{
|
|
"id": ing_ids[0],
|
|
"component_id": comp_id,
|
|
"dry_matter": 50.0,
|
|
"dry_matter_per_head": 1.0,
|
|
"order": 1,
|
|
}
|
|
],
|
|
groups=[],
|
|
)
|
|
payload["dry_matter_locked"] = True
|
|
payload["heads_count"] = 10
|
|
payload["trip_percent"] = 100.0
|
|
|
|
update_recipe_from_payload(recipe_id, payload)
|
|
db.session.commit()
|
|
|
|
db.session.refresh(ing)
|
|
self.assertEqual(ing.weight_per_head, 2.0)
|
|
self.assertEqual(ing.amount, 20.0)
|
|
|
|
def test_locked_save_matches_calculate_api_math(self) -> None:
|
|
comp_id = create_component(dry_matter=60.0)
|
|
recipe_id, ing_ids, _ = create_recipe_with_children(
|
|
component_ids=[comp_id], heads=20, with_groups=False
|
|
)
|
|
recipe = db.session.get(Recipe, recipe_id)
|
|
recipe.dry_matter_locked = True
|
|
db.session.commit()
|
|
|
|
dm_per_head = 0.6
|
|
expected = calculate_recipe(
|
|
ingredients=[{"dryMatterPerHead": dm_per_head, "dryMatter": 60.0}],
|
|
heads_count=20,
|
|
trip_percent=100.0,
|
|
calculate_from_dry_matter=True,
|
|
)
|
|
|
|
resp = self.client.put(
|
|
f"/api/recipes/{recipe_id}",
|
|
json={
|
|
"name": recipe.name,
|
|
"heads_count": 20,
|
|
"trip_percent": 100.0,
|
|
"mixing_time": recipe.mixing_time,
|
|
"target_component_id": comp_id,
|
|
"dry_matter_locked": True,
|
|
"unloading_link_broken": False,
|
|
"ingredients": [
|
|
{
|
|
"id": ing_ids[0],
|
|
"component_id": comp_id,
|
|
"dry_matter": 60.0,
|
|
"dry_matter_per_head": dm_per_head,
|
|
"order": 1,
|
|
}
|
|
],
|
|
"unloading_groups": [],
|
|
},
|
|
)
|
|
self.assertEqual(resp.status_code, 200, resp.get_data(as_text=True))
|
|
|
|
get_resp = self.client.get(f"/api/recipes/{recipe_id}")
|
|
self.assertEqual(get_resp.status_code, 200)
|
|
ing = get_resp.get_json()["ingredients"][0]
|
|
self.assertEqual(
|
|
float(ing["weight_per_head"]),
|
|
expected["ingredients"][0]["weightPerHead"],
|
|
)
|
|
|
|
def test_locked_raises_when_dm_percent_missing(self) -> None:
|
|
comp_id = create_component(dry_matter=0.0)
|
|
recipe_id, ing_ids, _ = create_recipe_with_children(
|
|
component_ids=[comp_id], with_groups=False
|
|
)
|
|
recipe = db.session.get(Recipe, recipe_id)
|
|
recipe.dry_matter_locked = True
|
|
db.session.commit()
|
|
|
|
payload = recipe_update_payload(
|
|
recipe,
|
|
ingredients=[
|
|
{
|
|
"id": ing_ids[0],
|
|
"component_id": comp_id,
|
|
"dry_matter": 0,
|
|
"dry_matter_per_head": 1.0,
|
|
"order": 1,
|
|
}
|
|
],
|
|
groups=[],
|
|
)
|
|
payload["dry_matter_locked"] = True
|
|
|
|
with self.assertRaises(RecipeUpdateError) as ctx:
|
|
update_recipe_from_payload(recipe_id, payload)
|
|
self.assertEqual(ctx.exception.status_code, 400)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|