From 706d4ee0b500555812ca7e0ec95d322eaddec705 Mon Sep 17 00:00:00 2001 From: Michael Genson <71845777+michael-genson@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:49:34 -0600 Subject: [PATCH] fix: Coerce null servings into 0 servings (#6839) --- mealie/schema/recipe/recipe.py | 4 ++ tests/unit_tests/schema_tests/test_recipe.py | 63 ++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 tests/unit_tests/schema_tests/test_recipe.py diff --git a/mealie/schema/recipe/recipe.py b/mealie/schema/recipe/recipe.py index c398182da..a41d505ac 100644 --- a/mealie/schema/recipe/recipe.py +++ b/mealie/schema/recipe/recipe.py @@ -148,6 +148,10 @@ class RecipeSummary(MealieModel): last_made: datetime.datetime | None = None model_config = ConfigDict(from_attributes=True) + @field_validator("recipe_servings", "recipe_yield_quantity", mode="before") + def clean_numbers(val: Any): + return val or 0 + @field_validator("recipe_yield", "total_time", "prep_time", "cook_time", "perform_time", mode="before") def clean_strings(val: Any): if val is None: diff --git a/tests/unit_tests/schema_tests/test_recipe.py b/tests/unit_tests/schema_tests/test_recipe.py new file mode 100644 index 000000000..fd4ba0ba4 --- /dev/null +++ b/tests/unit_tests/schema_tests/test_recipe.py @@ -0,0 +1,63 @@ +from typing import Any +from uuid import uuid4 + +import pytest + +from mealie.schema.recipe import RecipeSummary + +SHOULD_ERROR = "this_test_should_error" + + +@pytest.mark.parametrize("field", ["recipe_servings", "recipe_yield_quantity"]) +@pytest.mark.parametrize( + ["val", "expected"], + [ + (0, 0), + (None, 0), + ("", 0), + (10, 10), + (2.25, 2.25), + ("10", 10), + ("invalid", SHOULD_ERROR), + ], +) +def test_recipe_number_sanitation(field: str, val: Any, expected: Any): + try: + recipe = RecipeSummary( + id=uuid4(), + user_id=uuid4(), + household_id=uuid4(), + group_id=uuid4(), + **{field: val}, + ) + except ValueError: + if expected == SHOULD_ERROR: + return + else: + raise + + assert expected != SHOULD_ERROR, "Value should have errored" + assert getattr(recipe, field) == expected + + +@pytest.mark.parametrize("field", ["recipe_yield", "total_time", "prep_time", "cook_time", "perform_time"]) +@pytest.mark.parametrize( + ["val", "expected"], + [ + ("normal string", "normal string"), + ("", ""), + (None, None), + (10, "10"), + (2.25, "2.25"), + ], +) +def test_recipe_string_sanitation(field: str, val: Any, expected: Any): + recipe = RecipeSummary( + id=uuid4(), + user_id=uuid4(), + household_id=uuid4(), + group_id=uuid4(), + **{field: val}, + ) + + assert getattr(recipe, field) == expected