From ac9fbc4534da6351ab18c2027ed3870c0bcd6b57 Mon Sep 17 00:00:00 2001 From: Lucy Tan Date: Thu, 21 May 2026 15:04:34 -0400 Subject: [PATCH 1/3] fix(ferry): allow CSV timetables to use special exception dates --- lib/timetable_loader.ex | 4 +++- priv/timetables/Boat-F8-1.csv | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/timetable_loader.ex b/lib/timetable_loader.ex index b5251bf31b..75ac2ff865 100644 --- a/lib/timetable_loader.ex +++ b/lib/timetable_loader.ex @@ -16,10 +16,12 @@ defmodule Dotcom.TimetableLoader do @metadata %{ "Boat-F6" => %{ effective_dates: {~D[2026-04-27], ~D[2026-06-13]}, + special_dates: %{~D[2026-05-25] => "Boat-F8"}, weekend: "Boat-F8" }, "Boat-F7" => %{ effective_dates: {~D[2026-04-27], ~D[2026-06-13]}, + special_dates: %{~D[2026-05-25] => "Boat-F8"}, weekend: "Boat-F8" }, "Boat-F8" => %{ @@ -42,7 +44,7 @@ defmodule Dotcom.TimetableLoader do """ @spec from_csv(Routes.Route.id_t(), 0 | 1, Date.t()) :: {:ok, list()} | {:error, term()} def from_csv(route_id, direction_id, date) when route_id in @available_route_ids do - route_id = maybe_use_weekend_route(route_id, date) + route_id = get_in(@metadata, [route_id, :special_dates, date]) || maybe_use_weekend_route(route_id, date) if in_timetable_date_range?(route_id, date) do case @loader_module.get_csv("#{route_id}-#{direction_id}.csv") do diff --git a/priv/timetables/Boat-F8-1.csv b/priv/timetables/Boat-F8-1.csv index 514c2adc59..8255066d02 100644 --- a/priv/timetables/Boat-F8-1.csv +++ b/priv/timetables/Boat-F8-1.csv @@ -1,9 +1,9 @@ Stop,0845,1030,1215,1500,1645,1830,2015 Boat-Winthrop,8:45 AM,10:30 AM,12:15 PM,3:00 PM,4:45 PM,6:30 PM,8:15 PM -Boat-Quincy,9:10 AM,10:55 AM,12:40 PM,3:35 PM,5:00 PM,6:55 PM,8:40 PM +Boat-Quincy,9:10 AM,10:55 AM,12:40 PM,3:25 PM,5:10 PM,6:55 PM,8:40 PM Boat-Fan,9:35 AM,11:20 AM,1:05 PM,3:50 PM,5:35 PM,7:20 PM,9:05 PM Boat-Aquarium,9:45 AM,11:30 AM,1:15 PM,4:00 PM,5:45 PM,7:30 PM,9:15 PM Boat-Logan,9:55 AM,11:40 AM,1:25 PM,4:10 PM,5:55 PM,7:40 PM,9:25 PM Boat-Fan,10:05 AM,11:50 AM,,4:20 PM,6:05 PM,7:50 PM,9:35 PM Boat-Winthrop,10:30 AM,12:15 PM,,4:45 PM,6:30 PM,8:15 PM,10:00 PM -Boat-Quincy,10:55 AM,12:40 PM,,5:00 PM,6:55 PM,8:40 PM,10:25 PM \ No newline at end of file +Boat-Quincy,10:55 AM,12:40 PM,,5:10 PM,6:55 PM,8:40 PM,10:25 PM From ad183b18f4a5c99756915f3d3ace301fbab85a35 Mon Sep 17 00:00:00 2001 From: Lucy Tan Date: Thu, 21 May 2026 15:30:02 -0400 Subject: [PATCH 2/3] Update test --- test/timetable_loader_test.exs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/timetable_loader_test.exs b/test/timetable_loader_test.exs index 416a6a1c52..18926a9de2 100644 --- a/test/timetable_loader_test.exs +++ b/test/timetable_loader_test.exs @@ -59,5 +59,18 @@ defmodule Dotcom.TimetableLoaderTest do invalid_date = ~D[2025-12-25] assert from_csv(valid_route_id, 1, invalid_date) == {:ok, []} end + + test "special case: specific overrides for F6/F7 return F8 table" do + f6_or_f7 = Faker.Util.pick(~w(Boat-F6 Boat-F7)) + + memorial_day = ~D[2026-05-25] + + expect(Dotcom.TimetableLoader.Mock, :get_csv, fn filename -> + assert filename =~ "Boat-F8" + [] + end) + + assert {:ok, _} = from_csv(f6_or_f7, 1, memorial_day) + end end end From 1558473255bacb1d0c8723046dbe2f153915d394 Mon Sep 17 00:00:00 2001 From: Lucy Tan Date: Fri, 22 May 2026 09:20:03 -0400 Subject: [PATCH 3/3] Formatting --- lib/timetable_loader.ex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/timetable_loader.ex b/lib/timetable_loader.ex index 75ac2ff865..f2b608e008 100644 --- a/lib/timetable_loader.ex +++ b/lib/timetable_loader.ex @@ -44,7 +44,9 @@ defmodule Dotcom.TimetableLoader do """ @spec from_csv(Routes.Route.id_t(), 0 | 1, Date.t()) :: {:ok, list()} | {:error, term()} def from_csv(route_id, direction_id, date) when route_id in @available_route_ids do - route_id = get_in(@metadata, [route_id, :special_dates, date]) || maybe_use_weekend_route(route_id, date) + route_id = + get_in(@metadata, [route_id, :special_dates, date]) || + maybe_use_weekend_route(route_id, date) if in_timetable_date_range?(route_id, date) do case @loader_module.get_csv("#{route_id}-#{direction_id}.csv") do