Nutzer können persönliche Foods anlegen und ändern; der Admin legt zentrale Einträge für alle an. Suche und Namens-Mapping berücksichtigen persönlich, zentral und BLS. Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
3.2 KiB
Python
87 lines
3.2 KiB
Python
from data_layer.food_attributes import (
|
|
create_extension_attribute,
|
|
editor_payload_for_food,
|
|
macros_and_attributes_to_values,
|
|
normalize_attr_key,
|
|
normalize_attr_unit,
|
|
scale_to_per_100g,
|
|
)
|
|
|
|
|
|
def test_scale_serving_to_per_100g():
|
|
assert scale_to_per_100g(1.1, 8) == 1.1 * (100 / 8)
|
|
assert scale_to_per_100g(10, 100) == 10
|
|
assert scale_to_per_100g(10, None) == 10
|
|
|
|
|
|
def test_attr_key_and_unit_normalize():
|
|
assert normalize_attr_key("Vitamin D3") == "VITAMIN_D3"
|
|
assert normalize_attr_unit("ug") == "µg"
|
|
assert normalize_attr_unit("mcg") == "µg"
|
|
|
|
|
|
def test_create_extension_returns_existing():
|
|
class _Cur:
|
|
def __init__(self):
|
|
self.calls = 0
|
|
|
|
def execute(self, sql, params=None):
|
|
self.calls += 1
|
|
self._row = {"id": 1, "attr_key": "VITAMIN_D3", "name_de": "Vitamin D3", "name_en": None, "unit": "µg", "category": "extension", "origin": "extension"} if self.calls == 1 else None
|
|
|
|
def fetchone(self):
|
|
return self._row
|
|
|
|
row = create_extension_attribute(_Cur(), "Vitamin D3", "µg")
|
|
assert row["attr_key"] == "VITAMIN_D3"
|
|
|
|
|
|
def test_norsan_label_epa_converts():
|
|
"""Etikett: 1100 mg EPA = 1.1 g in 8 g Portion → g/100 g."""
|
|
vals = macros_and_attributes_to_values(
|
|
{"kcal": 72, "protein_g": 0, "fat_g": 8, "carbs_g": 0},
|
|
{"EPA": 1.1},
|
|
serving_g=8,
|
|
)
|
|
assert abs(vals["FAT"] - 100) < 0.01
|
|
assert abs(vals["EPA"] - 13.75) < 0.01
|
|
assert abs(vals["ENERCC"] - 900) < 0.01
|
|
|
|
|
|
def test_edit_payload_does_not_rescale_at_100g():
|
|
vals = macros_and_attributes_to_values(
|
|
{"kcal": 900, "protein_g": 0, "fat_g": 100, "carbs_g": 0},
|
|
{"EPA": 13.75},
|
|
serving_g=100,
|
|
)
|
|
assert vals["FAT"] == 100
|
|
assert vals["EPA"] == 13.75
|
|
assert vals["ENERCC"] == 900
|
|
|
|
|
|
def test_editor_payload_splits_macros_and_extras():
|
|
class _Cur:
|
|
def execute(self, sql, params=None):
|
|
pass
|
|
|
|
def fetchall(self):
|
|
return [
|
|
{"attr_key": "ENERCC", "name_de": "Energie", "name_en": None, "unit": "kcal", "category": "energy", "origin": "bls", "value_num": 900},
|
|
{"attr_key": "FAT", "name_de": "Fett", "name_en": None, "unit": "g", "category": "macro", "origin": "bls", "value_num": 100},
|
|
{"attr_key": "PROT625", "name_de": "Protein", "name_en": None, "unit": "g", "category": "macro", "origin": "bls", "value_num": 0},
|
|
{"attr_key": "CHO", "name_de": "KH", "name_en": None, "unit": "g", "category": "macro", "origin": "bls", "value_num": 0},
|
|
{"attr_key": "EPA", "name_de": "EPA", "name_en": None, "unit": "g", "category": "extension", "origin": "extension", "value_num": 13.75},
|
|
]
|
|
|
|
payload = editor_payload_for_food(
|
|
_Cur(),
|
|
{"id": "abc", "name_de": "Omega-3", "name_en": None, "catalog_kind": "manual_user"},
|
|
editable=True,
|
|
)
|
|
assert payload["editable"] is True
|
|
assert payload["serving_g"] == 100
|
|
assert payload["macros_per_100g"]["kcal"] == 900
|
|
assert payload["macros_per_100g"]["fat_g"] == 100
|
|
assert payload["attributes"][0]["attr"]["attr_key"] == "EPA"
|
|
assert payload["attributes"][0]["value"] == 13.75
|