From 576e01802371b09380d9692b5b516f79e902a4f5 Mon Sep 17 00:00:00 2001 From: sloane Date: Tue, 27 Aug 2024 16:24:32 -0400 Subject: [PATCH] chore: remove unused alert caching code --- config/config.exs | 3 - config/test.exs | 5 - lib/screens/alerts/alert.ex | 45 +---- lib/screens/alerts/cache.ex | 82 -------- lib/screens/alerts/cache/filter.ex | 188 ------------------ lib/screens/application.ex | 5 +- lib/screens/routes/route.ex | 3 +- lib/screens/routes/routes_cache.ex | 39 ---- lib/screens/stops/stops_to_routes.ex | 54 ----- lib/screens/streams/alerts.ex | 46 ----- .../v2/candidate_generator/dup/alerts.ex | 2 +- .../widgets/reconstructed_alert.ex | 2 +- .../widgets/subway_status.ex | 2 +- mix.exs | 4 +- mix.lock | 2 - test/screens/alerts/alert_test.exs | 147 -------------- test/screens/alerts/cache/filter_test.exs | 128 ------------ test/support/mocks.ex | 1 - 18 files changed, 7 insertions(+), 751 deletions(-) delete mode 100644 lib/screens/alerts/cache.ex delete mode 100644 lib/screens/alerts/cache/filter.ex delete mode 100644 lib/screens/routes/routes_cache.ex delete mode 100644 lib/screens/stops/stops_to_routes.ex delete mode 100644 lib/screens/streams/alerts.ex delete mode 100644 test/screens/alerts/cache/filter_test.exs delete mode 100644 test/support/mocks.ex diff --git a/config/config.exs b/config/config.exs index 080d2aa16..5644301b5 100644 --- a/config/config.exs +++ b/config/config.exs @@ -485,9 +485,6 @@ config :screens, Screens.ScreenApiResponseCache, gc_interval: :timer.hours(1), allocated_memory: 250_000_000 -config :screens, Screens.Stops.StopsToRoutes, adapter: Nebulex.Adapters.Local -config :screens, Screens.Routes.RoutesCache, adapter: Nebulex.Adapters.Local - # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env()}.exs" diff --git a/config/test.exs b/config/test.exs index 01855c5c4..2c6e599b3 100644 --- a/config/test.exs +++ b/config/test.exs @@ -26,8 +26,6 @@ config :screens, blue_bikes_station_information_url: [:no_api_requests_allowed_during_testing], blue_bikes_station_status_url: [:no_api_requests_allowed_during_testing], blue_bikes_api_client: Screens.BlueBikes.FakeClient, - stops_to_routes_route_mod: Screens.Routes.Route.Mock, - routes_cache_route_mod: Screens.Routes.Route.Mock, dup_headsign_replacements: %{ "Test 1" => "T1" }, @@ -162,6 +160,3 @@ config :screens, :screens_by_alert, screens_by_alert_ttl_seconds: 2, screens_last_updated_ttl_seconds: 2, screens_ttl_seconds: 1 - -config :screens, Screens.Stops.StopsToRoutes, adapter: Nebulex.Adapters.Nil -config :screens, Screens.Routes.RoutesCache, adapter: Nebulex.Adapters.Nil diff --git a/lib/screens/alerts/alert.ex b/lib/screens/alerts/alert.ex index 17f1d1b20..acbf421b4 100644 --- a/lib/screens/alerts/alert.ex +++ b/lib/screens/alerts/alert.ex @@ -1,9 +1,6 @@ defmodule Screens.Alerts.Alert do @moduledoc false - import Screens.RouteType, only: :macros - - alias Screens.Alerts.Cache alias Screens.Alerts.InformedEntity alias Screens.Routes.Route alias Screens.RouteType @@ -192,46 +189,6 @@ defmodule Screens.Alerts.Alert do end) end - def fetch_from_cache(filters \\ [], get_all_alerts \\ &Cache.all/0) do - alerts = get_all_alerts.() - - filters = - filters - |> Enum.map(&format_cache_filter/1) - |> Enum.reject(&is_nil/1) - |> Enum.into(%{}) - - {:ok, Screens.Alerts.Cache.Filter.filter_by(alerts, filters)} - end - - def fetch_from_cache_or_empty_list(filters \\ [], get_all_alerts \\ &Cache.all/0) do - {:ok, alerts} = fetch_from_cache(filters, get_all_alerts) - - alerts - end - - defp format_cache_filter({:route_id, route_id}), do: {:routes, [route_id]} - defp format_cache_filter({:stop_id, stop_id}), do: {:stops, [stop_id]} - defp format_cache_filter({:route_ids, route_ids}), do: {:routes, route_ids} - defp format_cache_filter({:stop_ids, stop_ids}), do: {:stops, stop_ids} - - defp format_cache_filter({:route_type, route_type}), - do: format_cache_filter({:route_types, [route_type]}) - - defp format_cache_filter({:route_types, route_types}) do - route_types = - Enum.map(route_types, fn - route_type when is_route_type(route_type) -> RouteType.to_id(route_type) - route_type -> route_type - end) - - {:route_types, route_types} - end - - defp format_cache_filter({:direction_id, :both}), do: nil - - defp format_cache_filter(filter), do: filter - @doc """ Convenience for cases when it's safe to treat an API alert data outage as if there simply aren't any alerts for the given parameters. @@ -565,7 +522,7 @@ defmodule Screens.Alerts.Alert do def by_route_id(route_id, stop_id) do {inline_alerts, global_alerts} = [route_id: route_id] - |> fetch_from_cache_or_empty_list() + |> fetch_or_empty_list() |> Enum.split_with(&inline?/1) global_alert = Enum.min_by(global_alerts, &sort_key(&1, stop_id), fn -> nil end) diff --git a/lib/screens/alerts/cache.ex b/lib/screens/alerts/cache.ex deleted file mode 100644 index 3219c91f8..000000000 --- a/lib/screens/alerts/cache.ex +++ /dev/null @@ -1,82 +0,0 @@ -defmodule Screens.Alerts.Cache do - @moduledoc """ - GenStage Consumer of Alert server sent event data - """ - use GenStage - - require Logger - - alias Screens.Alerts - alias ServerSentEventStage.Event - - @table __MODULE__ - - defstruct [:table] - - def start_link(opts) do - {name, init_arg} = Keyword.pop(opts, :name, __MODULE__) - GenStage.start_link(__MODULE__, init_arg, name: name) - end - - @impl true - def init(init_arg) do - subscribe_to = Keyword.get(init_arg, :subscribe_to, [Screens.Streams.Alerts.Producer]) - - table = @table - - ^table = - :ets.new(table, [:named_table, :set, read_concurrency: true, write_concurrency: false]) - - state = %__MODULE__{table: table} - - {:consumer, state, subscribe_to: subscribe_to} - end - - @impl true - def handle_events(events, _from, state) do - events - |> Enum.map(&decode_data/1) - |> Enum.each(&handle_event(&1, state)) - - {:noreply, [], state} - end - - def all(table \\ @table) do - table - |> :ets.tab2list() - |> Enum.map(&elem(&1, 1)) - end - - defp handle_event(%Event{event: "reset", data: data}, state) do - alerts = - Enum.map(data, fn data -> - alert = Alerts.Parser.parse_alert(data) - {alert.id, alert} - end) - - true = :ets.delete_all_objects(state.table) - true = :ets.insert(state.table, alerts) - - :ok - end - - defp handle_event(%Event{event: event, data: alert}, state) when event in ~w[add update] do - alert = Alerts.Parser.parse_alert(alert) - - true = :ets.insert(state.table, {alert.id, alert}) - - :ok - end - - defp handle_event(%Event{event: "remove", data: %{"id" => id}}, state) do - true = :ets.delete(state.table, id) - - :ok - end - - defp decode_data(%Event{data: encoded} = event) do - decoded = Jason.decode!(encoded) - - %{event | data: decoded} - end -end diff --git a/lib/screens/alerts/cache/filter.ex b/lib/screens/alerts/cache/filter.ex deleted file mode 100644 index b75130d71..000000000 --- a/lib/screens/alerts/cache/filter.ex +++ /dev/null @@ -1,188 +0,0 @@ -defmodule Screens.Alerts.Cache.Filter do - @moduledoc """ - Logic to apply filters to a list of `Screens.Alerts.Alert` structs. - """ - alias Screens.Routes.Route - alias Screens.Routes.RoutesCache - alias Screens.RouteType - alias Screens.Stops.StopsToRoutes - - @default_activities ~w[BOARD EXIT RIDE] - - @type filter_opts() :: %{ - optional(:routes) => [String.t()], - optional(:route_types) => [0..4 | nil], - optional(:direction_id) => 0 | 1, - optional(:stops) => [String.t()], - optional(:activities) => [String.t()] - } - - @spec filter_by([Screens.Alerts.Alert.t()], filter_opts()) :: [Screens.Alerts.Alert.t()] - def filter_by(alerts, filter_opts) when filter_opts == %{}, do: alerts - - def filter_by(alerts, filter_opts) do - {activities, filter_opts} = Map.pop(filter_opts, :activities, @default_activities) - - alerts - |> filter(filter_opts) - |> filter_by_informed_entity_activity(activities) - end - - defp filter(alerts, filter_opts) when filter_opts == %{}, do: alerts - - defp filter(alerts, filter_opts) do - filter_opts - |> build_matchers() - |> apply_matchers(alerts) - end - - defp filter_by_informed_entity_activity(alerts, values) do - values = MapSet.new(values) - - if MapSet.member?(values, "ALL") do - alerts - else - alerts - |> Enum.filter(fn alert -> - Enum.any?(alert.informed_entities, fn informed_entity -> - activities = - informed_entity - |> Map.get(:activities, []) - |> MapSet.new() - - not MapSet.disjoint?(activities, values) - end) - end) - end - end - - defp build_matchers(filter_opts) do - filter_opts - |> Enum.reduce([%{}], &build_matcher/2) - |> reject_empty_matchers() - |> Enum.uniq() - end - - defp reject_empty_matchers(matchers) do - matchers - |> Enum.reject(fn matcher -> - matcher - |> Map.values() - |> Enum.all?(&is_nil/1) - end) - end - - defp apply_matchers(matchers, alerts) do - alerts - |> Enum.filter(&matches?(&1, matchers)) - end - - defp build_matcher({:routes, values}, acc) when is_list(values) do - for route_id <- values, - for_route <- matchers_for_route_id(route_id), - matcher <- acc do - Map.merge(matcher, for_route) - end - end - - defp build_matcher({:route_types, values}, acc) when is_list(values) do - matchers_for_values(acc, :route_type, values) - end - - defp build_matcher({:direction_id, value}, acc) when value in [0, 1] do - matchers_for_values(acc, :direction_id, [value]) - end - - defp build_matcher({:stops, values}, acc) when is_list(values) do - route_ids = StopsToRoutes.stops_to_routes(values) - - route_matchers = - for route_id <- route_ids, - stop_id <- [nil | values] do - %{route: route_id, stop: stop_id} - end - - stop_matchers = - for stop_id <- [nil | values] do - %{stop: stop_id} - end - - for matcher_list <- [route_matchers, stop_matchers], - merge <- matcher_list, - matcher <- acc do - Map.merge(matcher, merge) - end - end - - defp matchers_for_values(acc, key, values) do - for value <- values, - matcher <- acc do - Map.put(matcher, key, value) - end - end - - defp matchers_for_route_id(nil) do - [%{route: nil}] - end - - defp matchers_for_route_id(route_id) do - case RoutesCache.by_id(route_id) do - %Route{type: type} -> - [ - %{ - route_type: RouteType.to_id(type), - route: route_id - } - ] - - _ -> - [%{route: route_id}] - end - end - - defp matches?(alert, matchers) when is_list(matchers) do - matchers - |> Enum.any?(&matches?(alert, &1)) - end - - defp matches?(%{informed_entities: informed_entities}, matcher) when is_map(matcher) do - informed_entities - |> Enum.any?(fn ie -> - matcher - |> expand_matcher() - |> Enum.any?(fn matcher -> - ie - |> Map.intersect(matcher, &values_equal?/3) - |> Map.values() - |> Enum.all?() - end) - end) - end - - defp expand_matcher(matcher) do - for route_type <- part_values(matcher, :route_type), - route <- part_values(matcher, :route), - stop <- part_values(matcher, :stop), - direction_id <- part_values(matcher, :direction_id) do - %{route_type: route_type, route: route, stop: stop, direction_id: direction_id} - end - |> Enum.map(fn expanded_matcher -> - Map.reject(expanded_matcher, &match?({_, :_}, &1)) - end) - |> Enum.reject(fn expanded_matcher -> - expanded_matcher - |> Map.values() - |> Enum.all?(&is_nil/1) - end) - end - - defp part_values(map, key) do - case Map.fetch(map, key) do - {:ok, nil} -> [nil] - {:ok, value} -> [value, nil] - :error -> [:_] - end - end - - defp values_equal?(_key, a, b), do: a == b -end diff --git a/lib/screens/application.ex b/lib/screens/application.ex index 2fdf4841b..a09ce781d 100644 --- a/lib/screens/application.ex +++ b/lib/screens/application.ex @@ -36,10 +36,7 @@ defmodule Screens.Application do {Screens.ScreensByAlert.SelfRefreshRunner, name: Screens.ScreensByAlert.SelfRefreshRunner}, Screens.OlCrowding.DynamicSupervisor, {Screens.OlCrowding.Agent, %{}}, - {Screens.ScreenApiResponseCache, []}, - Screens.Streams.Alerts, - Screens.Stops.StopsToRoutes, - Screens.Routes.RoutesCache + {Screens.ScreenApiResponseCache, []} ] # See https://hexdocs.pm/elixir/Supervisor.html diff --git a/lib/screens/routes/route.ex b/lib/screens/routes/route.ex index edb220eff..93b2111a0 100644 --- a/lib/screens/routes/route.ex +++ b/lib/screens/routes/route.ex @@ -39,7 +39,6 @@ defmodule Screens.Routes.Route do @type color :: name_colors() | :purple | :teal | :yellow @type icon :: name_colors() | :bus | :cr | :ferry | :mattapan - @callback by_id(id()) :: {:ok, t()} | :error @spec by_id(id()) :: {:ok, t()} | :error def by_id(route_id) do case V3Api.get_json("routes/" <> route_id) do @@ -63,7 +62,7 @@ defmodule Screens.Routes.Route do end @doc "Fetches routes that serve the given stop." - @callback serving_stop(Stop.id()) :: {:ok, [t()]} | :error + @spec serving_stop(Stop.id()) :: {:ok, [t()]} | :error def serving_stop( stop_id, get_json_fn \\ &V3Api.get_json/2, diff --git a/lib/screens/routes/routes_cache.ex b/lib/screens/routes/routes_cache.ex deleted file mode 100644 index 0222319b9..000000000 --- a/lib/screens/routes/routes_cache.ex +++ /dev/null @@ -1,39 +0,0 @@ -defmodule Screens.Routes.RoutesCache do - @moduledoc """ - A read-through cache of routes by ID. - """ - use Nebulex.Cache, - otp_app: :screens, - adapter: Application.compile_env(:screens, [__MODULE__, :adapter]) - - alias Screens.Routes.Route - - @route_mod Application.compile_env(:screens, :routes_cache_route_mod, Screens.Routes.Route) - - @base_ttl :timer.hours(1) - - @spec by_id(id :: String.t()) :: Route.t() | nil - def by_id(id) do - if route = get(id) do - route - else - route = fetch_by_id(id) - - unless is_nil(route), do: put(id, route, ttl: ttl()) - - route - end - end - - defp fetch_by_id(id) do - case @route_mod.by_id(id) do - {:ok, %Route{} = route} -> route - _ -> nil - end - end - - def ttl do - additional_minutes = :rand.uniform(30) - @base_ttl + :timer.minutes(additional_minutes) - end -end diff --git a/lib/screens/stops/stops_to_routes.ex b/lib/screens/stops/stops_to_routes.ex deleted file mode 100644 index f89bd3783..000000000 --- a/lib/screens/stops/stops_to_routes.ex +++ /dev/null @@ -1,54 +0,0 @@ -defmodule Screens.Stops.StopsToRoutes do - @moduledoc """ - Cache of stop ids to route ids. Information for stop ids missing from the - cache is fetched automatically from the V3 API when requested. - """ - use Nebulex.Cache, - otp_app: :screens, - adapter: Application.compile_env(:screens, [__MODULE__, :adapter]) - - @route_mod Application.compile_env(:screens, :stops_to_routes_route_mod, Screens.Routes.Route) - - @base_ttl :timer.hours(1) - - @spec stops_to_routes([stop_id :: String.t()]) :: [route_id :: String.t()] - def stops_to_routes(stop_ids) do - from_cache = get_all(stop_ids) - missing_stop_ids = stop_ids -- Map.keys(from_cache) - - from_api = - if Enum.empty?(missing_stop_ids) do - %{} - else - from_api = - for stop_id <- missing_stop_ids, into: %{} do - {:ok, routes} = @route_mod.serving_stop(stop_id) - route_ids = Enum.map(routes, & &1.id) - - {stop_id, route_ids} - end - - put_all(from_api, ttl: ttl()) - - from_api - end - - [from_cache, from_api] - |> Enum.map(&ungroup_values/1) - |> Enum.concat() - |> Enum.uniq() - end - - defp ungroup_values(map) do - map - |> Map.values() - |> List.flatten() - |> Enum.uniq() - end - - # Set random TTLs from 1hr to 1.5hrs to alleviate the thundering herd problem - defp ttl do - additional_minutes = :rand.uniform(30) - @base_ttl + :timer.minutes(additional_minutes) - end -end diff --git a/lib/screens/streams/alerts.ex b/lib/screens/streams/alerts.ex deleted file mode 100644 index 521bf5085..000000000 --- a/lib/screens/streams/alerts.ex +++ /dev/null @@ -1,46 +0,0 @@ -defmodule Screens.Streams.Alerts do - @moduledoc """ - Supervisor for streamed producer and consumer(s) of Alerts data from the - V3 API - """ - use Supervisor - - @dialyzer {:nowarn_function, children: 1} - @env Mix.env() - - def start_link(opts) do - {name, init_arg} = Keyword.pop(opts, :name, __MODULE__) - Supervisor.start_link(__MODULE__, init_arg, name: name) - end - - @impl true - def init(_init_arg) do - children() - |> Supervisor.init(strategy: :one_for_all) - end - - defp children(env \\ @env) - defp children(:test), do: [] - - defp children(_env) do - api_url = Application.get_env(:screens, :api_v3_url) - api_key = Application.get_env(:screens, :api_v3_key) - - url = - api_url - |> URI.merge("/alerts") - |> URI.to_string() - - producer = { - ServerSentEventStage, - name: Screens.Streams.Alerts.Producer, url: url, headers: [{"x-api-key", api_key}] - } - - consumer = { - Screens.Alerts.Cache, - name: Screens.Alerts.Cache, subscribe_to: [Screens.Streams.Alerts.Producer] - } - - [producer, consumer] - end -end diff --git a/lib/screens/v2/candidate_generator/dup/alerts.ex b/lib/screens/v2/candidate_generator/dup/alerts.ex index 982c6a5bf..9cd898edd 100644 --- a/lib/screens/v2/candidate_generator/dup/alerts.ex +++ b/lib/screens/v2/candidate_generator/dup/alerts.ex @@ -23,7 +23,7 @@ defmodule Screens.V2.CandidateGenerator.Dup.Alerts do config, now \\ DateTime.utc_now(), fetch_stop_name_fn \\ &Stop.fetch_stop_name/1, - fetch_alerts_fn \\ &Alert.fetch_from_cache/1, + fetch_alerts_fn \\ &Alert.fetch/1, fetch_location_context_fn \\ &Stop.fetch_location_context/3 ) do # In this function: diff --git a/lib/screens/v2/candidate_generator/widgets/reconstructed_alert.ex b/lib/screens/v2/candidate_generator/widgets/reconstructed_alert.ex index f21863b72..dff151d7d 100644 --- a/lib/screens/v2/candidate_generator/widgets/reconstructed_alert.ex +++ b/lib/screens/v2/candidate_generator/widgets/reconstructed_alert.ex @@ -51,7 +51,7 @@ defmodule Screens.V2.CandidateGenerator.Widgets.ReconstructedAlert do def reconstructed_alert_instances( %Screen{app_params: %PreFare{} = app_params} = config, now \\ DateTime.utc_now(), - fetch_alerts_fn \\ &Alert.fetch_from_cache/1, + fetch_alerts_fn \\ &Alert.fetch/1, fetch_stop_name_fn \\ &Stop.fetch_stop_name/1, fetch_location_context_fn \\ &Stop.fetch_location_context/3, fetch_subway_platforms_for_stop_fn \\ &Stop.fetch_subway_platforms_for_stop/1 diff --git a/lib/screens/v2/candidate_generator/widgets/subway_status.ex b/lib/screens/v2/candidate_generator/widgets/subway_status.ex index 3832f178b..164c82898 100644 --- a/lib/screens/v2/candidate_generator/widgets/subway_status.ex +++ b/lib/screens/v2/candidate_generator/widgets/subway_status.ex @@ -12,7 +12,7 @@ defmodule Screens.V2.CandidateGenerator.Widgets.SubwayStatus do ) do route_ids = ["Blue", "Orange", "Red", "Green-B", "Green-C", "Green-D", "Green-E"] - {:ok, alerts} = Screens.Alerts.Alert.fetch_from_cache(route_ids: route_ids) + {:ok, alerts} = Screens.Alerts.Alert.fetch(route_ids: route_ids) relevant_alerts = alerts diff --git a/mix.exs b/mix.exs index a8d7b983e..d47c7ab9f 100644 --- a/mix.exs +++ b/mix.exs @@ -90,9 +90,7 @@ defmodule Screens.MixProject do {:nebulex, "~> 2.6"}, {:remote_ip, "~> 1.2"}, {:hackney_telemetry, "~> 0.2.0"}, - {:ex_cldr_messages, "~> 1.0"}, - {:server_sent_event_stage, "~> 1.2"}, - {:mox, "~> 1.1", only: :test} + {:ex_cldr_messages, "~> 1.0"} ] end end diff --git a/mix.lock b/mix.lock index 36681f70b..018299a5e 100644 --- a/mix.lock +++ b/mix.lock @@ -42,7 +42,6 @@ "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, "mix_test_watch": {:hex, :mix_test_watch, "1.2.0", "1f9acd9e1104f62f280e30fc2243ae5e6d8ddc2f7f4dc9bceb454b9a41c82b42", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "278dc955c20b3fb9a3168b5c2493c2e5cffad133548d307e0a50c7f2cfbf34f6"}, - "mox": {:hex, :mox, "1.1.0", "0f5e399649ce9ab7602f72e718305c0f9cdc351190f72844599545e4996af73c", [:mix], [], "hexpm", "d44474c50be02d5b72131070281a5d3895c0e7a95c780e90bc0cfe712f633a13"}, "nebulex": {:hex, :nebulex, "2.6.3", "78af348ed9f8a338871b41e0b6de718c1808e627ce03fbe86598cbda2bdda2f5", [:mix], [{:decorator, "~> 1.4", [hex: :decorator, repo: "hexpm", optional: true]}, {:shards, "~> 1.1", [hex: :shards, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "09cdcbb62f8463ffcec7cae4936425ce91e25d92a6cd37e48b5dda7c851958d5"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_ownership": {:hex, :nimble_ownership, "0.3.1", "99d5244672fafdfac89bfad3d3ab8f0d367603ce1dc4855f86a1c75008bce56f", [:mix], [], "hexpm", "4bf510adedff0449a1d6e200e43e57a814794c8b5b6439071274d248d272a549"}, @@ -66,7 +65,6 @@ "retry": {:hex, :retry, "0.18.0", "dc58ebe22c95aa00bc2459f9e0c5400e6005541cf8539925af0aa027dc860543", [:mix], [], "hexpm", "9483959cc7bf69c9e576d9dfb2b678b71c045d3e6f39ab7c9aa1489df4492d73"}, "screens_config": {:git, "https://github.com/mbta/screens-config-lib.git", "25fb47c58fc0b485c8c6df78fe94914292856903", [ref: "25fb47c58fc0b485c8c6df78fe94914292856903"]}, "sentry": {:hex, :sentry, "10.6.2", "a867ab728d424e187ccb2bccc388170a740a79bc0ddccabd72d303b203acbe0e", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_ownership, "~> 0.3.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.20", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.6", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "31bb84247274f9262fd300df0e3eb73302e4849cc6b7a6560bb2465f03fbd446"}, - "server_sent_event_stage": {:hex, :server_sent_event_stage, "1.2.1", "ede8c63496e19f039972503aa242cb4c16a301d495be7d9fdda2f952298cbf0c", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:ex_doc, "~> 0.22", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:gen_stage, "~> 1.1", [hex: :gen_stage, repo: "hexpm", optional: false]}, {:mint, "~> 1.4", [hex: :mint, repo: "hexpm", optional: false]}], "hexpm", "5b84b2c886bfa3ab38143d424eff6ec9d224e65ca576652aab762ed9d11847c3"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "stream_data": {:hex, :stream_data, "1.1.1", "fd515ca95619cca83ba08b20f5e814aaf1e5ebff114659dc9731f966c9226246", [:mix], [], "hexpm", "45d0cd46bd06738463fd53f22b70042dbb58c384bb99ef4e7576e7bb7d3b8c8c"}, "sweet_xml": {:hex, :sweet_xml, "0.7.4", "a8b7e1ce7ecd775c7e8a65d501bc2cd933bff3a9c41ab763f5105688ef485d08", [:mix], [], "hexpm", "e7c4b0bdbf460c928234951def54fe87edf1a170f6896675443279e2dbeba167"}, diff --git a/test/screens/alerts/alert_test.exs b/test/screens/alerts/alert_test.exs index 72c75023d..6cafbe6ed 100644 --- a/test/screens/alerts/alert_test.exs +++ b/test/screens/alerts/alert_test.exs @@ -1,12 +1,7 @@ defmodule Screens.Alerts.AlertTest do use ExUnit.Case, async: true - import Mox - alias Screens.Alerts.Alert - alias Screens.Routes.Route - - setup :verify_on_exit! defp alert_json(id) do %{ @@ -112,146 +107,4 @@ defmodule Screens.Alerts.AlertTest do assert effect == Alert.effect(%Alert{effect: effect}) end end - - describe "fetch_from_cache/2" do - setup do - alerts = [ - %Alert{ - id: "USING_WHEELCHAIR", - cause: :construction, - effect: :delay, - severity: 4, - header: "Alert 0", - description: "Alert 0", - informed_entities: [ - %{ - activities: ~w[USING_WHEELCHAIR], - stop: "A", - route: nil, - route_type: 3, - direction_id: nil - } - ] - }, - %Alert{ - id: "stop: A, route_type: 3", - cause: :construction, - effect: :delay, - severity: 4, - header: "Alert 1", - description: "Alert 1", - informed_entities: [ - %{activities: ~w[BOARD RIDE], stop: "A", route: nil, route_type: 3, direction_id: nil} - ] - }, - %Alert{ - id: "stop: B, route_type: 3", - cause: :construction, - effect: :delay, - severity: 4, - header: "Alert 2", - description: "Alert 2", - informed_entities: [ - %{activities: ~w[BOARD RIDE], stop: "B", route: nil, route_type: 3, direction_id: nil} - ] - }, - %Alert{ - id: "stop: C, route: Z, route_type: 2, direction_id: 0", - cause: :construction, - effect: :delay, - severity: 4, - header: "Alert 3", - description: "Alert 3", - informed_entities: [ - %{activities: ~w[BOARD EXIT], stop: "C", route: "Z", route_type: 2, direction_id: 0} - ] - }, - %Alert{ - id: "stop: D, route: Y/Z, route_type: 2, direction_id: 1", - cause: :construction, - effect: :delay, - severity: 4, - header: "Alert 4", - description: "Alert 4", - informed_entities: [ - %{activities: ~w[BOARD RIDE], stop: "D", route: "Z", route_type: 2, direction_id: 1}, - %{activities: ~w[BOARD RIDE], stop: nil, route: "Y", route_type: 2, direction_id: nil} - ] - } - ] - - [alerts: alerts, get_all_alerts: fn -> alerts end] - end - - test "returns all of the alerts matching the default activities", %{ - alerts: alerts, - get_all_alerts: get_all_alerts - } do - assert {:ok, alerts} == Alert.fetch_from_cache([], get_all_alerts) - end - - test "filters by stops", %{get_all_alerts: get_all_alerts} do - stub(Route.Mock, :serving_stop, fn _ -> {:ok, []} end) - - assert {:ok, [%Alert{id: "stop: A" <> _}]} = - Alert.fetch_from_cache([stop_id: "A"], get_all_alerts) - - assert {:ok, [%Alert{id: "stop: B" <> _}]} = - Alert.fetch_from_cache([stop_ids: ["B"]], get_all_alerts) - - assert {:ok, [%Alert{id: "stop: A" <> _}, %Alert{id: "stop: B" <> _}]} = - Alert.fetch_from_cache([stop_ids: ["A", "B"]], get_all_alerts) - end - - test "filters by routes", %{get_all_alerts: get_all_alerts} do - stub(Route.Mock, :by_id, fn - "Z" -> {:ok, %Route{id: "Z", type: :rail}} - "Y" -> {:ok, %Route{id: "Y", type: :rail}} - end) - - assert {:ok, [%Alert{id: "stop: C, route: Z" <> _}, %Alert{id: "stop: D, route: Y/Z" <> _}]} = - Alert.fetch_from_cache([route_ids: ["Z"]], get_all_alerts) - - assert {:ok, [%Alert{id: "stop: D, route: Y/Z" <> _}]} = - Alert.fetch_from_cache([route_ids: ["Y"]], get_all_alerts) - end - - test "filters by route_type", %{get_all_alerts: get_all_alerts} do - assert {:ok, - [ - %Alert{id: "stop: C, route: Z, route_type: 2" <> _}, - %Alert{id: "stop: D, route: Y/Z, route_type: 2" <> _} - ]} = - Alert.fetch_from_cache([route_type: :rail], get_all_alerts) - - assert {:ok, - [ - %Alert{id: "stop: C, route: Z, route_type: 2" <> _}, - %Alert{id: "stop: D, route: Y/Z, route_type: 2" <> _} - ]} = - Alert.fetch_from_cache([route_type: 2], get_all_alerts) - - assert {:ok, - [ - %Alert{id: "stop: A, route_type: 3" <> _}, - %Alert{id: "stop: B, route_type: 3" <> _} - ]} = - Alert.fetch_from_cache([route_types: [:bus]], get_all_alerts) - end - - test "filters by route and direction_id", %{get_all_alerts: get_all_alerts} do - stub(Route.Mock, :by_id, fn "Z" -> {:ok, %Route{id: "Z", type: :rail}} end) - - assert {:ok, [%Alert{id: "stop: D, route: Y/Z, route_type: 2, direction_id: 1"}]} = - Alert.fetch_from_cache([route_ids: ["Z"], direction_id: 1], get_all_alerts) - end - - test "filters by activities when passed", %{get_all_alerts: get_all_alerts} do - assert {:ok, [%Alert{id: "USING_WHEELCHAIR"}]} = - Alert.fetch_from_cache([activities: ["USING_WHEELCHAIR"]], get_all_alerts) - - assert {:ok, [%Alert{id: "stop: C, route: Z" <> _}]} = - Alert.fetch_from_cache([activities: ["EXIT", "DOES_NOT_EXIST"]], get_all_alerts) - end - end end diff --git a/test/screens/alerts/cache/filter_test.exs b/test/screens/alerts/cache/filter_test.exs deleted file mode 100644 index fbacc5128..000000000 --- a/test/screens/alerts/cache/filter_test.exs +++ /dev/null @@ -1,128 +0,0 @@ -defmodule Screens.Alerts.Cache.FilterTest do - use ExUnit.Case, async: true - - import Mox - - alias Screens.Alerts.Alert - alias Screens.Alerts.Cache.Filter - alias Screens.Routes.Route - - setup :verify_on_exit! - - describe "filter_by/2" do - setup do - alerts = [ - alert("stop only", ie(stop: "stop-only")), - alert("route serving stop", ie(route: "serving-stop")), - alert("route only", ie(route: "route-only", route_type: 0)), - alert("stop and route", ie(stop: "stop-and-route-stop", route: "stop-and-route-route")), - alert("route only 2", ie(route: "route-only-2", route_type: 1)), - alert("route type only", ie(route_type: 0)), - alert( - "route in one direction", - ie(route: "route-in-direction", direction_id: 0, route_type: 3) - ), - alert( - "route in the other direction", - ie(route: "route-in-direction", direction_id: 1, route_type: 3) - ), - alert("route in either direction", ie(route: "route-in-direction", route_type: 3)), - alert("other activities 1", ie(route: "route-only", activities: ~w[USING_WHEELCHAIR])), - alert("other activities 2", ie(route: "route-only-3", activities: ~w[USING_WHEELCHAIR])) - ] - - %{alerts: alerts} - end - - test "filters for stop, including alerts impacting routes serving the stop", %{alerts: alerts} do - stub(Route.Mock, :serving_stop, fn _ -> {:ok, [%Route{id: "serving-stop"}]} end) - - assert [%Alert{id: "stop only"}, %Alert{id: "route serving stop"}] = - Filter.filter_by(alerts, %{stops: ["stop-only"]}) - end - - test "filters for route, including alerts impacting the entire route type", %{alerts: alerts} do - stub(Route.Mock, :by_id, fn - "route-only" -> {:ok, %Route{id: "route-only", type: :light_rail}} - end) - - assert [%Alert{id: "route only"}, %Alert{id: "route type only"}] = - Filter.filter_by(alerts, %{routes: ["route-only"]}) - end - - test "filters for stop and route combined", %{alerts: alerts} do - stub(Route.Mock, :by_id, fn - "stop-and-route-route" -> {:ok, %Route{id: "stop-and-route-route", type: :subway}} - "route-only-2" -> {:ok, %Route{id: "route-only", type: :subway}} - end) - - stub(Route.Mock, :serving_stop, fn "stop-and-route-stop" -> - {:ok, [%Route{id: "stop-and-route-route"}]} - end) - - assert [%Alert{id: "stop and route"}, %Alert{id: "route only 2"}] = - Filter.filter_by(alerts, %{ - routes: ["stop-and-route-route", "route-only-2"], - stops: ["stop-and-route-stop"] - }) - end - - test "filters for route_type", %{alerts: alerts} do - assert [%Alert{id: "route only"}, %Alert{id: "route type only"}] = - Filter.filter_by(alerts, %{route_types: [0]}) - - assert [%Alert{id: "route only 2"}] = Filter.filter_by(alerts, %{route_types: [1]}) - - assert [%Alert{id: "route only"}, %Alert{id: "route only 2"}, %Alert{id: "route type only"}] = - Filter.filter_by(alerts, %{route_types: [0, 1]}) - end - - test "filters for a specific direction_id", %{alerts: alerts} do - stub(Route.Mock, :by_id, fn - "route-in-direction" -> {:ok, %Route{id: "route-in-direction", type: :bus}} - end) - - assert [%Alert{id: "route in one direction"}, %Alert{id: "route in either direction"}] = - Filter.filter_by(alerts, %{routes: ["route-in-direction"], direction_id: 0}) - - assert [%Alert{id: "route in the other direction"}, %Alert{id: "route in either direction"}] = - Filter.filter_by(alerts, %{routes: ["route-in-direction"], direction_id: 1}) - end - - test "filters on activities", %{alerts: alerts} do - stub(Route.Mock, :by_id, fn - "route-only" -> {:ok, %Route{id: "route-only", type: :light_rail}} - "route-only-3" -> {:ok, %Route{id: "route-only-3", type: :light_rail}} - end) - - assert [%Alert{id: "other activities 1"}, %Alert{id: "other activities 2"}] = - Filter.filter_by(alerts, %{activities: ~w[USING_WHEELCHAIR]}) - - assert [%Alert{id: "other activities 1"}] = - Filter.filter_by(alerts, %{ - routes: ["route-only"], - activities: ~w[USING_WHEELCHAIR] - }) - - assert [%Alert{id: "other activities 2"}] = - Filter.filter_by(alerts, %{ - routes: ["route-only-3"], - activities: ~w[USING_WHEELCHAIR] - }) - end - end - - defp alert(id, ies) do - %Alert{id: id, informed_entities: List.wrap(ies)} - end - - defp ie(opts) do - %{ - stop: opts[:stop], - route: opts[:route], - route_type: opts[:route_type], - activities: opts[:activities] || ~w[BOARD EXIT RIDE], - direction_id: opts[:direction_id] - } - end -end diff --git a/test/support/mocks.ex b/test/support/mocks.ex deleted file mode 100644 index 552fa1c40..000000000 --- a/test/support/mocks.ex +++ /dev/null @@ -1 +0,0 @@ -Mox.defmock(Screens.Routes.Route.Mock, for: Screens.Routes.Route)