Skip to content

Commit

Permalink
Prevent crash when there are no current services for the day
Browse files Browse the repository at this point in the history
  • Loading branch information
amaisano authored and phildarnowsky committed Jan 20, 2020
1 parent 5a13770 commit a262961
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 17 deletions.
43 changes: 26 additions & 17 deletions apps/site/lib/site_web/controllers/schedule/line_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,19 @@ defmodule SiteWeb.ScheduleController.LineController do
|> tag_default_service()
end

# Some routes have no services (ie, "Green")
defp tag_default_service([]), do: []

defp tag_default_service(services) do
current_service_id =
services
|> Enum.filter(&is_current_service?/1)
|> get_default_service(services)
|> Map.get(:id, "")

Enum.map(services, &Map.put(&1, :default_service?, &1.id === current_service_id))
end

# Find candidates that could be valid for today:
# - within the :start_date and :end_date (REJECT otherwise)
# - today NOT present in :removed_dates (REJECT if present)
Expand All @@ -160,35 +173,31 @@ defmodule SiteWeb.ScheduleController.LineController do
(in_current_rating? || added_in?) && !removed?
end

# Some routes have no services (ie, "Green")
defp tag_default_service([]), do: []

defp tag_default_service(services) do
current_service_id =
services
|> Enum.filter(&is_current_service?/1)
|> get_default_service()
|> Map.get(:id, "")

Enum.map(services, &Map.put(&1, :default_service?, &1.id === current_service_id))
end
# Prevent page crash when there are services, but none are valid for today.
# Uses first of original services found for this route.
defp get_default_service([], all_services), do: List.first(all_services)

# Get today's default service (reduce valid candidates to best match)
# - prefer if today's date is present inside :added_dates (typically means holiday)
# - otherwise, if today's day of week is within set of :valid_days
# - if all else fails, use the first candidate (already sorted by :start_date)
defp get_default_service(services) do
service_date = services |> List.first() |> Map.get(:service_date)
defp get_default_service(current_services, _all_services) do
service_date = current_services |> List.first() |> Map.get(:service_date)
day_number = Timex.weekday(service_date)

# Fallback #2: First service
first_service = List.first(services)
first_service = List.first(current_services)

# Fallback #1: Today is a valid day for this service
day_service = Enum.find(services, first_service, &Enum.member?(&1.valid_days, day_number))
day_service =
Enum.find(current_services, first_service, &Enum.member?(&1.valid_days, day_number))

# Best match: Today is explicitly listed in this service's :added_in list
Enum.find(services, day_service, &Enum.member?(&1.added_dates, Date.to_iso8601(service_date)))
Enum.find(
current_services,
day_service,
&Enum.member?(&1.added_dates, Date.to_iso8601(service_date))
)
end

def sort_services_by_date(%Service{typicality: :typical_service, type: :weekday} = service) do
Expand Down
47 changes: 47 additions & 0 deletions apps/site/test/site_web/controllers/schedule/line_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,39 @@ defmodule SiteWeb.ScheduleController.LineTest do
}
]

@fourtwofour_services [
%{
__struct__: Services.Service,
added_dates: [],
added_dates_notes: %{},
description: "Weekday schedule",
end_date: ~D[2020-03-13],
id: "WinterWeekday",
name: "Weekday",
removed_dates: [
"2020-01-20",
"2020-02-17",
"2020-02-18",
"2020-02-19",
"2020-02-20",
"2020-02-21"
],
removed_dates_notes: %{
"2020-01-20" => "Martin Luther King Day",
"2020-02-17" => "Washington's Birthday",
"2020-02-18" => nil,
"2020-02-19" => nil,
"2020-02-20" => nil,
"2020-02-21" => nil
},
service_date: ~D[2020-01-20],
start_date: ~D[2020-01-09],
type: :weekday,
typicality: :typical_service,
valid_days: [1, 2, 3, 4, 5]
}
]

def get_error_stop_list(_, _, _), do: {:error, "error"}

describe "get_branches" do
Expand Down Expand Up @@ -622,6 +655,20 @@ defmodule SiteWeb.ScheduleController.LineTest do

assert length(default_service) == 1
end

test "uses the first service as a default if no services are valid", %{conn: conn} do
conn =
conn
|> assign(:date_time, ~D[2020-01-20])
|> assign(:services_fn, fn _ -> @fourtwofour_services end)
|> get(line_path(conn, :show, "424"))

services_for_route = conn.assigns.schedule_page_data.services
default_services = Enum.filter(services_for_route, &(&1.default_service? === true))

assert length(default_services) == 1
assert default_services = [%{id: "WinterWeekday1"}]
end
end

describe "line diagram endpoint" do
Expand Down

0 comments on commit a262961

Please sign in to comment.