From 27d93317a90e5dd92aab6e91c1312fd37307b3e9 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Thu, 16 May 2024 12:36:07 -0500 Subject: [PATCH 01/24] rearrange factories and add new factories for alerts --- lib/alerts/alert.ex | 76 ++++++++++++------- lib/alerts/informed_entity.ex | 61 +++++++++------ lib/alerts/informed_entity_set.ex | 35 ++++----- lib/alerts/priority.ex | 5 ++ mix.exs | 5 +- test/dotcom/transit_near_me_test.exs | 2 +- test/dotcom/trip_plan/itinerary_row_test.exs | 4 +- .../vehicle_map_marker_channel_test.exs | 2 +- .../schedule/line/helpers_test.exs | 2 +- .../controllers/schedule/predictions_test.exs | 2 +- .../controllers/schedule/trip_info_test.exs | 2 +- test/leaflet/map_data/polyline_test.exs | 2 +- test/predicted_schedule_test.exs | 2 +- test/predictions/repo_test.exs | 2 +- test/predictions/stream_topic_test.exs | 2 +- test/route_patterns/repo_test.exs | 2 +- test/stops/nearby_test.exs | 2 +- test/stops/repo_test.exs | 2 +- test/stops/route_stops_test.exs | 2 +- test/support/factories/alerts/alert.ex | 29 +++++++ .../factories/alerts/informed_entity.ex | 22 ++++++ .../factories/alerts/informed_entity_set.ex | 15 ++++ .../mbta_api.ex => factories/mbta/api.ex} | 2 +- .../predictions}/prediction.ex | 2 +- .../route_patterns}/route_pattern.ex | 2 +- 25 files changed, 195 insertions(+), 89 deletions(-) create mode 100644 test/support/factories/alerts/alert.ex create mode 100644 test/support/factories/alerts/informed_entity.ex create mode 100644 test/support/factories/alerts/informed_entity_set.ex rename test/support/{factory/mbta_api.ex => factories/mbta/api.ex} (99%) rename test/support/{factory => factories/predictions}/prediction.ex (74%) rename test/support/{factory => factories/route_patterns}/route_pattern.ex (73%) diff --git a/lib/alerts/alert.ex b/lib/alerts/alert.ex index 8d7204ba5f..0258ea38e8 100644 --- a/lib/alerts/alert.ex +++ b/lib/alerts/alert.ex @@ -1,21 +1,26 @@ defmodule Alerts.Alert do - @moduledoc "Module for representation of an alert, including information such as description, severity or additional URL to learn more" - alias Alerts.Priority - alias Alerts.InformedEntitySet, as: IESet + @moduledoc """ + Module for representation of an alert, including information such as description, severity or additional URL to learn more + """ + + use Timex + + alias Alerts.{InformedEntitySet, Priority} defstruct id: "", - header: "", - informed_entity: %IESet{}, active_period: [], - effect: :unknown, - severity: 5, - lifecycle: :unknown, + banner: "", cause: "", - updated_at: Timex.now(), description: "", + effect: :unknown, + header: "", + image_url: "", + informed_entity: %InformedEntitySet{}, + lifecycle: :unknown, priority: :low, - url: "", - banner: "" + severity: 5, + updated_at: Timex.now(), + url: "" @type period_pair :: {DateTime.t() | nil, DateTime.t() | nil} @@ -51,30 +56,30 @@ defmodule Alerts.Alert do | :unknown @type severity :: 0..10 + @type lifecycle :: :ongoing | :upcoming | :ongoing_upcoming | :new | :unknown + @type id_t :: String.t() + @type t :: %Alerts.Alert{ id: id_t(), - header: String.t(), - informed_entity: IESet.t(), active_period: [period_pair], + banner: String.t() | nil, cause: String.t(), + description: String.t() | nil, effect: effect, - severity: severity, + header: String.t(), + image_url: String.t() | nil, + informed_entity: InformedEntitySet.t(), lifecycle: lifecycle, - updated_at: DateTime.t(), - description: String.t() | nil, priority: Priority.priority_level(), - url: String.t() | nil, - banner: String.t() | nil + severity: severity, + updated_at: DateTime.t(), + url: String.t() | nil } @type icon_type :: :alert | :cancel | :none | :shuttle | :snow - use Timex - - @stops_repo Application.compile_env!(:dotcom, :repo_modules)[:stops] - @ongoing_effects [ :cancellation, :detour, @@ -113,6 +118,10 @@ defmodule Alerts.Alert do :detour ] + @lifecycles [:ongoing, :upcoming, :ongoing_upcoming, :new, :unknown] + + @stops_repo Application.compile_env!(:dotcom, :repo_modules)[:stops] + @spec new(Keyword.t()) :: t() def new(keywords \\ []) @@ -145,7 +154,7 @@ defmodule Alerts.Alert do @spec ensure_entity_set(map) :: t() defp ensure_entity_set(alert) do - %__MODULE__{alert | informed_entity: IESet.new(alert.informed_entity)} + %__MODULE__{alert | informed_entity: InformedEntitySet.new(alert.informed_entity)} end @spec all_types :: [effect] @@ -154,13 +163,24 @@ defmodule Alerts.Alert do @spec ongoing_effects :: [effect] def ongoing_effects, do: @ongoing_effects + @spec lifecycles :: [lifecycle] + def lifecycles, do: @lifecycles + @spec get_entity(t, :route | :stop | :route_type | :trip | :direction_id) :: Enumerable.t() @doc "Helper function for retrieving InformedEntity values for an alert" - def get_entity(%__MODULE__{informed_entity: %IESet{route: set}}, :route), do: set - def get_entity(%__MODULE__{informed_entity: %IESet{stop: set}}, :stop), do: set - def get_entity(%__MODULE__{informed_entity: %IESet{route_type: set}}, :route_type), do: set - def get_entity(%__MODULE__{informed_entity: %IESet{trip: set}}, :trip), do: set - def get_entity(%__MODULE__{informed_entity: %IESet{direction_id: set}}, :direction_id), do: set + def get_entity(%__MODULE__{informed_entity: %InformedEntitySet{route: set}}, :route), do: set + def get_entity(%__MODULE__{informed_entity: %InformedEntitySet{stop: set}}, :stop), do: set + + def get_entity(%__MODULE__{informed_entity: %InformedEntitySet{route_type: set}}, :route_type), + do: set + + def get_entity(%__MODULE__{informed_entity: %InformedEntitySet{trip: set}}, :trip), do: set + + def get_entity( + %__MODULE__{informed_entity: %InformedEntitySet{direction_id: set}}, + :direction_id + ), + do: set def access_alert_types do [elevator_closure: "Elevator", escalator_closure: "Escalator", access_issue: "Other"] diff --git a/lib/alerts/informed_entity.ex b/lib/alerts/informed_entity.ex index cefd2fab51..fc9fc535c1 100644 --- a/lib/alerts/informed_entity.ex +++ b/lib/alerts/informed_entity.ex @@ -1,43 +1,51 @@ defmodule Alerts.InformedEntity do - @fields [:route, :route_type, :stop, :trip, :direction_id, :facility, :activities] - @empty_activities MapSet.new() - defstruct route: nil, - route_type: nil, - stop: nil, - trip: nil, + defstruct activities: MapSet.new(), direction_id: nil, facility: nil, - activities: @empty_activities + route: nil, + route_type: nil, + stop: nil, + trip: nil @type t :: %Alerts.InformedEntity{ + activities: MapSet.t(activity), + direction_id: 0 | 1 | nil, + facility: String.t() | nil, route: String.t() | nil, route_type: String.t() | nil, stop: String.t() | nil, - trip: String.t() | nil, - direction_id: 0 | 1 | nil, - facility: String.t() | nil, - activities: MapSet.t(activity_type) + trip: String.t() | nil } - @type activity_type :: + @type activity :: :board + | :bringing_bike | :exit - | :ride | :park_car - | :bringing_bike + | :ride | :store_bike - | :using_wheelchair | :using_escalator + | :using_wheelchair - alias __MODULE__, as: IE + @activities [ + :board, + :bringing_bike, + :exit, + :park_car, + :ride, + :store_bike, + :using_escalator, + :using_wheelchair + ] - @doc """ + @spec activities() :: list(activity) + def activities(), do: @activities + @doc """ Given a keyword list (with keys matching our fields), returns a new InformedEntity. Additional keys are ignored. - """ - @spec from_keywords(list) :: IE.t() + @spec from_keywords(list) :: Alerts.InformedEntity.t() def from_keywords(options) do options |> Enum.map(&ensure_value_type/1) @@ -60,13 +68,14 @@ defmodule Alerts.InformedEntity do Otherwise the nil can match any value in the other InformedEntity. """ - @spec match?(IE.t(), IE.t()) :: boolean - def match?(%IE{} = first, %IE{} = second) do + @spec match?(Alerts.InformedEntity.t(), Alerts.InformedEntity.t()) :: boolean + def match?(%__MODULE__{} = first, %__MODULE__{} = second) do share_a_key?(first, second) && do_match?(first, second) end + @spec mapsets_match?(MapSet.t(), MapSet.t()) :: boolean() def mapsets_match?(%MapSet{} = a, %MapSet{} = b) - when a == @empty_activities or b == @empty_activities, + when a == %MapSet{} or b == %MapSet{}, do: true def mapsets_match?(%MapSet{} = a, %MapSet{} = b), do: has_intersect?(a, b) @@ -74,7 +83,9 @@ defmodule Alerts.InformedEntity do defp has_intersect?(a, b), do: Enum.any?(a, &(&1 in b)) defp do_match?(f, s) do - @fields + __MODULE__.__struct__() + |> Map.keys() + |> List.delete(:__struct__) |> Enum.all?(&key_match(Map.get(f, &1), Map.get(s, &1))) end @@ -85,7 +96,9 @@ defmodule Alerts.InformedEntity do defp key_match(_, _), do: false defp share_a_key?(first, second) do - @fields + __MODULE__.__struct__() + |> Map.keys() + |> List.delete(:__struct__) |> Enum.any?(&shared_key(Map.get(first, &1), Map.get(second, &1))) end diff --git a/lib/alerts/informed_entity_set.ex b/lib/alerts/informed_entity_set.ex index 83954bc6cb..68640fec68 100644 --- a/lib/alerts/informed_entity_set.ex +++ b/lib/alerts/informed_entity_set.ex @@ -6,30 +6,31 @@ defmodule Alerts.InformedEntitySet do it's present in the InformedEntitySet. If it's not, there's no way for it to match any of the InformedEntities inside. """ - alias Alerts.InformedEntity, as: IE - defstruct route: MapSet.new(), - route_type: MapSet.new(), - stop: MapSet.new(), - trip: MapSet.new(), + alias Alerts.InformedEntity + + defstruct activities: MapSet.new(), direction_id: MapSet.new(), + entities: [], facility: MapSet.new(), - activities: MapSet.new(), - entities: [] + route: MapSet.new(), + route_type: MapSet.new(), + stop: MapSet.new(), + trip: MapSet.new() @type t :: %__MODULE__{ + activities: MapSet.t(), + direction_id: MapSet.t(), + entities: [InformedEntity.t()], + facility: MapSet.t(), route: MapSet.t(), route_type: MapSet.t(), stop: MapSet.t(), - trip: MapSet.t(), - direction_id: MapSet.t(), - facility: MapSet.t(), - activities: MapSet.t(), - entities: [IE.t()] + trip: MapSet.t() } @doc "Create a new InformedEntitySet from a list of InformedEntitys" - @spec new([IE.t()]) :: t + @spec new([InformedEntity.t()]) :: t def new(%__MODULE__{} = entity_set) do entity_set end @@ -40,8 +41,8 @@ defmodule Alerts.InformedEntitySet do end @doc "Returns whether the given entity matches the set" - @spec match?(t, IE.t()) :: boolean - def match?(%__MODULE__{} = set, %IE{} = entity) do + @spec match?(t, InformedEntity.t()) :: boolean + def match?(%__MODULE__{} = set, %InformedEntity{} = entity) do entity |> Map.from_struct() |> Enum.all?(&field_in_set?(set, &1)) @@ -73,7 +74,7 @@ defmodule Alerts.InformedEntitySet do end defp field_in_set?(set, {:activities, %MapSet{} = value}) do - IE.mapsets_match?(set.activities, value) + InformedEntity.mapsets_match?(set.activities, value) end defp field_in_set?(set, {key, value}) do @@ -89,7 +90,7 @@ defmodule Alerts.InformedEntitySet do defp try_all_entity_match(true, set, entity) do # we only try matching against the whole set when the MapSets overlapped - Enum.any?(set, &IE.match?(&1, entity)) + Enum.any?(set, &InformedEntity.match?(&1, entity)) end end diff --git a/lib/alerts/priority.ex b/lib/alerts/priority.ex index 80821b6927..94631533ab 100644 --- a/lib/alerts/priority.ex +++ b/lib/alerts/priority.ex @@ -8,6 +8,11 @@ defmodule Alerts.Priority do @type priority_level :: :high | :low | :system @ongoing_effects Alerts.Alert.ongoing_effects() + @priority_levels [:high, :low, :system] + + @spec priority_levels() :: [priority_level] + def priority_levels, do: @priority_levels + @spec priority(map, DateTime.t()) :: priority_level def priority(map, now \\ Util.now()) diff --git a/mix.exs b/mix.exs index 8bdf03f216..fffd89d62b 100644 --- a/mix.exs +++ b/mix.exs @@ -35,6 +35,7 @@ defmodule DotCom.Mixfile do end # Specifies which paths to compile per environment. + defp elixirc_paths(:dev), do: ["lib", "test/support/factories"] defp elixirc_paths(:test), do: ["lib", "test/support"] defp elixirc_paths(_), do: ["lib"] @@ -82,11 +83,11 @@ defmodule DotCom.Mixfile do {:ex_aws_s3, "2.5.3"}, {:ex_aws_ses, "2.4.1"}, {:ex_doc, "0.32.2", only: :dev}, - {:ex_machina, "2.7.0", only: :test}, + {:ex_machina, "2.7.0", only: [:dev, :test]}, {:ex_unit_summary, "0.1.0", only: [:dev, :test]}, # latest version 0.18.1; cannot upgrade because expects castore >= 1 {:excoveralls, "0.16.1", only: :test}, - {:faker, "0.18.0", only: :test}, + {:faker, "0.18.0", only: [:dev, :test]}, {:floki, "0.36.2"}, {:gen_stage, "1.2.1"}, {:gettext, "0.24.0"}, diff --git a/test/dotcom/transit_near_me_test.exs b/test/dotcom/transit_near_me_test.exs index 723de5a6be..0285110431 100644 --- a/test/dotcom/transit_near_me_test.exs +++ b/test/dotcom/transit_near_me_test.exs @@ -4,7 +4,7 @@ defmodule Dotcom.TransitNearMeTest do import Mox import Mox - import Test.Support.Factory.Prediction + import Test.Support.Factories.Predictions.Prediction alias LocationService.Address alias Predictions.Prediction diff --git a/test/dotcom/trip_plan/itinerary_row_test.exs b/test/dotcom/trip_plan/itinerary_row_test.exs index 1ab9a3c06b..da2aad187c 100644 --- a/test/dotcom/trip_plan/itinerary_row_test.exs +++ b/test/dotcom/trip_plan/itinerary_row_test.exs @@ -327,10 +327,10 @@ defmodule TripPlan.ItineraryRowTest do stub(MBTA.Api.Mock, :get_json, fn path, _ -> cond do String.contains?(path, "trips") -> - %JsonApi{data: [Test.Support.Factory.MbtaApi.build(:trip_item)]} + %JsonApi{data: [Test.Support.Factories.Mbta.Api.build(:trip_item)]} String.contains?(path, "routes") -> - %JsonApi{data: [Test.Support.Factory.MbtaApi.build(:route_item)]} + %JsonApi{data: [Test.Support.Factories.Mbta.Api.build(:route_item)]} true -> %JsonApi{data: []} diff --git a/test/dotcom_web/channels/vehicle_map_marker_channel_test.exs b/test/dotcom_web/channels/vehicle_map_marker_channel_test.exs index 2278c9c62a..340bcef06d 100644 --- a/test/dotcom_web/channels/vehicle_map_marker_channel_test.exs +++ b/test/dotcom_web/channels/vehicle_map_marker_channel_test.exs @@ -7,7 +7,7 @@ defmodule DotcomWeb.VehicleMapMarkerChannelTest do import Mock import Mox - import Test.Support.Factory.MbtaApi + import Test.Support.Factories.Mbta.Api @vehicles [ %Vehicle{ diff --git a/test/dotcom_web/controllers/schedule/line/helpers_test.exs b/test/dotcom_web/controllers/schedule/line/helpers_test.exs index ad7b042f68..a104fc9252 100644 --- a/test/dotcom_web/controllers/schedule/line/helpers_test.exs +++ b/test/dotcom_web/controllers/schedule/line/helpers_test.exs @@ -2,7 +2,7 @@ defmodule DotcomWeb.ScheduleController.Line.HelpersTest do use ExUnit.Case, async: false import Mox - import Test.Support.Factory.MbtaApi + import Test.Support.Factories.Mbta.Api alias Routes.{Route} alias DotcomWeb.ScheduleController.Line.Helpers alias Stops.{RouteStops, RouteStop, Stop} diff --git a/test/dotcom_web/controllers/schedule/predictions_test.exs b/test/dotcom_web/controllers/schedule/predictions_test.exs index c07804de3b..294fa63766 100644 --- a/test/dotcom_web/controllers/schedule/predictions_test.exs +++ b/test/dotcom_web/controllers/schedule/predictions_test.exs @@ -3,7 +3,7 @@ defmodule DotcomWeb.ScheduleController.PredictionsTest do import DotcomWeb.ScheduleController.Predictions import Mox - import Test.Support.Factory.Prediction + import Test.Support.Factories.Predictions.Prediction setup %{conn: conn} do conn = diff --git a/test/dotcom_web/controllers/schedule/trip_info_test.exs b/test/dotcom_web/controllers/schedule/trip_info_test.exs index b610e8f617..e028e1a63a 100644 --- a/test/dotcom_web/controllers/schedule/trip_info_test.exs +++ b/test/dotcom_web/controllers/schedule/trip_info_test.exs @@ -3,7 +3,7 @@ defmodule DotcomWeb.ScheduleController.TripInfoTest do import DotcomWeb.ScheduleController.TripInfo import Mox - import Test.Support.Factory.Prediction + import Test.Support.Factories.Predictions.Prediction alias DotcomWeb.ScheduleController.TripInfo alias Schedules.{Schedule, Trip} diff --git a/test/leaflet/map_data/polyline_test.exs b/test/leaflet/map_data/polyline_test.exs index f9a19afa21..5b26bafaeb 100644 --- a/test/leaflet/map_data/polyline_test.exs +++ b/test/leaflet/map_data/polyline_test.exs @@ -1,7 +1,7 @@ defmodule Leaflet.MapData.PolylineTest do use ExUnit.Case, async: true - import Test.Support.Factory.RoutePattern + import Test.Support.Factories.RoutePatterns.RoutePattern alias Leaflet.MapData.Polyline diff --git a/test/predicted_schedule_test.exs b/test/predicted_schedule_test.exs index f09d3753a9..bb5090726c 100644 --- a/test/predicted_schedule_test.exs +++ b/test/predicted_schedule_test.exs @@ -8,7 +8,7 @@ defmodule PredictedScheduleTest do import PredictedSchedule import Mock import Mox - import Test.Support.Factory.Prediction + import Test.Support.Factories.Predictions.Prediction # set to the end of a month to uncover issues with sorting times as # structs, rather than as integers diff --git a/test/predictions/repo_test.exs b/test/predictions/repo_test.exs index 60804c06d2..ee86f84f7a 100644 --- a/test/predictions/repo_test.exs +++ b/test/predictions/repo_test.exs @@ -2,7 +2,7 @@ defmodule Predictions.RepoTest do use ExUnit.Case, async: true import Mox - import Test.Support.Factory.MbtaApi + import Test.Support.Factories.Mbta.Api alias Predictions.Repo alias Routes.Route diff --git a/test/predictions/stream_topic_test.exs b/test/predictions/stream_topic_test.exs index a32591bba2..da3f6b30c5 100644 --- a/test/predictions/stream_topic_test.exs +++ b/test/predictions/stream_topic_test.exs @@ -7,7 +7,7 @@ defmodule Predictions.StreamTopicTest do import Mox import Predictions.StreamTopic - import Test.Support.Factory.RoutePattern + import Test.Support.Factories.RoutePatterns.RoutePattern alias Predictions.StreamTopic diff --git a/test/route_patterns/repo_test.exs b/test/route_patterns/repo_test.exs index 92697dbb6c..6d7a3b315d 100644 --- a/test/route_patterns/repo_test.exs +++ b/test/route_patterns/repo_test.exs @@ -2,7 +2,7 @@ defmodule RoutePatterns.RepoTest do use ExUnit.Case, async: true import Mox - import Test.Support.Factory.MbtaApi + import Test.Support.Factories.Mbta.Api alias RoutePatterns.RoutePattern diff --git a/test/stops/nearby_test.exs b/test/stops/nearby_test.exs index e69c0a2dcb..259d1597d0 100644 --- a/test/stops/nearby_test.exs +++ b/test/stops/nearby_test.exs @@ -6,7 +6,7 @@ defmodule Stops.NearbyTest do import Mox import Stops.Nearby - import Test.Support.Factory.MbtaApi + import Test.Support.Factories.Mbta.Api @latitude 42.577 @longitude -71.225 diff --git a/test/stops/repo_test.exs b/test/stops/repo_test.exs index 5a4854c4fb..c877e855af 100644 --- a/test/stops/repo_test.exs +++ b/test/stops/repo_test.exs @@ -3,7 +3,7 @@ defmodule Stops.RepoTest do import Mox import Stops.Repo - import Test.Support.Factory.MbtaApi + import Test.Support.Factories.Mbta.Api alias Stops.Stop @direction_id Faker.Util.pick([0, 1]) diff --git a/test/stops/route_stops_test.exs b/test/stops/route_stops_test.exs index a1039d43d3..f19fcbd073 100644 --- a/test/stops/route_stops_test.exs +++ b/test/stops/route_stops_test.exs @@ -2,7 +2,7 @@ defmodule Stops.RouteStopsTest do use ExUnit.Case, async: true import Mox - import Test.Support.Factory.MbtaApi + import Test.Support.Factories.Mbta.Api alias Routes.Route alias Stops.{RouteStop, RouteStops, Stop} diff --git a/test/support/factories/alerts/alert.ex b/test/support/factories/alerts/alert.ex new file mode 100644 index 0000000000..c31ca13e0d --- /dev/null +++ b/test/support/factories/alerts/alert.ex @@ -0,0 +1,29 @@ +defmodule Test.Support.Factories.Alerts.Alert do + @moduledoc """ + Generated fake data for %Alerts.Alert{} + """ + + use ExMachina + + alias Alerts.{Alert, Priority} + alias Test.Support.Factories.Alerts.InformedEntitySet + + def alert_factory do + %Alert{ + id: :rand.uniform(999) |> Integer.to_string(), + active_period: {Faker.DateTime.backward(1), Faker.DateTime.forward(1)}, + banner: Faker.Lorem.Shakespeare.king_richard_iii(), + cause: Faker.Lorem.Shakespeare.king_richard_iii(), + description: Faker.Lorem.Shakespeare.king_richard_iii(), + effect: Alert.all_types() |> Faker.Util.pick(), + header: Faker.Lorem.Shakespeare.king_richard_iii(), + image_url: Faker.Internet.image_url(), + informed_entity: InformedEntitySet.build(:informed_entity_set), + lifecycle: Alert.lifecycles() |> Faker.Util.pick(), + priority: Priority.priority_levels() |> Faker.Util.pick(), + severity: :rand.uniform(10), + updated_at: Timex.now(), + url: Faker.Internet.url() + } + end +end diff --git a/test/support/factories/alerts/informed_entity.ex b/test/support/factories/alerts/informed_entity.ex new file mode 100644 index 0000000000..f896b0f235 --- /dev/null +++ b/test/support/factories/alerts/informed_entity.ex @@ -0,0 +1,22 @@ +defmodule Test.Support.Factories.Alerts.InformedEntity do + @moduledoc """ + Generated fake data for %Alerts.InformedEntity{} + """ + + use ExMachina + + alias Test.Support.Factories.Alerts.InformedEntity + alias Alerts.InformedEntity + + def informed_entity_factory do + %InformedEntity{ + route: Faker.Lorem.word(), + route_type: Faker.Lorem.word(), + stop: Faker.Lorem.word(), + trip: Faker.Lorem.word(), + direction_id: Faker.Util.pick([0, 1]), + facility: Faker.Lorem.word(), + activities: InformedEntity.activities() |> Enum.take_random(3) + } + end +end diff --git a/test/support/factories/alerts/informed_entity_set.ex b/test/support/factories/alerts/informed_entity_set.ex new file mode 100644 index 0000000000..e8fb2be375 --- /dev/null +++ b/test/support/factories/alerts/informed_entity_set.ex @@ -0,0 +1,15 @@ +defmodule Test.Support.Factories.Alerts.InformedEntitySet do + @moduledoc """ + Generated fake data for %Alerts.InformedEntitySet{} + """ + + use ExMachina + + alias Alerts.InformedEntitySet + alias Test.Support.Factories.Alerts.InformedEntity + + def informed_entity_set_factory do + InformedEntity.build_list(3, :informed_entity) + |> InformedEntitySet.new() + end +end diff --git a/test/support/factory/mbta_api.ex b/test/support/factories/mbta/api.ex similarity index 99% rename from test/support/factory/mbta_api.ex rename to test/support/factories/mbta/api.ex index 9a3653e85e..8fa16c9d01 100644 --- a/test/support/factory/mbta_api.ex +++ b/test/support/factories/mbta/api.ex @@ -1,4 +1,4 @@ -defmodule Test.Support.Factory.MbtaApi do +defmodule Test.Support.Factories.Mbta.Api do @moduledoc """ Generated fake data for MBTA.Api """ diff --git a/test/support/factory/prediction.ex b/test/support/factories/predictions/prediction.ex similarity index 74% rename from test/support/factory/prediction.ex rename to test/support/factories/predictions/prediction.ex index 057b21ba71..cc5d7176dc 100644 --- a/test/support/factory/prediction.ex +++ b/test/support/factories/predictions/prediction.ex @@ -1,4 +1,4 @@ -defmodule Test.Support.Factory.Prediction do +defmodule Test.Support.Factories.Predictions.Prediction do @moduledoc """ Generated fake data for %RoutePattern{} """ diff --git a/test/support/factory/route_pattern.ex b/test/support/factories/route_patterns/route_pattern.ex similarity index 73% rename from test/support/factory/route_pattern.ex rename to test/support/factories/route_patterns/route_pattern.ex index 4c08fabc87..df9f941757 100644 --- a/test/support/factory/route_pattern.ex +++ b/test/support/factories/route_patterns/route_pattern.ex @@ -1,4 +1,4 @@ -defmodule Test.Support.Factory.RoutePattern do +defmodule Test.Support.Factories.RoutePatterns.RoutePattern do @moduledoc """ Generated fake data for %RoutePattern{} """ From f867f71b2034dc56c6b7fd64d6c2cda7e7d248f6 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Mon, 20 May 2024 08:42:03 -0500 Subject: [PATCH 02/24] images are showing up in diversion alerts --- lib/alerts/alert.ex | 2 +- lib/alerts/repo.ex | 30 +++++++++ lib/cms/helpers.ex | 17 +++++ lib/cms/page.ex | 5 ++ lib/cms/page/diversions.ex | 64 +++++++++++++++++++ lib/dotcom_web/controllers/cms_controller.ex | 12 ++++ lib/dotcom_web/templates/alert/_item.html.eex | 5 ++ .../templates/cms/diversions.html.eex | 3 + .../templates/cms/page/_diversions.html.eex | 27 ++++++++ lib/dotcom_web/views/page_content_view.ex | 16 +++++ 10 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 lib/cms/page/diversions.ex create mode 100644 lib/dotcom_web/templates/cms/diversions.html.eex create mode 100644 lib/dotcom_web/templates/cms/page/_diversions.html.eex diff --git a/lib/alerts/alert.ex b/lib/alerts/alert.ex index 0258ea38e8..15cfcd57a8 100644 --- a/lib/alerts/alert.ex +++ b/lib/alerts/alert.ex @@ -14,7 +14,7 @@ defmodule Alerts.Alert do description: "", effect: :unknown, header: "", - image_url: "", + image_url: nil, informed_entity: %InformedEntitySet{}, lifecycle: :unknown, priority: :low, diff --git a/lib/alerts/repo.ex b/lib/alerts/repo.ex index a712b11550..3e44cdf7bc 100644 --- a/lib/alerts/repo.ex +++ b/lib/alerts/repo.ex @@ -17,6 +17,11 @@ defmodule Alerts.Repo do Store.alert(id) end + @spec by_route_id(String.t(), DateTime.t()) :: [Alert.t()] + def by_route_id(route_id, now) do + by_route_ids([route_id], now) + end + @spec by_route_ids([String.t()], DateTime.t()) :: [Alert.t()] def by_route_ids([], _now) do [] @@ -28,6 +33,15 @@ defmodule Alerts.Repo do |> Store.alerts(now) end + def diversions_by_route_ids(route_ids, now) do + route_ids + |> by_route_ids(now) + |> Enum.filter(fn alert -> + Enum.member?([:shuttle, :station_closure, :suspension], alert.effect) + end) + |> Enum.map(&maybe_attach_image_url/1) + end + @spec by_route_types(Enumerable.t(), DateTime.t()) :: [Alert.t()] def by_route_types(types, now) do types @@ -55,4 +69,20 @@ defmodule Alerts.Repo do |> Store.all_alerts() |> Enum.filter(&(&1.priority == priority)) end + + # This function is used to attach an image URL to an alert if it doesn't already have one. + # + defp maybe_attach_image_url(alert) do + if is_nil(alert.image_url) do + cms_api_base_url = Application.get_env(:dotcom, :cms_api)[:base_url] + this_month = Timex.format!(Timex.now(), "%Y-%m", :strftime) + + image_url = + cms_api_base_url <> "/sites/default/files/media/#{this_month}/alert-#{alert.id}.png" + + Map.put(alert, :image_url, image_url) + else + alert + end + end end diff --git a/lib/cms/helpers.ex b/lib/cms/helpers.ex index 421077ad79..c42ab8091c 100644 --- a/lib/cms/helpers.ex +++ b/lib/cms/helpers.ex @@ -69,6 +69,23 @@ defmodule CMS.Helpers do |> Enum.map(&File.from_api/1) end + @spec parse_page_types(map) :: list(String.t()) + def parse_page_types(%{} = data) do + data + |> Map.get("field_page_type", []) + |> Enum.map(&Map.get(&1, "name")) + |> Enum.filter(&(!is_nil(&1))) + |> Enum.map(&String.downcase/1) + end + + @spec parse_related_transit(map) :: list(String.t()) + def parse_related_transit(%{} = data) do + data + |> Map.get("field_related_transit", []) + |> Enum.map(&Map.get(&1, "name")) + |> Enum.filter(&(!is_nil(&1))) + end + @spec path_alias(map) :: String.t() | nil def path_alias(data) do data diff --git a/lib/cms/page.ex b/lib/cms/page.ex index a44b402f44..d0579768a5 100644 --- a/lib/cms/page.ex +++ b/lib/cms/page.ex @@ -10,6 +10,7 @@ defmodule CMS.Page do alias CMS.Page.{ Basic, + Diversions, Event, EventAgenda, Landing, @@ -73,6 +74,10 @@ defmodule CMS.Page do Redirect.from_api(api_data) end + defp parse(%{"field_page_type" => [%{"name" => "Diversions"}]} = api_data, preview_opts) do + Diversions.from_api(api_data, preview_opts) + end + # For all other node/content types from the CMS, use a common struct/template defp parse(%{"type" => [%{"target_type" => "node_type"}]} = api_data, preview_opts) do Basic.from_api(api_data, preview_opts) diff --git a/lib/cms/page/diversions.ex b/lib/cms/page/diversions.ex new file mode 100644 index 0000000000..7a1c8ab298 --- /dev/null +++ b/lib/cms/page/diversions.ex @@ -0,0 +1,64 @@ +defmodule CMS.Page.Diversions do + @moduledoc """ + Represents a basic "page" type in the Drupal CMS. Multiple + content types can use this struct, as defined in CMS.Page.Basic + """ + + alias CMS.Breadcrumbs + alias CMS.Partial.{MenuLinks, Paragraph} + alias Phoenix.HTML + + import CMS.Helpers, + only: [ + field_value: 2, + int_or_string_to_int: 1, + parse_body: 1, + parse_page_types: 1, + parse_paragraphs: 2, + parse_related_transit: 1 + ] + + defstruct id: nil, + body: HTML.raw(""), + breadcrumbs: [], + page_types: [], + paragraphs: [], + related_transit: [], + sidebar_menu: nil, + title: "" + + @type t :: %__MODULE__{ + id: integer | nil, + body: HTML.safe(), + breadcrumbs: [Util.Breadcrumb.t()], + page_types: [String.t()], + paragraphs: [Paragraph.t()], + related_transit: [String.t()], + sidebar_menu: MenuLinks.t() | nil, + title: String.t() + } + + @spec from_api(map, Keyword.t()) :: t + def from_api(%{} = data, preview_opts \\ []) do + %__MODULE__{ + id: int_or_string_to_int(field_value(data, "nid")), + body: parse_body(data), + breadcrumbs: Breadcrumbs.build(data), + page_types: parse_page_types(data), + paragraphs: parse_paragraphs(data, preview_opts), + related_transit: parse_related_transit(data), + sidebar_menu: parse_menu_links(data), + title: field_value(data, "title") || "" + } + end + + @spec parse_menu_links(map) :: MenuLinks.t() | nil + defp parse_menu_links(%{"field_sidebar_menu" => [menu_links_data]}) + when not is_nil(menu_links_data) do + MenuLinks.from_api(menu_links_data) + end + + defp parse_menu_links(_) do + nil + end +end diff --git a/lib/dotcom_web/controllers/cms_controller.ex b/lib/dotcom_web/controllers/cms_controller.ex index f4d637bbe9..a2e83126ba 100644 --- a/lib/dotcom_web/controllers/cms_controller.ex +++ b/lib/dotcom_web/controllers/cms_controller.ex @@ -19,6 +19,7 @@ defmodule DotcomWeb.CMSController do @generic [ Page.Basic, + Page.Diversions, Page.Person, Page.Landing, Page.Project, @@ -137,6 +138,17 @@ defmodule DotcomWeb.CMSController do end end + defp render_page(conn, %Page.Diversions{} = page) do + conn + |> assign( + :alerts, + Alerts.Repo.diversions_by_route_ids(page.related_transit, conn.assigns.date_time) + ) + |> assign(:breadcrumbs, page.breadcrumbs) + |> assign(:page, page) + |> render("diversions.html", conn: conn) + end + defp render_page(conn, %Page.Basic{} = page) do render_generic(conn, page, page.breadcrumbs) end diff --git a/lib/dotcom_web/templates/alert/_item.html.eex b/lib/dotcom_web/templates/alert/_item.html.eex index 7f92c9d666..75bc037e60 100644 --- a/lib/dotcom_web/templates/alert/_item.html.eex +++ b/lib/dotcom_web/templates/alert/_item.html.eex @@ -28,6 +28,11 @@ <%= if @alert.description do %>
+ <%= if @alert.image_url do %> +
+ <%= effect_name(@alert) %> +
+ <% end %>
<%= format_alert_description(@alert.description) %> diff --git a/lib/dotcom_web/templates/cms/diversions.html.eex b/lib/dotcom_web/templates/cms/diversions.html.eex new file mode 100644 index 0000000000..d5290e6a63 --- /dev/null +++ b/lib/dotcom_web/templates/cms/diversions.html.eex @@ -0,0 +1,3 @@ +
+ <%= DotcomWeb.CMS.PageView.render_page(@page, @conn) %> +
diff --git a/lib/dotcom_web/templates/cms/page/_diversions.html.eex b/lib/dotcom_web/templates/cms/page/_diversions.html.eex new file mode 100644 index 0000000000..e8b897aa9b --- /dev/null +++ b/lib/dotcom_web/templates/cms/page/_diversions.html.eex @@ -0,0 +1,27 @@ +
+ +
+
+

+ <%= @page.title %> +

+
+
+ +
+ <%# Sidebar Left %> + <%= if @sidebar_left, do: DotcomWeb.CMSView.render("_sidebar_left.html", page: @page, conn: @conn) %> + + <%# Main Content %> +
+ <%= render_page_content(@page, @conn) %> + +

Diversions

+ <%= DotcomWeb.AlertView.render("group.html", alerts: @conn.assigns.alerts, date_time: @conn.assigns.date_time) %> +
+ + <%# Sidebar Right %> + <%= if !@sidebar_left && @sidebar_right, do: DotcomWeb.CMSView.render("_sidebar_right.html", page: @page, conn: @conn) %> +
+ +
diff --git a/lib/dotcom_web/views/page_content_view.ex b/lib/dotcom_web/views/page_content_view.ex index e93c8eed82..82536766c3 100644 --- a/lib/dotcom_web/views/page_content_view.ex +++ b/lib/dotcom_web/views/page_content_view.ex @@ -13,6 +13,22 @@ defmodule DotcomWeb.CMS.PageView do @doc "Universal wrapper for CMS page content" @spec render_page(Page.t(), Conn.t()) :: Phoenix.HTML.safe() + + def render_page(%CMS.Page.Diversions{} = page, conn) do + sidebar_left = Map.has_key?(page, :sidebar_menu) && !is_nil(page.sidebar_menu) + sidebar_right = has_right_rail?(page) + sidebar_layout = sidebar_classes(sidebar_left, sidebar_right) + + render( + "_diversions.html", + page: page, + sidebar_left: sidebar_left, + sidebar_right: sidebar_right, + sidebar_class: sidebar_layout, + conn: conn + ) + end + def render_page(page, conn) do sidebar_left = Map.has_key?(page, :sidebar_menu) && !is_nil(page.sidebar_menu) sidebar_right = has_right_rail?(page) From 1e477185ac2d52f3f25a538d9495f3a5dea29a63 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Mon, 20 May 2024 10:45:13 -0500 Subject: [PATCH 03/24] tests --- lib/alerts/repo.ex | 11 ++-- lib/cms/helpers.ex | 1 - .../templates/cms/page/_diversions.html.eex | 2 +- test/alerts/alerts_test.exs | 12 +++++ test/alerts/informed_entity_test.exs | 11 ++++ test/alerts/priority_test.exs | 10 ++++ test/alerts/repo_test.exs | 53 +++++++++++++++++-- test/cms/helpers_test.exs | 37 +++++++++++++ test/cms/page/diversions_test.exs | 50 +++++++++++++++++ test/cms/page_test.exs | 6 +++ .../views/page_content_view_test.exs | 20 ++++++- test/support/factories/alerts/alert.ex | 2 +- .../factories/alerts/informed_entity_set.ex | 5 +- 13 files changed, 206 insertions(+), 14 deletions(-) create mode 100644 test/alerts/informed_entity_test.exs create mode 100644 test/cms/page/diversions_test.exs diff --git a/lib/alerts/repo.ex b/lib/alerts/repo.ex index 3e44cdf7bc..4d4011dab0 100644 --- a/lib/alerts/repo.ex +++ b/lib/alerts/repo.ex @@ -17,11 +17,6 @@ defmodule Alerts.Repo do Store.alert(id) end - @spec by_route_id(String.t(), DateTime.t()) :: [Alert.t()] - def by_route_id(route_id, now) do - by_route_ids([route_id], now) - end - @spec by_route_ids([String.t()], DateTime.t()) :: [Alert.t()] def by_route_ids([], _now) do [] @@ -33,6 +28,12 @@ defmodule Alerts.Repo do |> Store.alerts(now) end + @doc """ + Get alerts that are diversion types: shuttle, station_closure, suspension. + + Try to attach an image URL to the alert if it doesn't already have one. + """ + @spec diversions_by_route_ids([String.t()], DateTime.t()) :: [Alert.t()] def diversions_by_route_ids(route_ids, now) do route_ids |> by_route_ids(now) diff --git a/lib/cms/helpers.ex b/lib/cms/helpers.ex index c42ab8091c..3022960b29 100644 --- a/lib/cms/helpers.ex +++ b/lib/cms/helpers.ex @@ -75,7 +75,6 @@ defmodule CMS.Helpers do |> Map.get("field_page_type", []) |> Enum.map(&Map.get(&1, "name")) |> Enum.filter(&(!is_nil(&1))) - |> Enum.map(&String.downcase/1) end @spec parse_related_transit(map) :: list(String.t()) diff --git a/lib/dotcom_web/templates/cms/page/_diversions.html.eex b/lib/dotcom_web/templates/cms/page/_diversions.html.eex index e8b897aa9b..9e46016d94 100644 --- a/lib/dotcom_web/templates/cms/page/_diversions.html.eex +++ b/lib/dotcom_web/templates/cms/page/_diversions.html.eex @@ -17,7 +17,7 @@ <%= render_page_content(@page, @conn) %>

Diversions

- <%= DotcomWeb.AlertView.render("group.html", alerts: @conn.assigns.alerts, date_time: @conn.assigns.date_time) %> + <%= DotcomWeb.AlertView.render("group.html", alerts: Map.get(@conn.assigns, :alerts, []), date_time: Map.get(@conn.assigns, :date_time, Timex.now())) %>
<%# Sidebar Right %> diff --git a/test/alerts/alerts_test.exs b/test/alerts/alerts_test.exs index 33ee9c9407..ed52cd1132 100644 --- a/test/alerts/alerts_test.exs +++ b/test/alerts/alerts_test.exs @@ -24,6 +24,18 @@ defmodule AlertsTest do end end + describe "ongoing_effects/0" do + test "returs a list" do + assert is_list(ongoing_effects()) + end + end + + describe "lifecycles/0" do + test "returns a list" do + assert is_list(lifecycles()) + end + end + describe "update/2" do test "updates an existing alert, keeping the old values" do alert = new(effect: :detour) diff --git a/test/alerts/informed_entity_test.exs b/test/alerts/informed_entity_test.exs new file mode 100644 index 0000000000..ea8a26b90b --- /dev/null +++ b/test/alerts/informed_entity_test.exs @@ -0,0 +1,11 @@ +defmodule Alerts.InformedEntityTest do + use ExUnit.Case, async: true + + alias Alerts.InformedEntity + + describe "activities/0" do + test "returns a list" do + assert is_list(InformedEntity.activities()) + end + end +end diff --git a/test/alerts/priority_test.exs b/test/alerts/priority_test.exs index 45e25bc338..f0b65e4ab6 100644 --- a/test/alerts/priority_test.exs +++ b/test/alerts/priority_test.exs @@ -8,6 +8,12 @@ defmodule Alerts.PriorityTest do @now Util.to_local_time(~N[2018-01-15T12:00:00]) + describe "priority_levels/0" do + test "returns a list" do + assert is_list(priority_levels()) + end + end + describe "priority/2" do test "Delay alerts are low if severity is under 5 and the route type is bus and the cause is traffic" do alert = %Alert{ @@ -372,6 +378,10 @@ defmodule Alerts.PriorityTest do end describe "urgent_period?/2" do + test "returns false when given no information" do + assert urgent_period?({nil, nil}, @now) == true + end + test "severe alerts within 1 week of end date are urgent" do now = ~N[2018-01-15T12:00:00] |> Util.to_local_time() start_date = Timex.shift(now, days: -10) diff --git a/test/alerts/repo_test.exs b/test/alerts/repo_test.exs index 9afcbc6f43..e36e710e1f 100644 --- a/test/alerts/repo_test.exs +++ b/test/alerts/repo_test.exs @@ -1,11 +1,14 @@ defmodule Alerts.RepoTest do use ExUnit.Case - alias Alerts.{Alert, Banner, Cache.Store, InformedEntity, Repo, InformedEntitySet} - @now Timex.parse!("2017-06-08T10:00:00-05:00", "{ISO:Extended}") + alias Alerts.{Alert, Banner, Cache.Store, InformedEntity, InformedEntitySet, Repo} + alias Test.Support.Factories + + @now Timex.now() setup_all do start_supervised(Store) + :ok end @@ -38,7 +41,7 @@ defmodule Alerts.RepoTest do end end - describe "by_route_ids/1" do + describe "by_route_ids/2" do @orange_entity %InformedEntity{route: "Orange"} @red_entity %InformedEntity{route: "Red"} @blue_entity %InformedEntity{route: "Blue"} @@ -54,6 +57,50 @@ defmodule Alerts.RepoTest do assert red_alert in alerts refute blue_alert in alerts end + + test "returns an empty list of alerts when given an empty list of ids" do + assert [] = Repo.by_route_ids([], @now) + end + end + + describe "diversions_by_route_id/2" do + test "returns only diversions for the given route_ids" do + # Setup + diversion = Factories.Alerts.Alert.build(:alert, effect: :shuttle) + non_diversion = Factories.Alerts.Alert.build(:alert, effect: :delay) + + Store.update([diversion, non_diversion], nil) + + diversion_route = + diversion.informed_entity.route |> MapSet.to_list() |> List.first() + + non_diversion_route = + non_diversion.informed_entity.route |> MapSet.to_list() |> List.first() + + # Exercise + diversions = + Repo.diversions_by_route_ids([diversion_route, non_diversion_route], Timex.now()) + + # Verify + assert [^diversion] = diversions + end + + test "attaches an image url to the alert if it doesn't already have one" do + # Setup + diversion = Factories.Alerts.Alert.build(:alert, effect: :shuttle, image_url: nil) + + Store.update([diversion], nil) + + diversion_route = + diversion.informed_entity.route |> MapSet.to_list() |> List.first() + + # Exercise + diversions = + Repo.diversions_by_route_ids([diversion_route], Timex.now()) + + # Verify + assert diversions |> List.first() |> Map.get(:image_url) != nil + end end describe "by_route_types/1" do diff --git a/test/cms/helpers_test.exs b/test/cms/helpers_test.exs index c94ca9e30f..49ab8b5d34 100644 --- a/test/cms/helpers_test.exs +++ b/test/cms/helpers_test.exs @@ -1,5 +1,6 @@ defmodule CMS.HelpersTest do use ExUnit.Case, async: true + import CMS.Helpers alias CMS.Helpers @@ -7,6 +8,42 @@ defmodule CMS.HelpersTest do doctest CMS.Helpers + describe "parse_page_types/1" do + test "it parses the page type" do + # Setup + page_type = Faker.Cat.breed() + + data = %{ + "field_page_type" => [ + %{ + "name" => page_type + } + ] + } + + # Exercise / Verify + assert [^page_type] = parse_page_types(data) + end + end + + describe "parse_related_transit/1" do + test "it parses the related transit data" do + # Setup + related_transit = Faker.Cat.breed() + + data = %{ + "field_related_transit" => [ + %{ + "name" => related_transit + } + ] + } + + # Exercise / Verify + assert [^related_transit] = parse_related_transit(data) + end + end + describe "handle_html/1" do test "removes unsafe html tags from safe content" do html = "

hello!

" diff --git a/test/cms/page/diversions_test.exs b/test/cms/page/diversions_test.exs new file mode 100644 index 0000000000..c0eeb5ddab --- /dev/null +++ b/test/cms/page/diversions_test.exs @@ -0,0 +1,50 @@ +defmodule CMS.Page.DiversionsTest do + use ExUnit.Case, async: true + + import CMS.APITestHelpers, only: [update_api_response: 3] + + alias CMS.Api.Static + alias CMS.Page.Diversions + alias CMS.Partial.MenuLinks + alias Phoenix.HTML + + setup do + %{ + api_page: + Static.basic_page_response() |> Map.put("field_page_type", [%{"name" => "Diversions"}]) + } + end + + describe "from_api/1" do + test "it parses the api response", %{api_page: api_page} do + assert %Diversions{ + id: id, + body: body, + title: title + } = Diversions.from_api(api_page) + + assert id == 3195 + assert HTML.safe_to_string(body) =~ "

The MBTA permits musical performances" + assert title == "Arts on the T" + end + + test "it strips out script tags", %{api_page: api_page} do + api_page = update_api_response(api_page, "body", "

Hi

") + + assert %Diversions{body: body} = Diversions.from_api(api_page) + assert HTML.safe_to_string(body) == "alert()

Hi

" + end + + test "it parses a sidebar menu" do + api_page = Static.basic_page_with_sidebar_response() + + assert %Diversions{ + sidebar_menu: %MenuLinks{ + blurb: + {:safe, + "

Visiting Boston? Learn more about some of the popular spots you can get to on the T.

"} + } + } = Diversions.from_api(api_page) + end + end +end diff --git a/test/cms/page_test.exs b/test/cms/page_test.exs index 9fbc1f3981..7ccfaaa0f8 100644 --- a/test/cms/page_test.exs +++ b/test/cms/page_test.exs @@ -11,6 +11,12 @@ defmodule PageTest do describe "from_api/1" do test "switches on the node type in the json response and returns the proper page struct" do assert %Page.Basic{} = Page.from_api(Static.basic_page_response()) + + diversions_data = + Static.basic_page_response() |> Map.put("field_page_type", [%{"name" => "Diversions"}]) + + assert %Page.Diversions{} = Page.from_api(diversions_data) + assert %Page.Event{} = Page.from_api(List.first(Static.events_response())) assert %Page.Landing{} = Page.from_api(Static.landing_page_response()) assert %Page.NewsEntry{} = Page.from_api(List.first(Static.news_repo())) diff --git a/test/dotcom_web/views/page_content_view_test.exs b/test/dotcom_web/views/page_content_view_test.exs index c03695136b..5ddb60eb81 100644 --- a/test/dotcom_web/views/page_content_view_test.exs +++ b/test/dotcom_web/views/page_content_view_test.exs @@ -3,7 +3,7 @@ defmodule DotcomWeb.CMS.PageViewTest do import DotcomWeb.CMS.PageView - alias CMS.Page.{Basic, Project} + alias CMS.Page.{Basic, Diversions, Project} alias CMS.Partial.Paragraph.{ContentList, CustomHTML} alias Phoenix.HTML @@ -18,6 +18,24 @@ defmodule DotcomWeb.CMS.PageViewTest do assert rendered =~ "

Hello

" end + + test "renders a CMS.Page.Diversions with sub-templates", %{conn: conn} do + # Setup + food = Faker.Food.description() + + paragraph = %Diversions{ + body: HTML.raw("

#{food}

") + } + + # Exercise + rendered = + paragraph + |> render_page(conn) + |> HTML.safe_to_string() + + # Verify + assert rendered =~ "

#{food}

" + end end describe "sidebar_classes/2" do diff --git a/test/support/factories/alerts/alert.ex b/test/support/factories/alerts/alert.ex index c31ca13e0d..6394199faa 100644 --- a/test/support/factories/alerts/alert.ex +++ b/test/support/factories/alerts/alert.ex @@ -11,7 +11,7 @@ defmodule Test.Support.Factories.Alerts.Alert do def alert_factory do %Alert{ id: :rand.uniform(999) |> Integer.to_string(), - active_period: {Faker.DateTime.backward(1), Faker.DateTime.forward(1)}, + active_period: [Faker.DateTime.backward(1), Faker.DateTime.forward(1)], banner: Faker.Lorem.Shakespeare.king_richard_iii(), cause: Faker.Lorem.Shakespeare.king_richard_iii(), description: Faker.Lorem.Shakespeare.king_richard_iii(), diff --git a/test/support/factories/alerts/informed_entity_set.ex b/test/support/factories/alerts/informed_entity_set.ex index e8fb2be375..a48641b158 100644 --- a/test/support/factories/alerts/informed_entity_set.ex +++ b/test/support/factories/alerts/informed_entity_set.ex @@ -9,7 +9,8 @@ defmodule Test.Support.Factories.Alerts.InformedEntitySet do alias Test.Support.Factories.Alerts.InformedEntity def informed_entity_set_factory do - InformedEntity.build_list(3, :informed_entity) - |> InformedEntitySet.new() + informed_entity = InformedEntity.build(:informed_entity) + + InformedEntitySet.new([informed_entity]) end end From 15361c4b3101720e5bea8b0ee6a95c6af6230e19 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Mon, 20 May 2024 11:09:53 -0500 Subject: [PATCH 04/24] use relative path and css for image --- assets/css/_alerts.scss | 6 ++++++ lib/alerts/repo.ex | 5 +---- lib/dotcom_web/templates/alert/_item.html.eex | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/assets/css/_alerts.scss b/assets/css/_alerts.scss index eaec1b8980..0049eb22a5 100644 --- a/assets/css/_alerts.scss +++ b/assets/css/_alerts.scss @@ -169,6 +169,12 @@ margin-top: $space-12; } +.c-alert-item__image { + img { + width: 100%; + } +} + .m-alerts__mode-buttons { display: flex; margin-left: calc(-#{$grid-gutter-width} / 4); diff --git a/lib/alerts/repo.ex b/lib/alerts/repo.ex index 4d4011dab0..db2f63d1fc 100644 --- a/lib/alerts/repo.ex +++ b/lib/alerts/repo.ex @@ -75,11 +75,8 @@ defmodule Alerts.Repo do # defp maybe_attach_image_url(alert) do if is_nil(alert.image_url) do - cms_api_base_url = Application.get_env(:dotcom, :cms_api)[:base_url] this_month = Timex.format!(Timex.now(), "%Y-%m", :strftime) - - image_url = - cms_api_base_url <> "/sites/default/files/media/#{this_month}/alert-#{alert.id}.png" + image_url = "/sites/default/files/media/#{this_month}/alert-#{alert.id}.png" Map.put(alert, :image_url, image_url) else diff --git a/lib/dotcom_web/templates/alert/_item.html.eex b/lib/dotcom_web/templates/alert/_item.html.eex index 75bc037e60..735b08cab1 100644 --- a/lib/dotcom_web/templates/alert/_item.html.eex +++ b/lib/dotcom_web/templates/alert/_item.html.eex @@ -30,7 +30,7 @@
<%= if @alert.image_url do %>
- <%= effect_name(@alert) %> + <%= effect_name(@alert) %>
<% end %>
From 23e3cb58f93c3c23ea52a341169cfeac497f4e07 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Mon, 20 May 2024 11:16:34 -0500 Subject: [PATCH 05/24] alpha --- test/support/factories/alerts/informed_entity.ex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/support/factories/alerts/informed_entity.ex b/test/support/factories/alerts/informed_entity.ex index f896b0f235..3e2a68bb00 100644 --- a/test/support/factories/alerts/informed_entity.ex +++ b/test/support/factories/alerts/informed_entity.ex @@ -10,13 +10,13 @@ defmodule Test.Support.Factories.Alerts.InformedEntity do def informed_entity_factory do %InformedEntity{ + activities: InformedEntity.activities() |> Enum.take_random(3), + direction_id: Faker.Util.pick([0, 1]), + facility: Faker.Lorem.word(), route: Faker.Lorem.word(), route_type: Faker.Lorem.word(), stop: Faker.Lorem.word(), - trip: Faker.Lorem.word(), - direction_id: Faker.Util.pick([0, 1]), - facility: Faker.Lorem.word(), - activities: InformedEntity.activities() |> Enum.take_random(3) + trip: Faker.Lorem.word() } end end From 796182942370c0b0a3c763bfa578d070ea1e5d80 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Mon, 20 May 2024 11:19:15 -0500 Subject: [PATCH 06/24] docs --- lib/alerts/repo.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/alerts/repo.ex b/lib/alerts/repo.ex index db2f63d1fc..6a5dd9be86 100644 --- a/lib/alerts/repo.ex +++ b/lib/alerts/repo.ex @@ -72,7 +72,7 @@ defmodule Alerts.Repo do end # This function is used to attach an image URL to an alert if it doesn't already have one. - # + # It should be removed once alerts support image URLs. defp maybe_attach_image_url(alert) do if is_nil(alert.image_url) do this_month = Timex.format!(Timex.now(), "%Y-%m", :strftime) From e4355ef98c479a1e1bad9b9815b96f1bd855d623 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Mon, 20 May 2024 14:55:26 -0500 Subject: [PATCH 07/24] typo --- test/alerts/alerts_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/alerts/alerts_test.exs b/test/alerts/alerts_test.exs index ed52cd1132..216cac025d 100644 --- a/test/alerts/alerts_test.exs +++ b/test/alerts/alerts_test.exs @@ -25,7 +25,7 @@ defmodule AlertsTest do end describe "ongoing_effects/0" do - test "returs a list" do + test "returns a list" do assert is_list(ongoing_effects()) end end From c9fd7e673b40916882750dfead184fb9fb932ea4 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Wed, 22 May 2024 11:27:14 -0500 Subject: [PATCH 08/24] alt text and check created at time --- lib/alerts/alert.ex | 8 ++++-- lib/alerts/parser.ex | 25 +++++++++++++------ lib/dotcom_web/templates/alert/_item.html.eex | 6 ++--- .../templates/cms/page/_diversions.html.eex | 3 ++- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/lib/alerts/alert.ex b/lib/alerts/alert.ex index 15cfcd57a8..6f09643997 100644 --- a/lib/alerts/alert.ex +++ b/lib/alerts/alert.ex @@ -11,9 +11,11 @@ defmodule Alerts.Alert do active_period: [], banner: "", cause: "", + created_at: nil, description: "", effect: :unknown, header: "", + image_alt_text: "", image_url: nil, informed_entity: %InformedEntitySet{}, lifecycle: :unknown, @@ -252,8 +254,10 @@ defmodule Alerts.Alert do def high_severity_or_high_priority?(_), do: false @spec diversion?(t) :: boolean() - def diversion?(%{effect: effect}), - do: effect in @diversion_effects + def diversion?(alert) do + alert.effect in @diversion_effects && + Timex.before?(alert.created_at, alert.active_period[0]) + end @spec municipality(t) :: String.t() | nil def municipality(alert) do diff --git a/lib/alerts/parser.ex b/lib/alerts/parser.ex index 425583fbdc..b8a86d9939 100644 --- a/lib/alerts/parser.ex +++ b/lib/alerts/parser.ex @@ -10,17 +10,20 @@ defmodule Alerts.Parser do def parse(%JsonApi.Item{type: "alert", id: id, attributes: attributes}) do Alerts.Alert.new( id: id, - header: attributes["header"], - informed_entity: parse_informed_entity(attributes["informed_entity"]), active_period: Enum.map(attributes["active_period"], &active_period/1), - effect: effect(attributes), + banner: description(attributes["banner"]), cause: cause(attributes["cause"]), - severity: severity(attributes["severity"]), + created_at: parse_time(attributes["created_at"]), + description: description(attributes["description"]), + effect: effect(attributes), + header: attributes["header"], + image_alt_text: parse_informed_entity(attributes["informed_entity"]) |> create_alt_text(), + image_url: attributes["image_url"], + informed_entity: parse_informed_entity(attributes["informed_entity"]), lifecycle: lifecycle(attributes["lifecycle"]), + severity: severity(attributes["severity"]), updated_at: parse_time(attributes["updated_at"]), - description: description(attributes["description"]), - url: description(attributes["url"]), - banner: description(attributes["banner"]) + url: description(attributes["url"]) ) end @@ -214,6 +217,14 @@ defmodule Alerts.Parser do :unknown end end + + defp create_alt_text(informed_entities) do + informed_entities + |> Enum.map(& &1.route) + |> MapSet.new() + |> Enum.join(", ") + |> (fn routes -> "Line map of the " <> routes <> " route(s) closures" end).() + end end defmodule Banner do diff --git a/lib/dotcom_web/templates/alert/_item.html.eex b/lib/dotcom_web/templates/alert/_item.html.eex index 735b08cab1..009c49a896 100644 --- a/lib/dotcom_web/templates/alert/_item.html.eex +++ b/lib/dotcom_web/templates/alert/_item.html.eex @@ -28,9 +28,9 @@
<%= if @alert.description do %>
- <%= if @alert.image_url do %> -
- <%= effect_name(@alert) %> + <%= if @alert.image_url && @alert.image_alt_text do %> +
+ <%= @alert.image_alt_text %>
<% end %>
diff --git a/lib/dotcom_web/templates/cms/page/_diversions.html.eex b/lib/dotcom_web/templates/cms/page/_diversions.html.eex index 9e46016d94..fa6de9a141 100644 --- a/lib/dotcom_web/templates/cms/page/_diversions.html.eex +++ b/lib/dotcom_web/templates/cms/page/_diversions.html.eex @@ -16,7 +16,8 @@
<%= render_page_content(@page, @conn) %> -

Diversions

+
+ <%= DotcomWeb.AlertView.render("group.html", alerts: Map.get(@conn.assigns, :alerts, []), date_time: Map.get(@conn.assigns, :date_time, Timex.now())) %>
From 2b6ff177d7078fe2399f5da720c9c18b6ab84e48 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Wed, 22 May 2024 11:29:32 -0500 Subject: [PATCH 09/24] remove css --- assets/css/_alerts.scss | 6 ------ 1 file changed, 6 deletions(-) diff --git a/assets/css/_alerts.scss b/assets/css/_alerts.scss index 0049eb22a5..eaec1b8980 100644 --- a/assets/css/_alerts.scss +++ b/assets/css/_alerts.scss @@ -169,12 +169,6 @@ margin-top: $space-12; } -.c-alert-item__image { - img { - width: 100%; - } -} - .m-alerts__mode-buttons { display: flex; margin-left: calc(-#{$grid-gutter-width} / 4); From 839dd37a0a0929d09739b9e9e841027973469def Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Wed, 22 May 2024 12:00:22 -0500 Subject: [PATCH 10/24] renaming and tests --- lib/alerts/alert.ex | 2 +- test/alerts/alerts_test.exs | 67 +++++++++++-------- test/alerts/parser_test.exs | 3 +- test/dotcom/trip_plan/itinerary_row_test.exs | 4 +- test/dotcom/trip_plan/location_test.exs | 2 +- test/dotcom/trip_plan/query_test.exs | 2 +- .../vehicle_map_marker_channel_test.exs | 2 +- .../controllers/places_controller_test.exs | 2 +- .../schedule/line/helpers_test.exs | 2 +- .../transit_near_me/location_test.exs | 2 +- .../controllers/trip_plan_controller_test.exs | 7 +- test/predictions/repo_test.exs | 2 +- test/route_patterns/repo_test.exs | 2 +- test/stops/nearby_test.exs | 2 +- test/stops/repo_test.exs | 2 +- test/stops/route_stops_test.exs | 2 +- test/support/factories/alerts/alert.ex | 4 +- .../location_service}/location_service.ex | 2 +- test/support/factories/mbta/api.ex | 2 +- 19 files changed, 65 insertions(+), 48 deletions(-) rename test/support/{factory => factories/location_service}/location_service.ex (89%) diff --git a/lib/alerts/alert.ex b/lib/alerts/alert.ex index 6f09643997..3288608e8b 100644 --- a/lib/alerts/alert.ex +++ b/lib/alerts/alert.ex @@ -256,7 +256,7 @@ defmodule Alerts.Alert do @spec diversion?(t) :: boolean() def diversion?(alert) do alert.effect in @diversion_effects && - Timex.before?(alert.created_at, alert.active_period[0]) + Timex.before?(alert.created_at, List.first(alert.active_period)) end @spec municipality(t) :: String.t() | nil diff --git a/test/alerts/alerts_test.exs b/test/alerts/alerts_test.exs index 216cac025d..2dd647cfaf 100644 --- a/test/alerts/alerts_test.exs +++ b/test/alerts/alerts_test.exs @@ -4,8 +4,10 @@ defmodule AlertsTest do import Alerts.Alert import Mox + alias Alerts.Alert - alias Alerts.InformedEntity, as: IE + alias Alerts.InformedEntity + alias Test.Support.Factories setup :verify_on_exit! @@ -109,42 +111,51 @@ defmodule AlertsTest do end describe "diversion?/1" do + test "returns true when created at is before active period" do + created_at = Timex.now() + active_period = [Timex.shift(created_at, days: 1), Timex.shift(created_at, days: 2)] + + alert = + Factories.Alerts.Alert.build(:alert, + active_period: active_period, + created_at: created_at, + effect: :shuttle + ) + + assert diversion?(alert) + end + + test "returns false when created at is after active period" do + created_at = Timex.now() + active_period = [Timex.shift(created_at, days: -2), Timex.shift(created_at, days: -1)] + + alert = + Factories.Alerts.Alert.build(:alert, + active_period: active_period, + created_at: created_at, + effect: :shuttle + ) + + refute diversion?(alert) + end + test "returns true for certain effects" do - assert diversion?(%Alert{effect: :shuttle}) - assert diversion?(%Alert{effect: :stop_closure}) - assert diversion?(%Alert{effect: :station_closure}) - assert diversion?(%Alert{effect: :detour}) + assert diversion?(Factories.Alerts.Alert.build(:alert, effect: :shuttle)) + assert diversion?(Factories.Alerts.Alert.build(:alert, effect: :stop_closure)) + assert diversion?(Factories.Alerts.Alert.build(:alert, effect: :station_closure)) end test "returns false for other effects" do - refute diversion?(%Alert{effect: :access_issue}) - refute diversion?(%Alert{effect: :amber_alert}) - refute diversion?(%Alert{effect: :delay}) - refute diversion?(%Alert{effect: :dock_closure}) - refute diversion?(%Alert{effect: :dock_issue}) - refute diversion?(%Alert{effect: :extra_service}) - refute diversion?(%Alert{effect: :elevator_closure}) - refute diversion?(%Alert{effect: :escalator_closure}) - refute diversion?(%Alert{effect: :policy_change}) - refute diversion?(%Alert{effect: :schedule_change}) - refute diversion?(%Alert{effect: :station_issue}) - refute diversion?(%Alert{effect: :stop_moved}) - refute diversion?(%Alert{effect: :summary}) - refute diversion?(%Alert{effect: :suspension}) - refute diversion?(%Alert{effect: :track_change}) - refute diversion?(%Alert{effect: :unknown}) - refute diversion?(%Alert{effect: :cancellation}) - refute diversion?(%Alert{effect: :no_service}) - refute diversion?(%Alert{effect: :service_change}) - refute diversion?(%Alert{effect: :snow_route}) - refute diversion?(%Alert{effect: :stop_shoveling}) + refute diversion?(Factories.Alerts.Alert.build(:alert, effect: :access_issu)) + refute diversion?(Factories.Alerts.Alert.build(:alert, effect: :amber_alert)) + refute diversion?(Factories.Alerts.Alert.build(:alert, effect: :delay)) end end describe "municipality/1" do test "gets municipality from an alert's stops" do - alert_with_muni = Alert.new(informed_entity: [%IE{stop: "some-stop"}]) - alert_no_muni = Alert.new(informed_entity: [%IE{stop: "other-stop"}]) + alert_with_muni = Alert.new(informed_entity: [%InformedEntity{stop: "some-stop"}]) + alert_no_muni = Alert.new(informed_entity: [%InformedEntity{stop: "other-stop"}]) Stops.Repo.Mock |> expect(:get, fn "some-stop" -> diff --git a/test/alerts/parser_test.exs b/test/alerts/parser_test.exs index d12aed3e23..f0b44f611b 100644 --- a/test/alerts/parser_test.exs +++ b/test/alerts/parser_test.exs @@ -76,7 +76,8 @@ defmodule Alerts.ParserTest do |> Timex.Timezone.convert("America/New_York"), description: "Affected routes: 18", priority: :low, - url: "www.mbta.com" + url: "www.mbta.com", + image_alt_text: "Line map of the 18 route(s) closures" } end diff --git a/test/dotcom/trip_plan/itinerary_row_test.exs b/test/dotcom/trip_plan/itinerary_row_test.exs index da2aad187c..05722e915b 100644 --- a/test/dotcom/trip_plan/itinerary_row_test.exs +++ b/test/dotcom/trip_plan/itinerary_row_test.exs @@ -327,10 +327,10 @@ defmodule TripPlan.ItineraryRowTest do stub(MBTA.Api.Mock, :get_json, fn path, _ -> cond do String.contains?(path, "trips") -> - %JsonApi{data: [Test.Support.Factories.Mbta.Api.build(:trip_item)]} + %JsonApi{data: [Test.Support.Factories.MBTA.Api.build(:trip_item)]} String.contains?(path, "routes") -> - %JsonApi{data: [Test.Support.Factories.Mbta.Api.build(:route_item)]} + %JsonApi{data: [Test.Support.Factories.MBTA.Api.build(:route_item)]} true -> %JsonApi{data: []} diff --git a/test/dotcom/trip_plan/location_test.exs b/test/dotcom/trip_plan/location_test.exs index 688cface3c..4bd8f7f0fe 100644 --- a/test/dotcom/trip_plan/location_test.exs +++ b/test/dotcom/trip_plan/location_test.exs @@ -4,7 +4,7 @@ defmodule Dotcom.TripPlan.LocationTest do alias TripPlan.NamedPosition import Mox - import Test.Support.Factory.LocationService + import Test.Support.Factories.LocationService.LocationService setup :verify_on_exit! diff --git a/test/dotcom/trip_plan/query_test.exs b/test/dotcom/trip_plan/query_test.exs index 57e4dde484..24fa5c9220 100644 --- a/test/dotcom/trip_plan/query_test.exs +++ b/test/dotcom/trip_plan/query_test.exs @@ -3,7 +3,7 @@ defmodule Dotcom.TripPlan.QueryTest do import Dotcom.TripPlan.Query import Mox - import Test.Support.Factory.LocationService + import Test.Support.Factories.LocationService.LocationService alias Dotcom.TripPlan.Query alias TripPlan.NamedPosition diff --git a/test/dotcom_web/channels/vehicle_map_marker_channel_test.exs b/test/dotcom_web/channels/vehicle_map_marker_channel_test.exs index 340bcef06d..7ac24ebf1d 100644 --- a/test/dotcom_web/channels/vehicle_map_marker_channel_test.exs +++ b/test/dotcom_web/channels/vehicle_map_marker_channel_test.exs @@ -7,7 +7,7 @@ defmodule DotcomWeb.VehicleMapMarkerChannelTest do import Mock import Mox - import Test.Support.Factories.Mbta.Api + import Test.Support.Factories.MBTA.Api @vehicles [ %Vehicle{ diff --git a/test/dotcom_web/controllers/places_controller_test.exs b/test/dotcom_web/controllers/places_controller_test.exs index 76907da2c1..8414ae4e8b 100644 --- a/test/dotcom_web/controllers/places_controller_test.exs +++ b/test/dotcom_web/controllers/places_controller_test.exs @@ -4,7 +4,7 @@ defmodule DotcomWeb.PlacesControllerTest do import DotcomWeb.PlacesController import Mox - import Test.Support.Factory.LocationService + import Test.Support.Factories.LocationService.LocationService setup :verify_on_exit! diff --git a/test/dotcom_web/controllers/schedule/line/helpers_test.exs b/test/dotcom_web/controllers/schedule/line/helpers_test.exs index a104fc9252..d01fc99c79 100644 --- a/test/dotcom_web/controllers/schedule/line/helpers_test.exs +++ b/test/dotcom_web/controllers/schedule/line/helpers_test.exs @@ -2,7 +2,7 @@ defmodule DotcomWeb.ScheduleController.Line.HelpersTest do use ExUnit.Case, async: false import Mox - import Test.Support.Factories.Mbta.Api + import Test.Support.Factories.MBTA.Api alias Routes.{Route} alias DotcomWeb.ScheduleController.Line.Helpers alias Stops.{RouteStops, RouteStop, Stop} diff --git a/test/dotcom_web/controllers/transit_near_me/location_test.exs b/test/dotcom_web/controllers/transit_near_me/location_test.exs index 3307819c92..3dfe07412b 100644 --- a/test/dotcom_web/controllers/transit_near_me/location_test.exs +++ b/test/dotcom_web/controllers/transit_near_me/location_test.exs @@ -3,7 +3,7 @@ defmodule DotcomWeb.TransitNearMeController.LocationTest do alias DotcomWeb.TransitNearMeController.Location import Mox - import Test.Support.Factory.LocationService + import Test.Support.Factories.LocationService.LocationService setup :verify_on_exit! diff --git a/test/dotcom_web/controllers/trip_plan_controller_test.exs b/test/dotcom_web/controllers/trip_plan_controller_test.exs index c6e5075646..cce4f0877b 100644 --- a/test/dotcom_web/controllers/trip_plan_controller_test.exs +++ b/test/dotcom_web/controllers/trip_plan_controller_test.exs @@ -10,7 +10,7 @@ defmodule DotcomWeb.TripPlanControllerTest do doctest DotcomWeb.TripPlanController import Mox - import Test.Support.Factory.MbtaApi + import Test.Support.Factories.MBTA.Api @system_time "2017-01-01T12:20:00-05:00" @morning %{ @@ -166,7 +166,10 @@ defmodule DotcomWeb.TripPlanControllerTest do end) stub(LocationService.Mock, :geocode, fn name -> - {:ok, Test.Support.Factory.LocationService.build_list(2, :address, %{formatted: name})} + {:ok, + Test.Support.Factories.LocationService.LocationService.build_list(2, :address, %{ + formatted: name + })} end) stub(Stops.Repo.Mock, :get_parent, fn _ -> diff --git a/test/predictions/repo_test.exs b/test/predictions/repo_test.exs index ee86f84f7a..39e22f07a7 100644 --- a/test/predictions/repo_test.exs +++ b/test/predictions/repo_test.exs @@ -2,7 +2,7 @@ defmodule Predictions.RepoTest do use ExUnit.Case, async: true import Mox - import Test.Support.Factories.Mbta.Api + import Test.Support.Factories.MBTA.Api alias Predictions.Repo alias Routes.Route diff --git a/test/route_patterns/repo_test.exs b/test/route_patterns/repo_test.exs index 6d7a3b315d..5be3260390 100644 --- a/test/route_patterns/repo_test.exs +++ b/test/route_patterns/repo_test.exs @@ -2,7 +2,7 @@ defmodule RoutePatterns.RepoTest do use ExUnit.Case, async: true import Mox - import Test.Support.Factories.Mbta.Api + import Test.Support.Factories.MBTA.Api alias RoutePatterns.RoutePattern diff --git a/test/stops/nearby_test.exs b/test/stops/nearby_test.exs index 259d1597d0..989433a694 100644 --- a/test/stops/nearby_test.exs +++ b/test/stops/nearby_test.exs @@ -6,7 +6,7 @@ defmodule Stops.NearbyTest do import Mox import Stops.Nearby - import Test.Support.Factories.Mbta.Api + import Test.Support.Factories.MBTA.Api @latitude 42.577 @longitude -71.225 diff --git a/test/stops/repo_test.exs b/test/stops/repo_test.exs index c877e855af..ded0fc3302 100644 --- a/test/stops/repo_test.exs +++ b/test/stops/repo_test.exs @@ -3,7 +3,7 @@ defmodule Stops.RepoTest do import Mox import Stops.Repo - import Test.Support.Factories.Mbta.Api + import Test.Support.Factories.MBTA.Api alias Stops.Stop @direction_id Faker.Util.pick([0, 1]) diff --git a/test/stops/route_stops_test.exs b/test/stops/route_stops_test.exs index f19fcbd073..96f3513ece 100644 --- a/test/stops/route_stops_test.exs +++ b/test/stops/route_stops_test.exs @@ -2,7 +2,7 @@ defmodule Stops.RouteStopsTest do use ExUnit.Case, async: true import Mox - import Test.Support.Factories.Mbta.Api + import Test.Support.Factories.MBTA.Api alias Routes.Route alias Stops.{RouteStop, RouteStops, Stop} diff --git a/test/support/factories/alerts/alert.ex b/test/support/factories/alerts/alert.ex index 6394199faa..5718199818 100644 --- a/test/support/factories/alerts/alert.ex +++ b/test/support/factories/alerts/alert.ex @@ -11,12 +11,14 @@ defmodule Test.Support.Factories.Alerts.Alert do def alert_factory do %Alert{ id: :rand.uniform(999) |> Integer.to_string(), - active_period: [Faker.DateTime.backward(1), Faker.DateTime.forward(1)], + active_period: [Faker.DateTime.forward(1), Faker.DateTime.forward(2)], banner: Faker.Lorem.Shakespeare.king_richard_iii(), cause: Faker.Lorem.Shakespeare.king_richard_iii(), + created_at: Timex.now(), description: Faker.Lorem.Shakespeare.king_richard_iii(), effect: Alert.all_types() |> Faker.Util.pick(), header: Faker.Lorem.Shakespeare.king_richard_iii(), + image_alt_text: Faker.Lorem.Shakespeare.king_richard_iii(), image_url: Faker.Internet.image_url(), informed_entity: InformedEntitySet.build(:informed_entity_set), lifecycle: Alert.lifecycles() |> Faker.Util.pick(), diff --git a/test/support/factory/location_service.ex b/test/support/factories/location_service/location_service.ex similarity index 89% rename from test/support/factory/location_service.ex rename to test/support/factories/location_service/location_service.ex index f813949755..1ec4801012 100644 --- a/test/support/factory/location_service.ex +++ b/test/support/factories/location_service/location_service.ex @@ -1,4 +1,4 @@ -defmodule Test.Support.Factory.LocationService do +defmodule Test.Support.Factories.LocationService.LocationService do @moduledoc """ Data generation for LocationService outputs. """ diff --git a/test/support/factories/mbta/api.ex b/test/support/factories/mbta/api.ex index 8fa16c9d01..b80c90cd01 100644 --- a/test/support/factories/mbta/api.ex +++ b/test/support/factories/mbta/api.ex @@ -1,4 +1,4 @@ -defmodule Test.Support.Factories.Mbta.Api do +defmodule Test.Support.Factories.MBTA.Api do @moduledoc """ Generated fake data for MBTA.Api """ From ebba0d1a7450351d407d12d4e748caea06ca81ee Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Wed, 22 May 2024 12:21:45 -0500 Subject: [PATCH 11/24] rename module --- test/dotcom_web/controllers/transit_near_me_controller_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/dotcom_web/controllers/transit_near_me_controller_test.exs b/test/dotcom_web/controllers/transit_near_me_controller_test.exs index fc90f46f9e..21419660ad 100644 --- a/test/dotcom_web/controllers/transit_near_me_controller_test.exs +++ b/test/dotcom_web/controllers/transit_near_me_controller_test.exs @@ -7,7 +7,7 @@ defmodule DotcomWeb.TransitNearMeControllerTest do alias Stops.Stop import Mox - import Test.Support.Factory.MbtaApi + import Test.Support.Factory.MBTA.Api @orange_line %{ id: "Orange", From 1da5c26bcc84210d3528df8becbbb61449d25d21 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Wed, 22 May 2024 12:49:02 -0500 Subject: [PATCH 12/24] ... --- test/dotcom_web/controllers/transit_near_me_controller_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/dotcom_web/controllers/transit_near_me_controller_test.exs b/test/dotcom_web/controllers/transit_near_me_controller_test.exs index 21419660ad..45cb1c39e3 100644 --- a/test/dotcom_web/controllers/transit_near_me_controller_test.exs +++ b/test/dotcom_web/controllers/transit_near_me_controller_test.exs @@ -7,7 +7,7 @@ defmodule DotcomWeb.TransitNearMeControllerTest do alias Stops.Stop import Mox - import Test.Support.Factory.MBTA.Api + import Test.Support.Factories.MBTA.Api @orange_line %{ id: "Orange", From 8e9e2232f3bf9811d1792e3eb850d07313eae2cd Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Fri, 24 May 2024 08:50:27 -0500 Subject: [PATCH 13/24] use object instead of image --- lib/dotcom_web/templates/alert/_item.html.eex | 6 +++--- lib/dotcom_web/templates/cms/page/_diversions.html.eex | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/dotcom_web/templates/alert/_item.html.eex b/lib/dotcom_web/templates/alert/_item.html.eex index 009c49a896..e85ddff531 100644 --- a/lib/dotcom_web/templates/alert/_item.html.eex +++ b/lib/dotcom_web/templates/alert/_item.html.eex @@ -29,9 +29,9 @@ <%= if @alert.description do %>
<%= if @alert.image_url && @alert.image_alt_text do %> -
- <%= @alert.image_alt_text %> -
+ + <%= @alert.image_alt_text %> + <% end %>
<%= format_alert_description(@alert.description) %> diff --git a/lib/dotcom_web/templates/cms/page/_diversions.html.eex b/lib/dotcom_web/templates/cms/page/_diversions.html.eex index fa6de9a141..72a996c012 100644 --- a/lib/dotcom_web/templates/cms/page/_diversions.html.eex +++ b/lib/dotcom_web/templates/cms/page/_diversions.html.eex @@ -24,5 +24,4 @@ <%# Sidebar Right %> <%= if !@sidebar_left && @sidebar_right, do: DotcomWeb.CMSView.render("_sidebar_right.html", page: @page, conn: @conn) %>
-
From db435f649c2efec313d3e4414543ac4c759a38a6 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Fri, 7 Jun 2024 08:04:45 -0500 Subject: [PATCH 14/24] change url --- lib/alerts/repo.ex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/alerts/repo.ex b/lib/alerts/repo.ex index 6a5dd9be86..299f6d6259 100644 --- a/lib/alerts/repo.ex +++ b/lib/alerts/repo.ex @@ -75,8 +75,7 @@ defmodule Alerts.Repo do # It should be removed once alerts support image URLs. defp maybe_attach_image_url(alert) do if is_nil(alert.image_url) do - this_month = Timex.format!(Timex.now(), "%Y-%m", :strftime) - image_url = "/sites/default/files/media/#{this_month}/alert-#{alert.id}.png" + image_url = "/sites/default/files/diversion-diagrams/alert-#{alert.id}.png" Map.put(alert, :image_url, image_url) else From 4fbbc07357da2eecb365d6dec65846fe49c7a2ab Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Fri, 7 Jun 2024 12:33:14 -0500 Subject: [PATCH 15/24] open alert when there is a diversion diagram --- assets/js/alert-item.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/js/alert-item.js b/assets/js/alert-item.js index 75e04e79ff..389b99cda6 100644 --- a/assets/js/alert-item.js +++ b/assets/js/alert-item.js @@ -10,6 +10,10 @@ export const addAlertItemEventHandlers = () => { [...document.querySelectorAll(`.${ITEM_SELECTOR}`)].forEach(alertItem => { alertItem.addEventListener("click", handleAlertItemClick); alertItem.addEventListener("keydown", handleAlertItemKeyPress); + + if (alertItem.querySelector("object")) { + alertItem.click(); + } }); } }; From 91cde8442d5707499f708fb5ea6abf810fafa9a8 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Fri, 7 Jun 2024 13:08:54 -0500 Subject: [PATCH 16/24] subtract a minute before comparing time --- lib/alerts/alert.ex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/alerts/alert.ex b/lib/alerts/alert.ex index 3288608e8b..a912d65b23 100644 --- a/lib/alerts/alert.ex +++ b/lib/alerts/alert.ex @@ -256,7 +256,9 @@ defmodule Alerts.Alert do @spec diversion?(t) :: boolean() def diversion?(alert) do alert.effect in @diversion_effects && - Timex.before?(alert.created_at, List.first(alert.active_period)) + alert.created_at + |> Timex.shift(minutes: -1) + |> Timex.before?(List.first(alert.active_period)) end @spec municipality(t) :: String.t() | nil From 77e637a02a6236a01725854500091cdbad4ab268 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Fri, 7 Jun 2024 13:45:52 -0500 Subject: [PATCH 17/24] filter diversions --- lib/alerts/alert.ex | 7 ++++--- lib/alerts/repo.ex | 4 +--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/alerts/alert.ex b/lib/alerts/alert.ex index a912d65b23..e379a0c9c9 100644 --- a/lib/alerts/alert.ex +++ b/lib/alerts/alert.ex @@ -256,9 +256,10 @@ defmodule Alerts.Alert do @spec diversion?(t) :: boolean() def diversion?(alert) do alert.effect in @diversion_effects && - alert.created_at - |> Timex.shift(minutes: -1) - |> Timex.before?(List.first(alert.active_period)) + alert.active_period + |> List.first() + |> Kernel.elem(0) + |> Timex.after?(alert.created_at) end @spec municipality(t) :: String.t() | nil diff --git a/lib/alerts/repo.ex b/lib/alerts/repo.ex index 299f6d6259..72cf5dcdaa 100644 --- a/lib/alerts/repo.ex +++ b/lib/alerts/repo.ex @@ -37,9 +37,7 @@ defmodule Alerts.Repo do def diversions_by_route_ids(route_ids, now) do route_ids |> by_route_ids(now) - |> Enum.filter(fn alert -> - Enum.member?([:shuttle, :station_closure, :suspension], alert.effect) - end) + |> Enum.filter(&Alert.diversion?/1) |> Enum.map(&maybe_attach_image_url/1) end From a604ee106838bf852c16d050fcf9965b42079871 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Fri, 7 Jun 2024 14:22:16 -0500 Subject: [PATCH 18/24] update tests --- test/alerts/alerts_test.exs | 4 ++-- test/support/factories/alerts/alert.ex | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/alerts/alerts_test.exs b/test/alerts/alerts_test.exs index 2dd647cfaf..cf4ad6e423 100644 --- a/test/alerts/alerts_test.exs +++ b/test/alerts/alerts_test.exs @@ -113,7 +113,7 @@ defmodule AlertsTest do describe "diversion?/1" do test "returns true when created at is before active period" do created_at = Timex.now() - active_period = [Timex.shift(created_at, days: 1), Timex.shift(created_at, days: 2)] + active_period = [{Timex.shift(created_at, days: 1), Timex.shift(created_at, days: 2)}] alert = Factories.Alerts.Alert.build(:alert, @@ -127,7 +127,7 @@ defmodule AlertsTest do test "returns false when created at is after active period" do created_at = Timex.now() - active_period = [Timex.shift(created_at, days: -2), Timex.shift(created_at, days: -1)] + active_period = [{Timex.shift(created_at, days: -2), Timex.shift(created_at, days: -1)}] alert = Factories.Alerts.Alert.build(:alert, diff --git a/test/support/factories/alerts/alert.ex b/test/support/factories/alerts/alert.ex index 5718199818..10e18fd532 100644 --- a/test/support/factories/alerts/alert.ex +++ b/test/support/factories/alerts/alert.ex @@ -11,7 +11,7 @@ defmodule Test.Support.Factories.Alerts.Alert do def alert_factory do %Alert{ id: :rand.uniform(999) |> Integer.to_string(), - active_period: [Faker.DateTime.forward(1), Faker.DateTime.forward(2)], + active_period: [{Faker.DateTime.forward(1), Faker.DateTime.forward(2)}], banner: Faker.Lorem.Shakespeare.king_richard_iii(), cause: Faker.Lorem.Shakespeare.king_richard_iii(), created_at: Timex.now(), From d7a301080066101c66bcf8a54ff042387c7b0bb5 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Thu, 11 Jul 2024 08:09:43 -0500 Subject: [PATCH 19/24] change image key names --- lib/alerts/alert.ex | 7 ++++--- lib/alerts/parser.ex | 12 ++---------- lib/alerts/repo.ex | 15 --------------- lib/dotcom_web/templates/alert/_item.html.eex | 6 ++---- test/alerts/repo_test.exs | 17 ----------------- test/support/factories/alerts/alert.ex | 4 ++-- 6 files changed, 10 insertions(+), 51 deletions(-) diff --git a/lib/alerts/alert.ex b/lib/alerts/alert.ex index e379a0c9c9..402ce48bb1 100644 --- a/lib/alerts/alert.ex +++ b/lib/alerts/alert.ex @@ -15,8 +15,8 @@ defmodule Alerts.Alert do description: "", effect: :unknown, header: "", - image_alt_text: "", - image_url: nil, + image_alternative_text: nil, + image: nil, informed_entity: %InformedEntitySet{}, lifecycle: :unknown, priority: :low, @@ -71,7 +71,8 @@ defmodule Alerts.Alert do description: String.t() | nil, effect: effect, header: String.t(), - image_url: String.t() | nil, + image: String.t() | nil, + image_alternative_text: String.t() | nil, informed_entity: InformedEntitySet.t(), lifecycle: lifecycle, priority: Priority.priority_level(), diff --git a/lib/alerts/parser.ex b/lib/alerts/parser.ex index b8a86d9939..8da9406420 100644 --- a/lib/alerts/parser.ex +++ b/lib/alerts/parser.ex @@ -17,8 +17,8 @@ defmodule Alerts.Parser do description: description(attributes["description"]), effect: effect(attributes), header: attributes["header"], - image_alt_text: parse_informed_entity(attributes["informed_entity"]) |> create_alt_text(), - image_url: attributes["image_url"], + image_alternative_text: attributes["image_alternative_text"], + image: attributes["image"], informed_entity: parse_informed_entity(attributes["informed_entity"]), lifecycle: lifecycle(attributes["lifecycle"]), severity: severity(attributes["severity"]), @@ -217,14 +217,6 @@ defmodule Alerts.Parser do :unknown end end - - defp create_alt_text(informed_entities) do - informed_entities - |> Enum.map(& &1.route) - |> MapSet.new() - |> Enum.join(", ") - |> (fn routes -> "Line map of the " <> routes <> " route(s) closures" end).() - end end defmodule Banner do diff --git a/lib/alerts/repo.ex b/lib/alerts/repo.ex index 72cf5dcdaa..2885262803 100644 --- a/lib/alerts/repo.ex +++ b/lib/alerts/repo.ex @@ -30,15 +30,12 @@ defmodule Alerts.Repo do @doc """ Get alerts that are diversion types: shuttle, station_closure, suspension. - - Try to attach an image URL to the alert if it doesn't already have one. """ @spec diversions_by_route_ids([String.t()], DateTime.t()) :: [Alert.t()] def diversions_by_route_ids(route_ids, now) do route_ids |> by_route_ids(now) |> Enum.filter(&Alert.diversion?/1) - |> Enum.map(&maybe_attach_image_url/1) end @spec by_route_types(Enumerable.t(), DateTime.t()) :: [Alert.t()] @@ -68,16 +65,4 @@ defmodule Alerts.Repo do |> Store.all_alerts() |> Enum.filter(&(&1.priority == priority)) end - - # This function is used to attach an image URL to an alert if it doesn't already have one. - # It should be removed once alerts support image URLs. - defp maybe_attach_image_url(alert) do - if is_nil(alert.image_url) do - image_url = "/sites/default/files/diversion-diagrams/alert-#{alert.id}.png" - - Map.put(alert, :image_url, image_url) - else - alert - end - end end diff --git a/lib/dotcom_web/templates/alert/_item.html.eex b/lib/dotcom_web/templates/alert/_item.html.eex index e85ddff531..1c29373ee0 100644 --- a/lib/dotcom_web/templates/alert/_item.html.eex +++ b/lib/dotcom_web/templates/alert/_item.html.eex @@ -28,10 +28,8 @@
<%= if @alert.description do %>
- <%= if @alert.image_url && @alert.image_alt_text do %> - - <%= @alert.image_alt_text %> - + <%= if @alert.image do %> + <%= @alert.image_alternative_text %> <% end %>
<%= format_alert_description(@alert.description) %> diff --git a/test/alerts/repo_test.exs b/test/alerts/repo_test.exs index e36e710e1f..a703cf236d 100644 --- a/test/alerts/repo_test.exs +++ b/test/alerts/repo_test.exs @@ -84,23 +84,6 @@ defmodule Alerts.RepoTest do # Verify assert [^diversion] = diversions end - - test "attaches an image url to the alert if it doesn't already have one" do - # Setup - diversion = Factories.Alerts.Alert.build(:alert, effect: :shuttle, image_url: nil) - - Store.update([diversion], nil) - - diversion_route = - diversion.informed_entity.route |> MapSet.to_list() |> List.first() - - # Exercise - diversions = - Repo.diversions_by_route_ids([diversion_route], Timex.now()) - - # Verify - assert diversions |> List.first() |> Map.get(:image_url) != nil - end end describe "by_route_types/1" do diff --git a/test/support/factories/alerts/alert.ex b/test/support/factories/alerts/alert.ex index 10e18fd532..4fc24f3760 100644 --- a/test/support/factories/alerts/alert.ex +++ b/test/support/factories/alerts/alert.ex @@ -18,8 +18,8 @@ defmodule Test.Support.Factories.Alerts.Alert do description: Faker.Lorem.Shakespeare.king_richard_iii(), effect: Alert.all_types() |> Faker.Util.pick(), header: Faker.Lorem.Shakespeare.king_richard_iii(), - image_alt_text: Faker.Lorem.Shakespeare.king_richard_iii(), - image_url: Faker.Internet.image_url(), + image: Faker.Internet.image_url(), + image_alternative_text: Faker.Lorem.Shakespeare.king_richard_iii(), informed_entity: InformedEntitySet.build(:informed_entity_set), lifecycle: Alert.lifecycles() |> Faker.Util.pick(), priority: Priority.priority_levels() |> Faker.Util.pick(), From 5643e1af172f3f461c7c49c2f83c2d7070601442 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Thu, 11 Jul 2024 08:29:49 -0500 Subject: [PATCH 20/24] change click --- assets/js/alert-item.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/alert-item.js b/assets/js/alert-item.js index 389b99cda6..5c29468791 100644 --- a/assets/js/alert-item.js +++ b/assets/js/alert-item.js @@ -11,7 +11,7 @@ export const addAlertItemEventHandlers = () => { alertItem.addEventListener("click", handleAlertItemClick); alertItem.addEventListener("keydown", handleAlertItemKeyPress); - if (alertItem.querySelector("object")) { + if (alertItem.querySelector("img")) { alertItem.click(); } }); From c46dfa0422a2e3eb35b047be5ff69378d0bffa26 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Mon, 15 Jul 2024 10:45:59 -0500 Subject: [PATCH 21/24] move alerts to inside of page content --- lib/dotcom_web/templates/alert/_item.html.eex | 4 +++- lib/dotcom_web/templates/cms/page/_diversions.html.eex | 4 ---- lib/dotcom_web/templates/cms/page/_generic.html.eex | 2 ++ 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/dotcom_web/templates/alert/_item.html.eex b/lib/dotcom_web/templates/alert/_item.html.eex index 1c29373ee0..fd6bda9a54 100644 --- a/lib/dotcom_web/templates/alert/_item.html.eex +++ b/lib/dotcom_web/templates/alert/_item.html.eex @@ -29,7 +29,9 @@ <%= if @alert.description do %>
<%= if @alert.image do %> - <%= @alert.image_alternative_text %> + + <%= @alert.image_alternative_text %> + <% end %>
<%= format_alert_description(@alert.description) %> diff --git a/lib/dotcom_web/templates/cms/page/_diversions.html.eex b/lib/dotcom_web/templates/cms/page/_diversions.html.eex index 72a996c012..09b38b2b59 100644 --- a/lib/dotcom_web/templates/cms/page/_diversions.html.eex +++ b/lib/dotcom_web/templates/cms/page/_diversions.html.eex @@ -15,10 +15,6 @@ <%# Main Content %>
<%= render_page_content(@page, @conn) %> - -
- - <%= DotcomWeb.AlertView.render("group.html", alerts: Map.get(@conn.assigns, :alerts, []), date_time: Map.get(@conn.assigns, :date_time, Timex.now())) %>
<%# Sidebar Right %> diff --git a/lib/dotcom_web/templates/cms/page/_generic.html.eex b/lib/dotcom_web/templates/cms/page/_generic.html.eex index 8281a00073..55ba4102a5 100644 --- a/lib/dotcom_web/templates/cms/page/_generic.html.eex +++ b/lib/dotcom_web/templates/cms/page/_generic.html.eex @@ -1,6 +1,8 @@
<%= Dotcom.ContentRewriter.rewrite(@page.body, @conn) %> + <%= DotcomWeb.AlertView.render("group.html", alerts: Map.get(@conn.assigns, :alerts, []), date_time: Map.get(@conn.assigns, :date_time, Timex.now())) %> + <%= for paragraph <- @page.paragraphs do %> <%= render_paragraph(paragraph, @conn) %> <% end %> From f50b666307b8d0f3eee3086531e8939a82c8ae70 Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Mon, 15 Jul 2024 13:39:05 -0500 Subject: [PATCH 22/24] only auto open alert images on diversion pages --- assets/js/alert-item.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/alert-item.js b/assets/js/alert-item.js index 5c29468791..76aee4ebbf 100644 --- a/assets/js/alert-item.js +++ b/assets/js/alert-item.js @@ -11,7 +11,7 @@ export const addAlertItemEventHandlers = () => { alertItem.addEventListener("click", handleAlertItemClick); alertItem.addEventListener("keydown", handleAlertItemKeyPress); - if (alertItem.querySelector("img")) { + if (document.querySelector(".diversions-template") && alertItem.querySelector("img")) { alertItem.click(); } }); From bca4a6cfe49be76d423ca14d48302d5987cd30ba Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Wed, 17 Jul 2024 08:00:21 -0500 Subject: [PATCH 23/24] add suspension as diversion effect and sort alerts by start time --- lib/alerts/alert.ex | 5 +++-- lib/alerts/repo.ex | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/alerts/alert.ex b/lib/alerts/alert.ex index 402ce48bb1..8d09ef5f97 100644 --- a/lib/alerts/alert.ex +++ b/lib/alerts/alert.ex @@ -115,10 +115,11 @@ defmodule Alerts.Alert do ] @diversion_effects [ + :detour, :shuttle, - :stop_closure, :station_closure, - :detour + :stop_closure, + :suspension ] @lifecycles [:ongoing, :upcoming, :ongoing_upcoming, :new, :unknown] diff --git a/lib/alerts/repo.ex b/lib/alerts/repo.ex index 2885262803..fdc580c66f 100644 --- a/lib/alerts/repo.ex +++ b/lib/alerts/repo.ex @@ -36,6 +36,7 @@ defmodule Alerts.Repo do route_ids |> by_route_ids(now) |> Enum.filter(&Alert.diversion?/1) + |> Enum.sort(&(List.first(&1.active_period) > List.first(&2.priority))) end @spec by_route_types(Enumerable.t(), DateTime.t()) :: [Alert.t()] From 8d1389e909dd9eef14015316395e741bef644dfd Mon Sep 17 00:00:00 2001 From: Anthony Shull Date: Wed, 17 Jul 2024 08:29:19 -0500 Subject: [PATCH 24/24] sort correctly --- lib/alerts/repo.ex | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/alerts/repo.ex b/lib/alerts/repo.ex index fdc580c66f..684c8eadfd 100644 --- a/lib/alerts/repo.ex +++ b/lib/alerts/repo.ex @@ -30,13 +30,17 @@ defmodule Alerts.Repo do @doc """ Get alerts that are diversion types: shuttle, station_closure, suspension. + + We sort them so that earlier alerts are displaed first. """ @spec diversions_by_route_ids([String.t()], DateTime.t()) :: [Alert.t()] def diversions_by_route_ids(route_ids, now) do route_ids |> by_route_ids(now) |> Enum.filter(&Alert.diversion?/1) - |> Enum.sort(&(List.first(&1.active_period) > List.first(&2.priority))) + |> Enum.sort(fn a, b -> + a.active_period |> List.first() |> elem(0) < b.active_period |> List.first() |> elem(0) + end) end @spec by_route_types(Enumerable.t(), DateTime.t()) :: [Alert.t()]