Skip to content

Commit

Permalink
Handle form redirects in Live pages (#21)
Browse files Browse the repository at this point in the history
Closes #19 

What changed?
============

Our `Live` implementation doesn't handle form redirects, be they to
another LiveView with `push_navigate/2` or to a static page via
`redirect/2`.

This commit updates the implementation to follow redirects the same way
we follow redirects when we click on links.

Testing note
-----------

We also create a new describe block to encapsulate all the testing for
`fill_form/3` + `click_button/2`.
  • Loading branch information
germsvel authored Feb 10, 2024
1 parent 9014df7 commit 531e5e9
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 58 deletions.
48 changes: 14 additions & 34 deletions lib/phoenix_test/live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,10 @@ defimpl PhoenixTest.Driver, for: PhoenixTest.Live do
end

def click_link(session, selector, text) do
result =
session.view
|> element(selector, text)
|> render_click()
|> maybe_redirect(session)

case result do
{:ok, view, _} ->
%{session | view: view}

{:static_view, conn, path} ->
PhoenixTest.visit(conn, path)
end
session.view
|> element(selector, text)
|> render_click()
|> maybe_redirect(session)
end

def click_button(session, text) do
Expand Down Expand Up @@ -93,24 +84,14 @@ defimpl PhoenixTest.Driver, for: PhoenixTest.Live do
session.view
|> form(form.selector, form.form_data)
|> render_submit()

session
|> maybe_redirect(session)
end

defp regular_click(session, selector, text) do
result =
session.view
|> element(selector, text)
|> render_click()
|> maybe_redirect(session)

case result do
{:ok, view, _} ->
%{session | view: view}

{:static_view, conn, path} ->
PhoenixTest.visit(conn, path)
end
session.view
|> element(selector, text)
|> render_click()
|> maybe_redirect(session)
end

def fill_form(session, selector, form_data) do
Expand Down Expand Up @@ -148,24 +129,23 @@ defimpl PhoenixTest.Driver, for: PhoenixTest.Live do
session.view
|> form(selector, form_data)
|> render_submit()

session
|> maybe_redirect(session)
end

def render_html(%{view: view}) do
render(view)
end

defp maybe_redirect({:error, {:redirect, %{to: path}}}, session) do
{:static_view, session.conn, path}
PhoenixTest.visit(session.conn, path)
end

defp maybe_redirect({:error, {:live_redirect, _}} = result, session) do
result
|> follow_redirect(session.conn)
{:ok, view, _} = follow_redirect(result, session.conn)
%{session | view: view}
end

defp maybe_redirect(html, session) when is_binary(html) do
{:ok, session.view, html}
session
end
end
80 changes: 56 additions & 24 deletions test/phoenix_test/live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -126,37 +126,13 @@ defmodule PhoenixTest.LiveTest do
assert starting_html == ending_html
end

test "can handle forms with inputs, checkboxes, selects, textboxes", %{conn: conn} do
conn
|> visit("/live/index")
|> fill_form("#full-form",
name: "Aragorn",
admin: "on",
race: "human",
notes: "King of Gondor"
)
|> click_button("Save")
|> assert_has("#form-data", "name: Aragorn")
|> assert_has("#form-data", "admin: on")
|> assert_has("#form-data", "race: human")
|> assert_has("#form-data", "notes: King of Gondor")
end

test "triggers a phx-change event on a form (when it has one)", %{conn: conn} do
conn
|> visit("/live/index")
|> fill_form("#email-form", email: nil)
|> assert_has("#form-errors", "Errors present")
end

test "can be combined with click_button to submit a form", %{conn: conn} do
conn
|> visit("/live/index")
|> fill_form("#email-form", email: "[email protected]")
|> click_button("Save")
|> assert_has("#form-data", "email: [email protected]")
end

test "raises an error when form can't be found with selector", %{conn: conn} do
assert_raise ArgumentError, ~r/Could not find element with selector/, fn ->
conn
Expand All @@ -182,6 +158,48 @@ defmodule PhoenixTest.LiveTest do
end
end

describe "fill_form + click_button" do
test "fill_form can be combined with click_button to submit a form", %{conn: conn} do
conn
|> visit("/live/index")
|> fill_form("#email-form", email: "[email protected]")
|> click_button("Save")
|> assert_has("#form-data", "email: [email protected]")
end

test "can handle forms with inputs, checkboxes, selects, textboxes", %{conn: conn} do
conn
|> visit("/live/index")
|> fill_form("#full-form",
name: "Aragorn",
admin: "on",
race: "human",
notes: "King of Gondor"
)
|> click_button("Save")
|> assert_has("#form-data", "name: Aragorn")
|> assert_has("#form-data", "admin: on")
|> assert_has("#form-data", "race: human")
|> assert_has("#form-data", "notes: King of Gondor")
end

test "follows form's redirect to live page", %{conn: conn} do
conn
|> visit("/live/index")
|> fill_form("#redirect-form", name: "Aragorn")
|> click_button("#redirect-form-submit", "Save")
|> assert_has("h1", "LiveView page 2")
end

test "follows form's redirect to static page", %{conn: conn} do
conn
|> visit("/live/index")
|> fill_form("#redirect-form-to-static", name: "Aragorn")
|> click_button("#redirect-form-to-static-submit", "Save")
|> assert_has("h1", "Main page")
end
end

describe "submit_form/3" do
test "submits a form via phx-submit", %{conn: conn} do
conn
Expand All @@ -190,6 +208,20 @@ defmodule PhoenixTest.LiveTest do
|> assert_has("#form-data", "email: [email protected]")
end

test "follows form's redirect to live page", %{conn: conn} do
conn
|> visit("/live/index")
|> submit_form("#redirect-form", name: "Aragorn")
|> assert_has("h1", "LiveView page 2")
end

test "follows form's redirect to static page", %{conn: conn} do
conn
|> visit("/live/index")
|> submit_form("#redirect-form-to-static", name: "Aragorn")
|> assert_has("h1", "Main page")
end

test "raises an error if the form can't be found", %{conn: conn} do
message = ~r/expected selector "#no-existing-form" to return a single element/

Expand Down
24 changes: 24 additions & 0 deletions test/support/index_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,22 @@ defmodule PhoenixTest.IndexLive do
<textarea name="notes" rows="5" cols="33">
</textarea>
</form>
<form id="redirect-form" phx-submit="save-redirect-form">
<label for="name">Name</label>
<input name="name" />
<button type="submit" id="redirect-form-submit">
Save
</button>
</form>
<form id="redirect-form-to-static" phx-submit="save-redirect-form-to-static">
<label for="name">Name</label>
<input name="name" />
<button type="submit" id="redirect-form-to-static-submit">
Save
</button>
</form>
"""
end

Expand Down Expand Up @@ -95,6 +111,14 @@ defmodule PhoenixTest.IndexLive do
}
end

def handle_event("save-redirect-form", _, socket) do
{:noreply, push_navigate(socket, to: "/live/page_2")}
end

def handle_event("save-redirect-form-to-static", _, socket) do
{:noreply, redirect(socket, to: "/page/index")}
end

def handle_event("validate-email", %{"email" => email}, socket) do
case email do
empty when empty == nil or empty == "" ->
Expand Down

0 comments on commit 531e5e9

Please sign in to comment.