diff --git a/lib/arrow/shuttles.ex b/lib/arrow/shuttles.ex index 18138366..857af5e6 100644 --- a/lib/arrow/shuttles.ex +++ b/lib/arrow/shuttles.ex @@ -9,10 +9,12 @@ defmodule Arrow.Shuttles do alias ArrowWeb.ErrorHelpers alias Arrow.Gtfs.Route, as: GtfsRoute + alias Arrow.Gtfs.Stop, as: GtfsStop alias Arrow.Shuttles.KML alias Arrow.Shuttles.Shape alias Arrow.Shuttles.ShapesUpload alias Arrow.Shuttles.ShapeUpload + alias Arrow.Shuttles.Stop @doc """ Returns the list of shapes. @@ -331,4 +333,17 @@ defmodule Arrow.Shuttles do query = from(r in GtfsRoute, where: r.type in [:light_rail, :heavy_rail]) Repo.all(query) end + + @doc """ + Given a stop ID, returns either an Arrow-created stop, or a + stop from GTFS. Prefers the Arrow-created stop if both are + present. + """ + @spec stop_or_gtfs_stop_for_stop_id(String.t()) :: Stop.t() | GtfsStop.t() | nil + def stop_or_gtfs_stop_for_stop_id(id) do + case Repo.get_by(Stop, stop_id: id) do + nil -> Repo.get(GtfsStop, id) + stop -> stop + end + end end diff --git a/test/arrow/shuttles_test.exs b/test/arrow/shuttles_test.exs index 228af94e..3afef71f 100644 --- a/test/arrow/shuttles_test.exs +++ b/test/arrow/shuttles_test.exs @@ -1,9 +1,11 @@ defmodule Arrow.ShuttlesTest do use Arrow.DataCase + import Arrow.Factory alias Arrow.Shuttles alias Arrow.Shuttles.Shape import Arrow.ShuttlesFixtures + import Arrow.StopsFixtures import Test.Support.Helpers describe "shapes with s3 functionality enabled (mocked)" do @@ -214,4 +216,34 @@ defmodule Arrow.ShuttlesTest do assert %Ecto.Changeset{} = Shuttles.change_shuttle(shuttle) end end + + describe "stop_or_gtfs_stop_for_stop_id/1" do + test "fetches Arrow stop" do + stop = stop_fixture() + stop_id = stop.stop_id + + assert %Arrow.Shuttles.Stop{stop_id: ^stop_id} = + Shuttles.stop_or_gtfs_stop_for_stop_id(stop_id) + end + + test "fetches GTFS stop" do + gtfs_stop = insert(:gtfs_stop) + stop_id = gtfs_stop.id + + assert %Arrow.Gtfs.Stop{id: ^stop_id} = Shuttles.stop_or_gtfs_stop_for_stop_id(stop_id) + end + + test "prefers the Arrow stop if there are both Arrow and Gtfs stops" do + stop = stop_fixture() + _gtfs_stop = insert(:gtfs_stop) + stop_id = stop.stop_id + + assert %Arrow.Shuttles.Stop{stop_id: ^stop_id} = + Shuttles.stop_or_gtfs_stop_for_stop_id(stop_id) + end + + test "returns nil if no stops are found" do + assert is_nil(Shuttles.stop_or_gtfs_stop_for_stop_id("nonexistent-stop")) + end + end end diff --git a/test/support/factory.ex b/test/support/factory.ex index 41d70d1e..2f8225cc 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -67,4 +67,28 @@ defmodule Arrow.Factory do municipality: "Boston" } end + + def gtfs_stop_factory do + %Arrow.Gtfs.Stop{ + id: sequence(:source_label, &"gtfs-stop-#{&1}"), + code: nil, + name: "Test Stop", + desc: nil, + platform_code: nil, + platform_name: nil, + lat: 72.0, + lon: 43.0, + zone_id: nil, + address: nil, + url: nil, + level: nil, + location_type: :stop_platform, + parent_station: nil, + wheelchair_boarding: :accessible, + municipality: "Boston", + on_street: nil, + at_street: nil, + vehicle_type: :bus + } + end end