mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-09-30 14:43:12 +00:00
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.
66 lines
2.2 KiB
Python
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")
|