Skip to content

Commit

Permalink
feat(Live.TripPlanner): support /from and /to shortcuts (#2306)
Browse files Browse the repository at this point in the history
  • Loading branch information
thecristen authored Jan 7, 2025
1 parent 3d38b6f commit 33744f2
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 3 deletions.
24 changes: 24 additions & 0 deletions lib/dotcom/trip_plan/anti_corruption_layer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,30 @@ defmodule Dotcom.TripPlan.AntiCorruptionLayer do
We ignore datetime_type and datetime and allow those to be set to 'now' and the current time respectively.
"""

@location_service Application.compile_env!(:dotcom, :location_service)

@doc """
Given a query for the old trip planner /to or /from actions, replicate the old
behavior by searching for a location and using the first result. Convert this
to the new trip planner form values.
"""
def convert_old_action(action) do
with [key] when key in [:from, :to] <- Map.keys(action),
query when is_binary(query) <- Map.get(action, key),
{:ok, [%LocationService.Address{} = geocoded | _]} <- @location_service.geocode(query) do
%{
"plan" => %{
"#{key}_latitude" => geocoded.latitude,
"#{key}_longitude" => geocoded.longitude,
"#{key}" => geocoded.formatted
}
}
else
_ ->
%{"plan" => %{}}
end
end

@doc """
Given the params from the old trip planner, convert them to the new trip planner form values.
Expand Down
18 changes: 16 additions & 2 deletions lib/dotcom_web/live/trip_planner.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,16 @@ defmodule DotcomWeb.Live.TripPlanner do
- Clean any query parameters and convert them to a changeset for the input form.
- Then, submit the form if the changeset is valid (i.e., the user visited with valid query parameters).
"""
def mount(params, _session, socket) do
changeset = query_params_to_changeset(params)
def mount(params, _session, %{assigns: %{live_action: live_action}} = socket) do
changeset =
if is_atom(live_action) and is_binary(params["place"]) do
# Handle the /to/:place or /from/:place situation
live_action
|> action_to_query_params(params["place"])
|> query_params_to_changeset()
else
query_params_to_changeset(params)
end

new_socket =
socket
Expand Down Expand Up @@ -355,6 +363,12 @@ defmodule DotcomWeb.Live.TripPlanner do
Timex.shift(datetime, minutes: added_minutes)
end

defp action_to_query_params(action_key, action_value) do
%{}
|> Map.put(action_key, action_value)
|> AntiCorruptionLayer.convert_old_action()
end

# Convert query parameters to a changeset for the input form.
# Use an anti corruption layer to convert old query parameters to new ones.
defp query_params_to_changeset(params) do
Expand Down
2 changes: 2 additions & 0 deletions lib/dotcom_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ defmodule DotcomWeb.Router do

live_session :rider, layout: {DotcomWeb.LayoutView, :preview} do
live("/trip-planner", Live.TripPlanner)
live("/trip-planner/from/:place", Live.TripPlanner, :from)
live("/trip-planner/to/:place", Live.TripPlanner, :to)
end
end

Expand Down
49 changes: 48 additions & 1 deletion test/dotcom/trip_plan/anti_corruption_layer_test.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,54 @@
defmodule Dotcom.TripPlan.AntiCorruptionLayerTest do
use ExUnit.Case

import Dotcom.TripPlan.AntiCorruptionLayer, only: [convert_old_params: 1]
import Dotcom.TripPlan.AntiCorruptionLayer, only: [convert_old_action: 1, convert_old_params: 1]
import Mox
import Test.Support.Factories.LocationService.LocationService

setup :verify_on_exit!

describe "convert_old_action/1" do
test "returns all defaults when no params are given" do
assert convert_old_action(%{}) == convert_old_action(%{"plan" => %{}})
end

test "returns params representing successfully geocoded result" do
query = Faker.Address.street_address()
geocoded_result = build(:address)

expect(LocationService.Mock, :geocode, fn ^query ->
{:ok, [geocoded_result]}
end)

assert convert_old_action(%{from: query}) == %{
"plan" => %{
"from" => geocoded_result.formatted,
"from_latitude" => geocoded_result.latitude,
"from_longitude" => geocoded_result.longitude
}
}
end

test "returns all defaults when no address found" do
query = Faker.Address.street_address()

expect(LocationService.Mock, :geocode, fn _ ->
{:ok, []}
end)

assert convert_old_action(%{from: query}) == %{"plan" => %{}}
end

test "returns all defaults for geocoding error" do
query = Faker.Address.street_address()

expect(LocationService.Mock, :geocode, fn _ ->
{:error, :internal_error}
end)

assert convert_old_action(%{from: query}) == %{"plan" => %{}}
end
end

describe "convert_old_params/1" do
test "returns all defaults when no params are given" do
Expand Down

0 comments on commit 33744f2

Please sign in to comment.