mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-09-30 08:53:13 +00:00
61 lines
2 KiB
Python
61 lines
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, 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_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")
|