Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Live.TripPlanner): support /from and /to shortcuts #2306

Merged
merged 1 commit into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading