aprs.me/test/aprsme_web/live/user_settings_live_test.exs
Graham McIntire 4481888976
Fix settings page showing validation errors on initial load
The email and callsign changesets add "did not change" errors when
created with empty attrs (on mount). Guard all field error displays
on changeset.action being set so errors only appear after user
interaction.
2026-02-20 17:09:18 -06:00

191 lines
5.5 KiB
Elixir

defmodule AprsmeWeb.UserSettingsLiveTest do
use AprsmeWeb.ConnCase
import Aprsme.AccountsFixtures
import Phoenix.LiveViewTest
alias Aprsme.Accounts
describe "Settings page" do
setup %{conn: conn} do
user = user_fixture()
conn = log_in_user(conn, user)
{:ok, conn: conn, user: user}
end
test "renders settings page", %{conn: conn} do
{:ok, _lv, html} = live(conn, ~p"/users/settings", on_error: :warn)
assert html =~ "Change Email"
assert html =~ "Change Callsign"
assert html =~ "Change Password"
end
test "does not show validation errors on initial load", %{conn: conn} do
{:ok, _lv, html} = live(conn, ~p"/users/settings", on_error: :warn)
refute html =~ "did not change"
refute html =~ "can't be blank"
refute html =~ "can't be blank"
end
test "redirects if user is not logged in" do
conn = build_conn()
{:error, redirect} = live(conn, ~p"/users/settings")
assert {:redirect, %{to: path, flash: flash}} = redirect
assert path == ~p"/users/log_in"
assert %{"error" => "You must log in to access this page."} = flash
end
end
describe "update callsign form" do
setup %{conn: conn} do
user = user_fixture()
conn = log_in_user(conn, user)
{:ok, conn: conn, user: user}
end
test "updates the user callsign", %{conn: conn, user: user} do
{:ok, lv, _html} = live(conn, ~p"/users/settings", on_error: :warn)
lv
|> form("#callsign_form", %{
"current_password" => valid_user_password(),
"user" => %{"callsign" => "W9NEW"}
})
|> render_submit()
# The form should redirect after success
flash = assert_redirect(lv, ~p"/users/settings")
assert flash["info"] == "Callsign updated successfully."
# Verify the callsign was updated
updated_user = Accounts.get_user!(user.id)
assert updated_user.callsign == "W9NEW"
end
test "renders errors with invalid callsign", %{conn: conn} do
{:ok, lv, _html} = live(conn, ~p"/users/settings", on_error: :warn)
result =
lv
|> form("#callsign_form", %{
"current_password" => valid_user_password(),
"user" => %{"callsign" => "INVALID"}
})
|> render_submit()
assert result =~ "must be a valid amateur radio callsign"
end
test "renders errors with invalid password", %{conn: conn, user: user} do
{:ok, lv, _html} = live(conn, ~p"/users/settings", on_error: :warn)
result =
lv
|> form("#callsign_form", %{
"current_password" => "invalid",
"user" => %{"callsign" => "W9NEW"}
})
|> render_submit()
assert result =~ "is not valid"
# Verify the callsign was not updated
updated_user = Accounts.get_user!(user.id)
assert updated_user.callsign == user.callsign
end
end
describe "update email form" do
setup %{conn: conn} do
user = user_fixture()
conn = log_in_user(conn, user)
{:ok, conn: conn, user: user}
end
test "updates the user email", %{conn: conn, user: user} do
{:ok, lv, _html} = live(conn, ~p"/users/settings", on_error: :warn)
result =
lv
|> form("#email_form", %{
"current_password" => valid_user_password(),
"user" => %{"email" => unique_user_email()}
})
|> render_submit()
assert result =~ "A link to confirm your email"
assert Accounts.get_user_by_email(user.email)
end
test "renders errors with invalid data (phx-change)", %{conn: conn} do
{:ok, lv, _html} = live(conn, ~p"/users/settings", on_error: :warn)
result =
lv
|> element("#email_form")
|> render_change(%{
"current_password" => valid_user_password(),
"user" => %{"email" => "with spaces"}
})
assert result =~ "must have the @ sign and no spaces"
end
end
describe "update password form" do
setup %{conn: conn} do
user = user_fixture()
conn = log_in_user(conn, user)
{:ok, conn: conn, user: user}
end
test "updates the user password", %{conn: conn, user: user} do
{:ok, lv, _html} = live(conn, ~p"/users/settings", on_error: :warn)
form =
form(lv, "#password_form", %{
"current_password" => valid_user_password(),
"user" => %{
"email" => user.email,
"password" => "new valid password",
"password_confirmation" => "new valid password"
}
})
render_submit(form)
new_password_conn = follow_trigger_action(form, conn)
assert redirected_to(new_password_conn) == ~p"/users/settings"
assert get_session(new_password_conn, :user_token) != get_session(conn, :user_token)
assert Phoenix.Flash.get(new_password_conn.assigns.flash, :info) =~
"Password updated successfully"
assert Accounts.get_user_by_email_and_password(user.email, "new valid password")
end
test "renders errors with invalid data (phx-change)", %{conn: conn} do
{:ok, lv, _html} = live(conn, ~p"/users/settings", on_error: :warn)
result =
lv
|> element("#password_form")
|> render_change(%{
"current_password" => valid_user_password(),
"user" => %{
"password" => "short",
"password_confirmation" => "does not match"
}
})
assert result =~ "should be at least 12 character"
assert result =~ "does not match password"
end
end
end