diff --git a/lib/dotcom_web/controllers/schedule/green.ex b/lib/dotcom_web/controllers/schedule/green.ex index 766407dcb1..7a279c77fd 100644 --- a/lib/dotcom_web/controllers/schedule/green.ex +++ b/lib/dotcom_web/controllers/schedule/green.ex @@ -15,7 +15,7 @@ defmodule DotcomWeb.ScheduleController.Green do import DotcomWeb.Schedule.Line, only: [line_direction: 2] import DotcomWeb.Schedule.RouteBreadcrumbs, only: [assign_breadcrumbs: 2] - alias DotcomWeb.Schedule.{Predictions, VehicleLocations} + alias DotcomWeb.Schedule.VehicleLocations alias DotcomWeb.ScheduleController.LineController alias DotcomWeb.ScheduleView @@ -27,7 +27,6 @@ defmodule DotcomWeb.ScheduleController.Green do plug(:assign_next_holidays) plug(:stops_on_routes) plug(:vehicle_locations) - plug(:predictions) plug(DotcomWeb.ScheduleController.VehicleTooltips) plug(:assign_breadcrumbs) plug(DotcomWeb.ScheduleController.ScheduleError) @@ -76,27 +75,6 @@ defmodule DotcomWeb.ScheduleController.Green do assign(conn, :stops_on_routes, GreenLine.stops_on_routes(direction_id, date)) end - def predictions(conn, _opts) do - {predictions, vehicle_predictions} = - conn - |> conn_with_branches - |> Task.async_stream( - fn branch_conn -> - Predictions.all_predictions(branch_conn) - end, - timeout: @task_timeout - ) - |> Enum.reduce({[], []}, fn {:ok, branch_conn}, - {acc_predictions, acc_vehicle_predictions} -> - {branch_conn.assigns.predictions ++ acc_predictions, - branch_conn.assigns.vehicle_predictions ++ acc_vehicle_predictions} - end) - - conn - |> assign(:predictions, predictions) - |> assign(:vehicle_predictions, vehicle_predictions) - end - def vehicle_locations(conn, opts) do vehicle_locations = conn diff --git a/lib/dotcom_web/controllers/schedule/predictions.ex b/lib/dotcom_web/controllers/schedule/predictions.ex deleted file mode 100644 index bb8404097b..0000000000 --- a/lib/dotcom_web/controllers/schedule/predictions.ex +++ /dev/null @@ -1,124 +0,0 @@ -defmodule DotcomWeb.Schedule.Predictions do - @moduledoc """ - - Assigns predictions based on the currently selected route/stop/direction. - - """ - - require Logger - - import Plug.Conn - - alias Predictions.Prediction - alias Util.AsyncAssign - - @predictions_repo Application.compile_env!(:dotcom, :repo_modules)[:predictions] - - def all_predictions(conn) do - if should_fetch_predictions?(conn) do - predictions_task = fn -> predictions(conn) end - vehicle_predictions_task = fn -> vehicle_predictions(conn) end - - conn - |> AsyncAssign.async_assign_default(:predictions, predictions_task, []) - |> AsyncAssign.async_assign_default(:vehicle_predictions, vehicle_predictions_task, []) - |> AsyncAssign.await_assign_all_default(__MODULE__) - else - conn - |> assign(:predictions, []) - |> assign(:vehicle_predictions, []) - end - end - - @spec should_fetch_predictions?(Plug.Conn.t()) :: boolean - @doc "We only fetch predictions if we selected an origin and the date is today." - def should_fetch_predictions?(%{assigns: %{origin: nil}}) do - false - end - - def should_fetch_predictions?(%{assigns: assigns}) do - Date.compare(assigns.date, Util.service_date(assigns.date_time)) == :eq - end - - @spec predictions(Plug.Conn.t()) :: [Prediction.t()] - defp predictions(%{ - assigns: %{ - origin: origin, - destination: destination, - route: %{id: route_id}, - direction_id: direction_id - } - }) - when not is_nil(origin) do - destination_id = if destination, do: Map.get(destination, :id) - - opts = - if destination_id do - [route: route_id] - else - [route: route_id, direction_id: direction_id] - end - - @predictions_repo.all(opts) - |> case do - {:error, error} -> - Logger.error("predictions for opts #{inspect(opts)}: #{inspect(error)}") - - [] - - list -> - list - |> Enum.filter(fn prediction -> - prediction.stop && prediction.stop.id in [origin.id, destination_id] - end) - |> filter_stop_at_origin(origin.id) - |> filter_missing_trip - end - end - - defp predictions(_conn) do - [] - end - - @spec filter_stop_at_origin([Prediction.t()], Stops.Stop.id_t()) :: [Prediction.t()] - defp filter_stop_at_origin(predictions, origin_id) do - predictions - |> Enum.reject(fn - %Prediction{time: nil} -> false - %Prediction{stop: %{id: ^origin_id}, departing?: false} -> true - %Prediction{} -> false - end) - end - - @spec filter_missing_trip([Prediction.t()]) :: [Prediction.t()] - defp filter_missing_trip(predictions) do - Enum.filter(predictions, fn pred -> - pred.trip != nil || pred.status != nil - end) - end - - @spec vehicle_predictions(Plug.Conn.t()) :: [Prediction.t()] - defp vehicle_predictions(%{assigns: %{vehicle_locations: vehicle_locations}}) do - {trip_ids, stop_ids} = - vehicle_locations - |> Map.keys() - |> Enum.unzip() - - trip_ids = trip_ids |> Enum.reject(&is_nil/1) |> Enum.join(",") - - case @predictions_repo.all(trip: trip_ids) do - {:error, error} -> - Logger.error("predictions for trips #{inspect(trip_ids)}: #{inspect(error)}") - - [] - - list -> - list - |> Enum.filter(&(&1.stop && &1.stop.id in stop_ids)) - end - end - - defp vehicle_predictions(_conn) do - [] - end -end diff --git a/lib/dotcom_web/controllers/schedule/vehicle_tooltips.ex b/lib/dotcom_web/controllers/schedule/vehicle_tooltips.ex index f7c78bb5f9..6a9bce71bf 100644 --- a/lib/dotcom_web/controllers/schedule/vehicle_tooltips.ex +++ b/lib/dotcom_web/controllers/schedule/vehicle_tooltips.ex @@ -1,6 +1,6 @@ defmodule DotcomWeb.ScheduleController.VehicleTooltips do @moduledoc """ - Assigns :vehicle_tooltips based on previously requested :route, :vehicle_locations and :vehicle_predictions. + Assigns :vehicle_tooltips based on previously requested :route, :vehicle_locations """ import Plug.Conn, only: [assign: 3] @@ -21,8 +21,7 @@ defmodule DotcomWeb.ScheduleController.VehicleTooltips do :vehicle_tooltips, VehicleHelpers.build_tooltip_index( conn.assigns.route, - conn.assigns.vehicle_locations, - conn.assigns.vehicle_predictions + conn.assigns.vehicle_locations ) ) end diff --git a/lib/vehicle_helpers.ex b/lib/vehicle_helpers.ex index 7177e196a9..5da76bc4a3 100644 --- a/lib/vehicle_helpers.ex +++ b/lib/vehicle_helpers.ex @@ -14,6 +14,7 @@ defmodule VehicleHelpers do alias Schedules.Trip alias Vehicles.Vehicle + @schedules_repo Application.compile_env!(:dotcom, :repo_modules)[:schedules] @stops_repo Application.compile_env!(:dotcom, :repo_modules)[:stops] @type tooltip_index_key :: {Trip.id_t() | nil, Stop.id_t()} | Stop.id_t() @@ -27,32 +28,19 @@ defmodule VehicleHelpers do construct a convenient map that can be used in views / templates to determine if a tooltip is available and to fetch all of the required data """ - @spec build_tooltip_index(Route.t(), VehicleLocations.t(), [Prediction.t()]) :: tooltip_index - def build_tooltip_index(route, vehicle_locations, vehicle_predictions) do - indexed_predictions = index_vehicle_predictions(vehicle_predictions) - + @spec build_tooltip_index(Route.t(), VehicleLocations.t()) :: tooltip_index + def build_tooltip_index(route, vehicle_locations) do vehicle_locations |> Stream.reject(fn {{_trip_id, stop_id}, _status} -> is_nil(stop_id) end) |> Enum.reduce(%{}, fn vehicle_location, output -> {{trip_id, stop_id}, vehicle} = vehicle_location - - {prediction, trip} = - if trip_id do - { - prediction_for_stop(indexed_predictions, trip_id, vehicle.stop_id), - Schedules.Repo.trip(trip_id) - } - else - {nil, nil} - end - stop_name = @stops_repo.get(vehicle.stop_id) |> stop_name() tooltip = %VehicleTooltip{ vehicle: vehicle, - prediction: prediction, + prediction: nil, stop_name: stop_name, - trip: trip, + trip: if(trip_id, do: @schedules_repo.trip(trip_id)), route: route } @@ -62,21 +50,6 @@ defmodule VehicleHelpers do end) end - @spec prediction_for_stop(VehicleLocations.t(), String.t(), String.t()) :: Prediction.t() | nil - defp prediction_for_stop(vehicle_predictions, trip_id, stop_id) do - Map.get(vehicle_predictions, {trip_id, stop_id}) - end - - @spec index_vehicle_predictions([Prediction.t()]) :: %{ - {String.t(), String.t()} => Prediction.t() - } - defp index_vehicle_predictions(predictions) do - predictions - |> Stream.filter(&(&1.trip && &1.stop)) - |> Stream.map(&{{&1.trip.id, &1.stop.id}, &1}) - |> Enum.into(Map.new()) - end - @spec stop_name(Stops.Stop.t() | nil) :: String.t() defp stop_name(nil), do: "" defp stop_name(stop), do: stop.name diff --git a/test/dotcom/lib/vehicle_helpers_test.exs b/test/dotcom/lib/vehicle_helpers_test.exs index 272a1cef16..7bbb3ce924 100644 --- a/test/dotcom/lib/vehicle_helpers_test.exs +++ b/test/dotcom/lib/vehicle_helpers_test.exs @@ -25,15 +25,13 @@ defmodule Dotcom.VehicleHelpersTest do } } - @predictions [ - %Predictions.Prediction{ - departing?: true, - time: ~N[2018-05-01T11:00:00], - status: "On Time", - trip: @trip, - stop: @station - } - ] + @prediction %Predictions.Prediction{ + departing?: true, + time: ~N[2018-05-01T11:00:00], + status: "On Time", + trip: @trip, + stop: @station + } setup :verify_on_exit! @@ -42,29 +40,20 @@ defmodule Dotcom.VehicleHelpersTest do @station end) - stub(MBTA.Api.Mock, :get_json, fn "/trips/" <> id, _ -> - trip = - Test.Support.Factories.MBTA.Api.build(:trip_item, - id: id, - attributes: %{ - "name" => @trip.name, - "headsign" => @trip.headsign - } - ) - - %JsonApi{links: %{}, data: [trip]} + stub(Schedules.Repo.Mock, :trip, fn _ -> + @trip end) :ok end setup do - tooltips = build_tooltip_index(@route, @locations, @predictions) + tooltips = build_tooltip_index(@route, @locations) {:ok, tooltips: tooltips, tooltip_base: tooltips[@station.id]} end - describe "build_tooltip_index/3" do + describe "build_tooltip_index/2" do test "verify the Vehicle tooltip data", %{tooltips: tooltips, tooltip_base: tooltip_base} do assert length(Map.keys(tooltips)) == 2 assert Map.has_key?(tooltips, {"CR-554466-501", "place-sstat"}) @@ -72,13 +61,12 @@ defmodule Dotcom.VehicleHelpersTest do assert tooltip_base.route.type == 2 assert tooltip_base.trip.name == "501" assert tooltip_base.trip.headsign == "Worcester" - assert tooltip_base.prediction.status == "On Time" assert tooltip_base.vehicle.status == :stopped end test "it does not return a tooltip if a vehicle has a null stop_id" do null_location = %{{"trip-1", nil} => %Vehicles.Vehicle{}} - tooltips = build_tooltip_index(@route, Enum.concat(@locations, null_location), @predictions) + tooltips = build_tooltip_index(@route, Enum.concat(@locations, null_location)) assert length(Map.keys(tooltips)) == 2 assert Map.has_key?(tooltips, {"CR-554466-501", "place-sstat"}) @@ -89,13 +77,12 @@ defmodule Dotcom.VehicleHelpersTest do assert tooltip_base.route.type == 2 assert tooltip_base.trip.name == "501" assert tooltip_base.trip.headsign == "Worcester" - assert tooltip_base.prediction.status == "On Time" assert tooltip_base.vehicle.status == :stopped end test "it does return a tooltip if a vehicle has a null trip_id" do null_trip = %{{nil, "place-sstat"} => %Vehicles.Vehicle{stop_id: ""}} - tooltips = build_tooltip_index(@route, null_trip, []) + tooltips = build_tooltip_index(@route, null_trip) tooltip_base = tooltips["place-sstat"] assert length(Map.keys(tooltips)) == 2 assert Map.has_key?(tooltips, {nil, "place-sstat"}) @@ -105,39 +92,6 @@ defmodule Dotcom.VehicleHelpersTest do assert tooltip_base.prediction == nil assert tooltip_base.vehicle == %Vehicles.Vehicle{stop_id: ""} end - - test "it uses the prediction corresponding to the vehicle's current stop" do - locations = %{ - {"trip_1", "stop_1"} => %Vehicles.Vehicle{ - stop_id: "stop_1", - trip_id: "trip_1" - } - } - - predictions = [ - %Predictions.Prediction{ - departing?: false, - time: ~N[2017-01-01T11:10:00], - status: "On Time", - trip: %Schedules.Trip{id: "trip_1"}, - stop: %Stops.Stop{id: "stop_2"} - }, - correct_prediction = %Predictions.Prediction{ - departing?: true, - time: ~N[2017-01-01T11:00:00], - status: "On Time", - trip: %Schedules.Trip{id: "trip_1"}, - stop: %Stops.Stop{id: "stop_1"} - } - ] - - route = %Routes.Route{type: 2} - - tooltips = build_tooltip_index(route, locations, predictions) - tooltip = tooltips[{"trip_1", "stop_1"}] - - assert tooltip.prediction == correct_prediction - end end describe "tooltip/1" do @@ -146,7 +100,7 @@ defmodule Dotcom.VehicleHelpersTest do } do tooltip = %{ tooltip_base - | prediction: %{tooltip_base.prediction | status: "Now Boarding", track: "4"} + | prediction: %{@prediction | status: "Now Boarding", track: "4"} } assert tooltip(tooltip) =~ "now boarding on track 4" @@ -155,7 +109,7 @@ defmodule Dotcom.VehicleHelpersTest do test "when a prediction does not have a track, gives nothing", %{tooltip_base: tooltip_base} do tooltip = %{ tooltip_base - | prediction: %{tooltip_base.prediction | status: "Now Boarding", track: nil} + | prediction: %{@prediction | status: "Now Boarding", track: nil} } refute tooltip(tooltip) =~ "now boarding" @@ -166,7 +120,7 @@ defmodule Dotcom.VehicleHelpersTest do } do tooltip = %{ tooltip_base - | prediction: %{tooltip_base.prediction | status: nil, time: nil} + | prediction: %{@prediction | status: nil, time: nil} } assert tooltip(tooltip) =~ "South Station" @@ -230,20 +184,4 @@ defmodule Dotcom.VehicleHelpersTest do assert actual =~ "has left South Station, departed on track 4" end end - - describe "prediction_for_stop/2" do - test "do not crash if vehicle prediction does not contain a trip" do - predictions = [ - %Predictions.Prediction{ - departing?: true, - time: ~N[2017-01-01T11:00:00], - status: "On Time" - } - ] - - tooltips = build_tooltip_index(@route, @locations, predictions) - tooltip = tooltips["place-sstat"] - assert tooltip(tooltip) =~ "train 501 has arrived" - end - end end diff --git a/test/dotcom_web/controllers/schedule/green_test.exs b/test/dotcom_web/controllers/schedule/green_test.exs index 3f47592315..9f4378cd21 100644 --- a/test/dotcom_web/controllers/schedule/green_test.exs +++ b/test/dotcom_web/controllers/schedule/green_test.exs @@ -62,83 +62,6 @@ defmodule DotcomWeb.ScheduleController.GreenTest do assert conn.assigns.meta_description end - describe "predictions" do - test "assigns predictions and vehicle_predictions for all branches", %{conn: conn} do - conn = - conn - |> assign(:date, ~D[2017-01-01]) - |> assign(:date_time, ~N[2017-01-01T12:00:00]) - |> assign(:origin, %Stops.Stop{id: "place-north"}) - |> assign(:destination, nil) - |> assign(:direction_id, 0) - |> assign(:route, @green_line) - |> assign(:vehicle_locations, %{ - {"trip_1", "stop_1"} => %Vehicles.Vehicle{}, - {"trip_2", "stop_3"} => %Vehicles.Vehicle{} - }) - |> predictions( - predictions_fn: fn params -> - case Enum.into(params, Map.new()) do - # vehicle predictions - %{trip: trip_ids} -> - Enum.map( - cartesian_product(trip_ids, "stop_1,stop_3"), - fn {trip_id, stop_id} -> - %Predictions.Prediction{ - id: "vehicle_predictions", - trip: %Schedules.Trip{id: trip_id}, - stop: %Stops.Stop{id: stop_id} - } - end - ) - - # predictions - value - when value in [ - %{direction_id: 0, route: "Green-E"}, - %{direction_id: 0, route: "Green-D"}, - %{direction_id: 0, route: "Green-C"}, - %{direction_id: 0, route: "Green-B"} - ] -> - [ - %Predictions.Prediction{ - id: "predictions", - trip: 1234, - route: %Routes.Route{id: value[:route]}, - stop: %Stops.Stop{id: "place-north"}, - departing?: true - } - ] - end - end - ) - - assert Enum.map(conn.assigns.predictions, & &1.route.id) == GreenLine.branch_ids() - assert Enum.all?(conn.assigns.predictions, &(&1.id == "predictions")) - - vehicle_prediction_ids = - conn.assigns.vehicle_predictions - |> Enum.map(&{&1.trip.id, &1.stop.id}) - |> Enum.sort() - - assert vehicle_prediction_ids == [ - {"trip_1", "stop_1"}, - {"trip_1", "stop_3"}, - {"trip_2", "stop_1"}, - {"trip_2", "stop_3"} - ] - - assert Enum.all?(conn.assigns.vehicle_predictions, &(&1.id == "vehicle_predictions")) - end - - defp cartesian_product(xs, ys) do - for x <- String.split(xs, ","), - y <- String.split(ys, ",") do - {x, y} - end - end - end - test "assigns vehicle locations for all branches", %{conn: conn} do conn = conn diff --git a/test/dotcom_web/controllers/schedule/predictions_test.exs b/test/dotcom_web/controllers/schedule/predictions_test.exs deleted file mode 100644 index fa8fae6b4b..0000000000 --- a/test/dotcom_web/controllers/schedule/predictions_test.exs +++ /dev/null @@ -1,337 +0,0 @@ -defmodule DotcomWeb.Schedule.PredictionsTest do - use DotcomWeb.ConnCase, async: true - - import DotcomWeb.Schedule.Predictions - import Mox - import Test.Support.Factories.Predictions.Prediction - - setup %{conn: conn} do - cache = Application.get_env(:dotcom, :cache) - cache.flush() - - conn = - conn - |> assign(:date, ~D[2017-01-01]) - |> assign(:date_time, ~N[2017-01-01T12:00:00]) - - {:ok, %{conn: conn}} - end - - describe "all_predictions/1" do - test "when given a date that isn't the service date, assigns no predictions", %{conn: conn} do - conn = - conn - |> assign(:date, ~D[2016-12-31]) - |> assign(:origin, Faker.Pokemon.location()) - |> all_predictions() - - assert conn.assigns[:predictions] == [] - assert conn.assigns[:vehicle_predictions] == [] - end - - test "when there is no origin, assigns no predictions", %{conn: conn} do - conn = - conn - |> assign(:origin, nil) - |> all_predictions() - - assert conn.assigns[:predictions] == [] - assert conn.assigns[:vehicle_predictions] == [] - end - - test "assigns predictions for a route, stop, and direction ID", %{conn: conn} do - route_id = "#{Faker.Util.digit()}" - direction_id = "#{Faker.Util.digit()}" - - expect(Predictions.Repo.Mock, :all, fn [route: ^route_id, direction_id: ^direction_id] -> - build_list(1, :prediction, %{}) - end) - - conn = - conn - |> assign(:origin, %Stops.Stop{id: Faker.Pokemon.location()}) - |> assign(:destination, nil) - |> assign(:route, %{id: route_id}) - |> assign(:direction_id, direction_id) - |> all_predictions() - - assert conn.assigns[:predictions] == [] - end - - test "ignores predictions which have the origin as their destination", %{conn: conn} do - stop_id = Faker.Pokemon.location() - trip_id = Faker.random_between(1000, 9999) - - expect(Predictions.Repo.Mock, :all, fn _ -> - build_list(1, :prediction, %{ - time: ~N[2017-01-01T00:00:00], - stop: %Stops.Stop{id: stop_id}, - trip: trip_id, - departing?: false - }) - end) - - conn = - conn - |> assign(:origin, %Stops.Stop{id: stop_id}) - |> assign(:destination, nil) - |> assign(:route, %{id: "#{Faker.Util.digit()}"}) - |> assign(:direction_id, "#{Faker.Util.digit()}") - |> all_predictions() - - assert conn.assigns.predictions == [] - end - - test "does not ignore predictions which have a trip id but not status", %{conn: conn} do - stop_id = Faker.Pokemon.location() - - prediction = - build(:prediction, %{ - time: ~N[2017-01-01T00:00:00], - stop: %Stops.Stop{id: stop_id}, - trip: Faker.random_between(1000, 9999), - departing?: true - }) - - expect(Predictions.Repo.Mock, :all, fn _ -> - [prediction] - end) - - conn = - conn - |> assign(:origin, %Stops.Stop{id: stop_id}) - |> assign(:destination, nil) - |> assign(:route, %{id: "#{Faker.Util.digit()}"}) - |> assign(:direction_id, "#{Faker.Util.digit()}") - |> all_predictions() - - assert conn.assigns.predictions == [prediction] - end - - test "does not ignore predictions which have a status but not a trip id", %{conn: conn} do - stop_id = Faker.Pokemon.location() - - prediction = - build(:prediction, %{ - time: ~N[2017-01-01T00:00:00], - stop: %Stops.Stop{id: stop_id}, - status: "On Time", - trip: nil, - departing?: true - }) - - expect(Predictions.Repo.Mock, :all, fn _ -> - [prediction] - end) - - conn = - conn - |> assign(:origin, %Stops.Stop{id: stop_id}) - |> assign(:destination, nil) - |> assign(:route, %{id: "#{Faker.Util.digit()}"}) - |> assign(:direction_id, "#{Faker.Util.digit()}") - |> all_predictions() - - assert conn.assigns.predictions == [prediction] - end - - test "ignores predictions which do not have a trip id or a status", %{conn: conn} do - stop_id = Faker.Pokemon.location() - - prediction = - build(:prediction, %{ - time: ~N[2017-01-01T00:00:00], - stop: %Stops.Stop{id: stop_id}, - status: nil, - trip: nil, - departing?: true - }) - - expect(Predictions.Repo.Mock, :all, fn _ -> - [prediction] - end) - - conn = - conn - |> assign(:origin, %Stops.Stop{id: stop_id}) - |> assign(:destination, nil) - |> assign(:route, %{id: "#{Faker.Util.digit()}"}) - |> assign(:direction_id, "#{Faker.Util.digit()}") - |> all_predictions() - - assert conn.assigns.predictions == [] - end - - test "keeps predictions without a time", %{conn: conn} do - stop_id = Faker.Pokemon.location() - - prediction = - build(:prediction, %{ - stop: %Stops.Stop{id: stop_id}, - trip: Faker.random_between(1000, 9999), - status: "", - departing?: true - }) - - expect(Predictions.Repo.Mock, :all, fn _ -> - [prediction] - end) - - conn = - conn - |> assign(:origin, %Stops.Stop{id: stop_id}) - |> assign(:destination, nil) - |> assign(:route, %{id: "#{Faker.Util.digit()}"}) - |> assign(:direction_id, "#{Faker.Util.digit()}") - |> all_predictions() - - assert conn.assigns.predictions == [prediction] - end - - test "otherwise, assigns no predictions", %{conn: conn} do - expect(Predictions.Repo.Mock, :all, fn _ -> - [] - end) - - conn = - conn - |> all_predictions() - - assert conn.assigns[:predictions] == [] - end - - test "destination predictions are assigned if destination is assigned", %{conn: conn} do - route_id = "#{Faker.Util.digit()}" - - expect(Predictions.Repo.Mock, :all, fn [route: ^route_id] -> - build_list(1, :prediction, %{}) - end) - - conn = - conn - |> assign(:origin, %Stops.Stop{id: Faker.Pokemon.location()}) - |> assign(:destination, %Stops.Stop{id: Faker.Pokemon.location()}) - |> assign(:route, %{id: route_id}) - |> assign(:direction_id, "#{Faker.Util.digit()}") - |> all_predictions() - - assert conn.assigns[:predictions] == [] - end - - @tag :flaky - test "assigns a list containing predictions for every stop with a vehicle at it", %{ - conn: conn - } do - stop_id_1 = Faker.Pokemon.location() - stop_id_2 = Faker.Pokemon.location() - route_id = "#{Faker.Util.digit()}" - trip_id_1 = "#{Faker.Internet.slug()}" - trip_id_2 = "#{Faker.Internet.slug()}" - - vehicle_locations = %{ - {trip_id_1, stop_id_1} => %Vehicles.Vehicle{ - trip_id: trip_id_1, - stop_id: stop_id_1, - status: :incoming - }, - {trip_id_2, stop_id_2} => %Vehicles.Vehicle{ - trip_id: trip_id_2, - stop_id: stop_id_2, - status: :stopped - } - } - - prediction_1 = build(:prediction, %{stop: %Stops.Stop{id: stop_id_1}}) - prediction_2 = build(:prediction, %{stop: %Stops.Stop{id: stop_id_2}}) - - trip_id_match = Enum.join(Enum.sort([trip_id_1, trip_id_2]), ",") - - Predictions.Repo.Mock - |> expect(:all, fn arg -> - assert arg[:route] == route_id - [] - end) - |> expect(:all, fn arg -> - assert arg[:trip] == trip_id_match - # we transform the data into this form so that we only need to make one repo call - [prediction_1, prediction_2] - end) - - conn = - conn - |> assign(:origin, %Stops.Stop{id: Faker.Pokemon.location()}) - |> assign(:destination, %Stops.Stop{id: Faker.Pokemon.location()}) - |> assign(:route, %{id: route_id}) - |> assign(:direction_id, "#{Faker.Util.digit()}") - |> assign(:vehicle_locations, vehicle_locations) - |> all_predictions() - - assert conn.assigns.vehicle_predictions == [ - prediction_1, - prediction_2 - ] - end - - @tag :flaky - test "does not make duplicate requests for vehicles at the same stop", %{conn: conn} do - stop_id_1 = Faker.Pokemon.location() - route_id = "#{Faker.Util.digit()}" - trip_id_1 = "#{Faker.Internet.slug()}" - trip_id_2 = "#{Faker.Internet.slug()}" - - vehicle_locations = %{ - {trip_id_1, stop_id_1} => %Vehicles.Vehicle{ - trip_id: trip_id_1, - stop_id: stop_id_1, - status: :incoming - }, - {trip_id_2, stop_id_1} => %Vehicles.Vehicle{ - trip_id: trip_id_2, - stop_id: stop_id_1, - status: :stopped - } - } - - prediction = build(:prediction, %{stop: %Stops.Stop{id: stop_id_1}}) - - Predictions.Repo.Mock - |> expect(:all, fn arg -> - assert arg[:route] == route_id - [] - end) - |> expect(:all, fn arg -> - assert arg[:trip] == Enum.join(Enum.sort([trip_id_1, trip_id_2]), ",") - # we transform the data into this form so that we only need to make one repo call - [ - prediction - ] - end) - - conn = - conn - |> assign(:origin, %Stops.Stop{id: Faker.Pokemon.location()}) - |> assign(:destination, %Stops.Stop{id: Faker.Pokemon.location()}) - |> assign(:route, %{id: route_id}) - |> assign(:direction_id, Faker.Util.pick([0, 1])) - |> assign(:vehicle_locations, vehicle_locations) - |> all_predictions() - - assert conn.assigns.vehicle_predictions == [ - prediction - ] - end - - test "assigns empty lists if the predictions return an error", %{conn: conn} do - route_id = "#{Faker.Util.digit()}" - - expect(Predictions.Repo.Mock, :all, fn [route: ^route_id] -> - {:error, :no_predictions} - end) - - conn = all_predictions(conn) - - assert conn.assigns.predictions == [] - assert conn.assigns.vehicle_predictions == [] - end - end -end