Skip to content

Commit

Permalink
refactor: elevator closure header/footer handling
Browse files Browse the repository at this point in the history
* Rather than the main Elevator screen candidate generator creating the
  header and footer widgets and the Closures generator "modifying" them
  with variants as appropriate, now the Closures generator alone is
  responsible. This somewhat simplifies the implementation and testing
  on both ends.

* Tests for the Closures generator were more verbose and testing more
  than they strictly needed to be (for example, that the correct header
  and footer were present in every case). These are now cut down to only
  the relevant and unique details.
  • Loading branch information
digitalcora committed Jan 24, 2025
1 parent d9a86bb commit 61ac725
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 221 deletions.
35 changes: 10 additions & 25 deletions lib/screens/v2/candidate_generator/elevator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ defmodule Screens.V2.CandidateGenerator.Elevator do
alias Screens.V2.CandidateGenerator.Elevator.Closures, as: ElevatorClosures
alias Screens.V2.CandidateGenerator.Widgets.Evergreen
alias Screens.V2.Template.Builder
alias Screens.V2.WidgetInstance.{Footer, NormalHeader}
alias ScreensConfig.Screen
alias ScreensConfig.V2.Elevator

@behaviour CandidateGenerator

@instance_fns [
&ElevatorClosures.elevator_status_instances/2,
&Evergreen.evergreen_content_instances/2
]

@impl true
def screen_template do
{
:screen,
Expand All @@ -26,29 +29,11 @@ defmodule Screens.V2.CandidateGenerator.Elevator do
|> Builder.build_template()
end

def candidate_instances(
config,
now \\ DateTime.utc_now(),
elevator_closure_instances_fn \\ &ElevatorClosures.elevator_status_instances/3,
evergreen_content_instances_fn \\ &Evergreen.evergreen_content_instances/2
) do
Enum.concat([
elevator_closure_instances_fn.(
config,
header_instance(config, now),
footer_instance(config)
),
evergreen_content_instances_fn.(config, now)
])
@impl true
def candidate_instances(config, now \\ DateTime.utc_now(), instance_fns \\ @instance_fns) do
instance_fns |> Enum.map(& &1.(config, now)) |> Enum.concat()
end

@impl true
def audio_only_instances(_widgets, _config), do: []

defp header_instance(%Screen{app_params: %Elevator{elevator_id: elevator_id}} = config, now) do
%NormalHeader{text: "Elevator #{elevator_id}", screen: config, time: now}
end

defp footer_instance(config) do
%Footer{screen: config}
end
end
27 changes: 18 additions & 9 deletions lib/screens/v2/candidate_generator/elevator/closures.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator.Closures do
alias Screens.Routes.Route
alias Screens.Stops.Stop
alias Screens.V2.WidgetInstance
alias Screens.V2.WidgetInstance.{Footer, NormalHeader}

alias Screens.V2.WidgetInstance.{
CurrentElevatorClosed,
Expand All @@ -54,12 +55,10 @@ defmodule Screens.V2.CandidateGenerator.Elevator.Closures do

@fallback_summary "Visit mbta.com/elevators for more info"

@spec elevator_status_instances(Screen.t(), NormalHeader.t(), Footer.t()) ::
list(WidgetInstance.t())
@spec elevator_status_instances(Screen.t(), DateTime.t()) :: list(WidgetInstance.t())
def elevator_status_instances(
%Screen{app_params: %ElevatorConfig{elevator_id: elevator_id} = app_params},
header_instance,
footer_instance
%Screen{app_params: %ElevatorConfig{elevator_id: elevator_id} = app_params} = config,
now
) do
{:ok, alerts} = @alert.fetch_elevator_alerts_with_facilities()

Expand All @@ -68,17 +67,27 @@ defmodule Screens.V2.CandidateGenerator.Elevator.Closures do

case Enum.find(closures, fn %Closure{id: id} -> id == elevator_id end) do
nil ->
[header_instance, elevator_closures_list(closures, app_params), footer_instance]
[elevator_closures_list(closures, app_params) | header_footer_instances(config, now)]

_closure ->
[
%NormalHeader{header_instance | variant: :closed},
%CurrentElevatorClosed{app_params: app_params},
%Footer{footer_instance | variant: :closed}
%CurrentElevatorClosed{app_params: app_params}
| header_footer_instances(config, now, :closed)
]
end
end

defp header_footer_instances(
%Screen{app_params: %ElevatorConfig{elevator_id: elevator_id}} = config,
now,
variant \\ nil
) do
[
%NormalHeader{text: "Elevator #{elevator_id}", screen: config, time: now, variant: variant},
%Footer{screen: config, variant: variant}
]
end

defp elevator_closure(%Alert{id: id, effect: :elevator_closure, informed_entities: entities}) do
# We expect there is a 1:1 relationship between `elevator_closure` alerts and individual
# out-of-service elevators. Log a warning if our assumptions don't hold.
Expand Down
Loading

0 comments on commit 61ac725

Please sign in to comment.