Skip to content

Commit

Permalink
Show alternative times and tests (#2187)
Browse files Browse the repository at this point in the history
* show alternative times and tests

* wrong name in test
  • Loading branch information
anthonyshull authored Oct 8, 2024
1 parent f98ea76 commit 375ba54
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 4 deletions.
17 changes: 13 additions & 4 deletions lib/dotcom_web/components/trip_planner/itinerary_group.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryGroup do
def itinerary_group(assigns) do
~H"""
<div class="mb-3 p-2 border border-2 border-slate-200">
<% [first | rest] = @group %>
<div class="text-slate-800 font-bold">Group with <%= Enum.count(@group) %> options</div>
<.accordion :for={{variation, index} <- Enum.with_index(@group)} open={index === 0}>
<.accordion>
<:heading>
<%= format_datetime(variation.departure) %> — <%= format_datetime(variation.arrival) %>
<%= format_datetime_full(first.departure) %> — <%= format_datetime_full(first.arrival) %>
</:heading>
<:content>
<div :for={leg <- variation.legs}>
<div :for={leg <- first.legs}>
<.leg
start_time={leg.start}
end_time={leg.stop}
Expand All @@ -32,13 +33,21 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryGroup do
realtime_state={leg.realtime_state}
/>
</div>
<%= if Enum.count(rest) > 0, do: "Similar trips depart at:" %>
<span :for={alternative <- rest}>
<%= format_datetime_short(alternative.departure) %>
</span>
</:content>
</.accordion>
</div>
"""
end

defp format_datetime(datetime) do
defp format_datetime_full(datetime) do
Timex.format!(datetime, "%-I:%M %p", :strftime)
end

defp format_datetime_short(datetime) do
Timex.format!(datetime, "%-I:%M", :strftime)
end
end
104 changes: 104 additions & 0 deletions test/dotcom/trip_plan/itinerary_group_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
defmodule Dotcom.TripPlan.ItineraryTest do
@moduledoc false

use ExUnit.Case, async: true

import Mox

alias Dotcom.TripPlan.ItineraryGroups
alias Test.Support.Factories.{Stops.Stop, TripPlanner.TripPlanner}

setup do
stub(Stops.Repo.Mock, :get, fn _ ->
Stop.build(:stop)
end)

stops = TripPlanner.build_list(3, :stop_named_position)

{:ok, stops: stops}
end

describe "from_itineraries/1" do
test "groups itineraries with the same mode, from, and to", %{stops: [a, b, c]} do
# SETUP
bus_a_b_leg = TripPlanner.build(:bus_leg, from: a, to: b)
subway_b_c_leg = TripPlanner.build(:subway_leg, from: b, to: c)

itineraries =
TripPlanner.build_list(:rand.uniform(5), :itinerary, legs: [bus_a_b_leg, subway_b_c_leg])

# EXERCISE
grouped_itineraries = ItineraryGroups.from_itineraries(itineraries)

# VERIFY
assert Kernel.length(grouped_itineraries) == 1
end

test "does not group itineraries with different modes", %{stops: [a, b, c]} do
# SETUP
bus_a_b_leg = TripPlanner.build(:bus_leg, from: a, to: b)
bus_b_c_leg = TripPlanner.build(:bus_leg, from: b, to: c)
subway_b_c_leg = TripPlanner.build(:subway_leg, from: b, to: c)

first_itinerary = TripPlanner.build(:itinerary, legs: [bus_a_b_leg, bus_b_c_leg])
second_interary = TripPlanner.build(:itinerary, legs: [bus_a_b_leg, subway_b_c_leg])

# EXERCISE
grouped_itineraries = ItineraryGroups.from_itineraries([first_itinerary, second_interary])

# VERIFY
assert Kernel.length(grouped_itineraries) == 2
end

test "does not group itineraries with different froms", %{stops: [a, b, c]} do
# SETUP
bus_a_b_leg = TripPlanner.build(:bus_leg, from: a, to: b)
bus_b_c_leg = TripPlanner.build(:bus_leg, from: b, to: c)
bus_c_a_leg = TripPlanner.build(:bus_leg, from: c, to: a)

first_itinerary = TripPlanner.build(:itinerary, legs: [bus_a_b_leg, bus_b_c_leg])
second_interary = TripPlanner.build(:itinerary, legs: [bus_a_b_leg, bus_c_a_leg])

# EXERCISE
grouped_itineraries = ItineraryGroups.from_itineraries([first_itinerary, second_interary])

# VERIFY
assert Kernel.length(grouped_itineraries) == 2
end

test "does not group itineraries with different tos", %{stops: [a, b, c]} do
# SETUP
bus_a_b_leg = TripPlanner.build(:bus_leg, from: a, to: b)
bus_b_c_leg = TripPlanner.build(:bus_leg, from: b, to: c)
bus_b_a_leg = TripPlanner.build(:bus_leg, from: b, to: a)

first_itinerary = TripPlanner.build(:itinerary, legs: [bus_a_b_leg, bus_b_c_leg])
second_interary = TripPlanner.build(:itinerary, legs: [bus_a_b_leg, bus_b_a_leg])

# EXERCISE
grouped_itineraries = ItineraryGroups.from_itineraries([first_itinerary, second_interary])

# VERIFY
assert Kernel.length(grouped_itineraries) == 2
end
end

test "ignores short walking distances of < 0.2 miles", %{stops: [a, b, c]} do
# SETUP
bus_a_b_leg = TripPlanner.build(:bus_leg, from: a, to: b)
walk_b_c_leg = TripPlanner.build(:walking_leg, from: b, to: c) |> Map.put(:distance, 0.199)
walk_c_b_leg = TripPlanner.build(:walking_leg, from: c, to: b) |> Map.put(:distance, 0.199)
bus_b_a_leg = TripPlanner.build(:bus_leg, from: b, to: a)

first_itinerary =
TripPlanner.build(:itinerary, legs: [bus_a_b_leg, walk_b_c_leg, walk_c_b_leg, bus_b_a_leg])

second_itinerary = TripPlanner.build(:itinerary, legs: [bus_a_b_leg, bus_b_a_leg])

# EXERCISE
grouped_itineraries = ItineraryGroups.from_itineraries([first_itinerary, second_itinerary])

# VERIFY
assert Kernel.length(grouped_itineraries) == 1
end
end

0 comments on commit 375ba54

Please sign in to comment.