Treat Mealie's "no image" sentinel as a missing cover
Mealie stores the literal string "no image" in the recipe's image field when there is no cover, so bool(recipe["image"]) reported a cover that is not there: the check meant to catch a missing image downgraded to a warning instead of failing. Observed on a recipe created through Mealie's own image import, which returned image: "no image". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+18
-1
@@ -16,6 +16,10 @@ from .normalize import (
|
||||
looks_mangled,
|
||||
)
|
||||
|
||||
#: Mealie stores this sentinel in ``image`` when a recipe has no cover, so a
|
||||
#: truthiness test on the field reports a cover that is not there.
|
||||
NO_IMAGE_SENTINEL = "no image"
|
||||
|
||||
Status = Literal["pass", "fail", "warn"]
|
||||
|
||||
|
||||
@@ -23,6 +27,19 @@ def _check(check_id: str, status: Status, detail: str) -> dict[str, str]:
|
||||
return {"check": check_id, "status": status, "detail": detail}
|
||||
|
||||
|
||||
def has_cover_image(recipe: dict[str, Any]) -> bool:
|
||||
"""Whether the recipe carries a real cover image.
|
||||
|
||||
Mealie writes the literal string ``"no image"`` instead of an empty value
|
||||
when a recipe has no cover, so an emptiness test has to reject that
|
||||
sentinel too.
|
||||
"""
|
||||
image = recipe.get("image")
|
||||
if not isinstance(image, str):
|
||||
return bool(image)
|
||||
return image.strip().casefold() not in ("", NO_IMAGE_SENTINEL)
|
||||
|
||||
|
||||
def is_parsed(recipe: dict[str, Any]) -> bool:
|
||||
"""Whether Mealie will stop showing 'your ingredients aren't parsed yet'.
|
||||
|
||||
@@ -149,7 +166,7 @@ def verify_recipe(
|
||||
)
|
||||
)
|
||||
|
||||
has_image_field = bool(recipe.get("image"))
|
||||
has_image_field = has_cover_image(recipe)
|
||||
if image_verified:
|
||||
image_status: Status = "pass"
|
||||
image_detail = "Image step ran and was verified by the caller"
|
||||
|
||||
@@ -61,6 +61,14 @@ class TestCoverImage:
|
||||
assert status_of(report, "cover_image") == "fail"
|
||||
assert report["complete"] is False
|
||||
|
||||
@pytest.mark.parametrize("stored", ["no image", "No Image", " no image ", ""])
|
||||
def test_mealies_no_image_sentinel_fails(self, stored):
|
||||
# Verified against Mealie 3.22: a recipe without a cover stores the
|
||||
# string "no image", which a truthiness test reads as a cover present.
|
||||
report = verify_recipe(complete_recipe(image=stored))
|
||||
assert status_of(report, "cover_image") == "fail"
|
||||
assert report["complete"] is False
|
||||
|
||||
|
||||
class TestSwedishContent:
|
||||
def test_english_ingredient_line_fails(self):
|
||||
|
||||
Reference in New Issue
Block a user