1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
require "minitest/autorun"
require_relative "../lib/menu_feed"

class MenuFeedTest < Minitest::Test
  def setup
    @feed = MenuFeed.new(JSON.parse((Pathname(__dir__) / "fixtures/menu.json").read))
  end

  def test_skips_days_without_menus
    assert_equal [Date.new(2026, 9, 2), Date.new(2026, 9, 4)], @feed.meals.map(&:date).uniq
  end

  def test_summary_lists_primary_items
    lunch = meal(Date.new(2026, 9, 2), "Lunch")

    assert_equal "Chicken Teriyaki w/ Steamed Rice / Turkey and Cheese Wrap", lunch.summary
  end

  def test_summary_falls_back_to_pre_pack_without_an_entree
    lunch = meal(Date.new(2026, 9, 4), "Lunch")

    assert_equal "Honey BBQ Wings w/ Mac and Cheese / Wowbutter Lunchbox", lunch.summary
  end

  def test_summary_ignores_pre_pack_with_an_entree
    items = [MenuFeed::Item.new(type: "Pre-Pack", name: "Soup, Tomato"), MenuFeed::Item.new(type: "Entree", name: "Ciabatta Cheese Melt")]
    meal = MenuFeed::Meal.new(date: Date.new(2026, 9, 17), block_id: 1, block_name: "Lunch", items:)

    assert_equal "Ciabatta Cheese Melt", meal.summary
  end

  def test_description_omits_condiments
    lunch = meal(Date.new(2026, 9, 2), "Lunch")

    refute_includes lunch.description, "Condiment"
    assert_includes lunch.description, "Daily Vegetable: Black Beans"
  end

  def test_summary_falls_back_to_block_name
    meal = MenuFeed::Meal.new(date: Date.new(2026, 9, 2), block_id: 1, block_name: "Lunch", items: [])

    assert_equal "Lunch", meal.summary
  end

  def test_skips_blacked_out_blocks
    menu = JSON.parse((Pathname(__dir__) / "fixtures/menu.json").read)
    menu.fetch("menuSchedules").flat_map { it.fetch("menuBlocks") }.each { it["blackedOut"] = true }

    assert_empty MenuFeed.new(menu).meals
  end

  def test_to_ical_emits_all_day_events_for_one_block
    calendar = Icalendar::Calendar.parse(@feed.to_ical("Lunch")).fetch(0)
    event = calendar.events.find { it.dtstart == Date.new(2026, 9, 2) }

    assert_equal "McDonald lunch", calendar.x_wr_calname.first
    assert_equal 2, calendar.events.size
    assert_equal Date.new(2026, 9, 3), event.dtend.value
    assert_equal "2026-09-02-3578@mealviewer.McDonald", event.uid
  end

  def test_to_ical_without_meals_is_an_empty_calendar
    calendar = Icalendar::Calendar.parse(@feed.to_ical("Dinner")).fetch(0)

    assert_empty calendar.events
  end

  private

  def meal(date, block_name)
    @feed.meals.find { it.date == date && it.block_name == block_name }
  end
end