meal-order-manager/tests/test_parse_menu.py
Adam Moussa bf1f3ea182
feat(cart): add a local Redefine cart filler (#220)
* feat(cart): add a local Redefine cart filler

Match the admin order-list CSV to the live menu and add each meal to a guest cart so the weekly bulk order does not have to be typed in by hand.

* fix(cart): report cart failures without a traceback

A closed window or a failed cart request during the fill now prints a short failure and the Added/Failed/Skipped summary instead of crashing.

* fix(cart): fail cleanly on a bad CSV and a closed browser

A non-UTF-8 order list and a Playwright error while opening the page now print a short message and exit 1 instead of a traceback.

* fix(cart): account for a closed window and an empty menu

A closed page during add marks the remaining meals as not attempted, and an empty menu catalog raises the same error as the menu parser.
2026-09-26 20:36:38 +00:00

66 lines
2.2 KiB
Python

"""Parser for the catalog embedded on the Redefine menu page."""
from pathlib import Path
import pytest
from scraper.parse_menu import MenuParseError, extract_catalog_products, parse_menu_html
FIXTURE = Path(__file__).resolve().parent / "fixtures" / "menu_page.html"
def test_parse_menu_html_maps_catalog_fields():
page = FIXTURE.read_text()
menu = parse_menu_html(
page,
menu_url="https://www.redefinemeals.com/menu",
scraped_at="2026-09-21T07:30:00-04:00",
)
assert menu["meal_count"] == 2
assert menu["scraped_at"] == "2026-09-21T07:30:00-04:00"
korean, sale = menu["meals"]
assert korean["name"] == "Korean Steak Bowl"
assert korean["price"] == 12.49
assert korean["calories"] == 590
assert korean["protein"] == "50g"
assert korean["dietary_tags"] == ["Gluten Free", "Dairy Free"]
assert korean["image_url"] == "https://example.com/korean.png"
assert korean["is_new"] is True
assert korean["description"] == "Shaved ribeye & rice."
assert sale["name"] == "Sale Bowl"
assert sale["price"] == 9.50
assert sale["calories"] == 400
assert sale["protein"] == "30g"
assert sale["is_new"] is False
assert sale["description"] == "On sale."
def test_parse_menu_html_rejects_a_missing_catalog():
with pytest.raises(MenuParseError, match="missing :products"):
parse_menu_html("<html></html>", menu_url="https://example.com/menu")
def test_extract_catalog_products_rejects_an_empty_catalog():
page = "<orders-page :products='[]' :newest-ids='[]'></orders-page>"
with pytest.raises(MenuParseError, match="empty"):
extract_catalog_products(page)
def test_parse_menu_html_rejects_an_empty_catalog():
page = "<orders-page :products='[]' :newest-ids='[]'></orders-page>"
with pytest.raises(MenuParseError, match="empty"):
parse_menu_html(page, menu_url="https://example.com/menu")
def test_parse_menu_html_rejects_a_meal_without_a_price():
page = """
<orders-page
:products='[{"id":1,"name":"Broken","price":null,"on_sale":false,"available":true}]'
:newest-ids='[]'
></orders-page>
"""
with pytest.raises(MenuParseError, match="missing a price"):
parse_menu_html(page, menu_url="https://example.com/menu")