settings_test.exs (6697B)
1 defmodule DailyTrackerWeb.UserLive.SettingsTest do 2 use DailyTrackerWeb.ConnCase, async: true 3 4 alias DailyTracker.Accounts 5 import Phoenix.LiveViewTest 6 import DailyTracker.AccountsFixtures 7 8 describe "Settings page" do 9 test "renders settings page", %{conn: conn} do 10 {:ok, _lv, html} = 11 conn 12 |> log_in_user(user_fixture()) 13 |> live(~p"/users/settings") 14 15 assert html =~ "Change Email" 16 assert html =~ "Save Password" 17 end 18 19 test "redirects if user is not logged in", %{conn: conn} do 20 assert {:error, redirect} = live(conn, ~p"/users/settings") 21 22 assert {:redirect, %{to: path, flash: flash}} = redirect 23 assert path == ~p"/users/log-in" 24 assert %{"error" => "You must log in to access this page."} = flash 25 end 26 27 test "redirects if user is not in sudo mode", %{conn: conn} do 28 {:ok, conn} = 29 conn 30 |> log_in_user(user_fixture(), 31 token_authenticated_at: DateTime.add(DateTime.utc_now(:second), -11, :minute) 32 ) 33 |> live(~p"/users/settings") 34 |> follow_redirect(conn, ~p"/users/log-in") 35 36 assert conn.resp_body =~ "You must re-authenticate to access this page." 37 end 38 end 39 40 describe "update email form" do 41 setup %{conn: conn} do 42 user = user_fixture() 43 %{conn: log_in_user(conn, user), user: user} 44 end 45 46 test "updates the user email", %{conn: conn, user: user} do 47 new_email = unique_user_email() 48 49 {:ok, lv, _html} = live(conn, ~p"/users/settings") 50 51 result = 52 lv 53 |> form("#email_form", %{ 54 "user" => %{"email" => new_email} 55 }) 56 |> render_submit() 57 58 assert result =~ "A link to confirm your email" 59 assert Accounts.get_user_by_email(user.email) 60 end 61 62 test "renders errors with invalid data (phx-change)", %{conn: conn} do 63 {:ok, lv, _html} = live(conn, ~p"/users/settings") 64 65 result = 66 lv 67 |> element("#email_form") 68 |> render_change(%{ 69 "action" => "update_email", 70 "user" => %{"email" => "with spaces"} 71 }) 72 73 assert result =~ "Change Email" 74 assert result =~ "must have the @ sign and no spaces" 75 end 76 77 test "renders errors with invalid data (phx-submit)", %{conn: conn, user: user} do 78 {:ok, lv, _html} = live(conn, ~p"/users/settings") 79 80 result = 81 lv 82 |> form("#email_form", %{ 83 "user" => %{"email" => user.email} 84 }) 85 |> render_submit() 86 87 assert result =~ "Change Email" 88 assert result =~ "did not change" 89 end 90 end 91 92 describe "update password form" do 93 setup %{conn: conn} do 94 user = user_fixture() 95 %{conn: log_in_user(conn, user), user: user} 96 end 97 98 test "updates the user password", %{conn: conn, user: user} do 99 new_password = valid_user_password() 100 101 {:ok, lv, _html} = live(conn, ~p"/users/settings") 102 103 form = 104 form(lv, "#password_form", %{ 105 "user" => %{ 106 "email" => user.email, 107 "password" => new_password, 108 "password_confirmation" => new_password 109 } 110 }) 111 112 render_submit(form) 113 114 new_password_conn = follow_trigger_action(form, conn) 115 116 assert redirected_to(new_password_conn) == ~p"/users/settings" 117 118 assert get_session(new_password_conn, :user_token) != get_session(conn, :user_token) 119 120 assert Phoenix.Flash.get(new_password_conn.assigns.flash, :info) =~ 121 "Password updated successfully" 122 123 assert Accounts.get_user_by_email_and_password(user.email, new_password) 124 end 125 126 test "renders errors with invalid data (phx-change)", %{conn: conn} do 127 {:ok, lv, _html} = live(conn, ~p"/users/settings") 128 129 result = 130 lv 131 |> element("#password_form") 132 |> render_change(%{ 133 "user" => %{ 134 "password" => "too short", 135 "password_confirmation" => "does not match" 136 } 137 }) 138 139 assert result =~ "Save Password" 140 assert result =~ "should be at least 12 character(s)" 141 assert result =~ "does not match password" 142 end 143 144 test "renders errors with invalid data (phx-submit)", %{conn: conn} do 145 {:ok, lv, _html} = live(conn, ~p"/users/settings") 146 147 result = 148 lv 149 |> form("#password_form", %{ 150 "user" => %{ 151 "password" => "too short", 152 "password_confirmation" => "does not match" 153 } 154 }) 155 |> render_submit() 156 157 assert result =~ "Save Password" 158 assert result =~ "should be at least 12 character(s)" 159 assert result =~ "does not match password" 160 end 161 end 162 163 describe "confirm email" do 164 setup %{conn: conn} do 165 user = user_fixture() 166 email = unique_user_email() 167 168 token = 169 extract_user_token(fn url -> 170 Accounts.deliver_user_update_email_instructions(%{user | email: email}, user.email, url) 171 end) 172 173 %{conn: log_in_user(conn, user), token: token, email: email, user: user} 174 end 175 176 test "updates the user email once", %{conn: conn, user: user, token: token, email: email} do 177 {:error, redirect} = live(conn, ~p"/users/settings/confirm-email/#{token}") 178 179 assert {:live_redirect, %{to: path, flash: flash}} = redirect 180 assert path == ~p"/users/settings" 181 assert %{"info" => message} = flash 182 assert message == "Email changed successfully." 183 refute Accounts.get_user_by_email(user.email) 184 assert Accounts.get_user_by_email(email) 185 186 # use confirm token again 187 {:error, redirect} = live(conn, ~p"/users/settings/confirm-email/#{token}") 188 assert {:live_redirect, %{to: path, flash: flash}} = redirect 189 assert path == ~p"/users/settings" 190 assert %{"error" => message} = flash 191 assert message == "Email change link is invalid or it has expired." 192 end 193 194 test "does not update email with invalid token", %{conn: conn, user: user} do 195 {:error, redirect} = live(conn, ~p"/users/settings/confirm-email/oops") 196 assert {:live_redirect, %{to: path, flash: flash}} = redirect 197 assert path == ~p"/users/settings" 198 assert %{"error" => message} = flash 199 assert message == "Email change link is invalid or it has expired." 200 assert Accounts.get_user_by_email(user.email) 201 end 202 203 test "redirects if user is not logged in", %{token: token} do 204 conn = build_conn() 205 {:error, redirect} = live(conn, ~p"/users/settings/confirm-email/#{token}") 206 assert {:redirect, %{to: path, flash: flash}} = redirect 207 assert path == ~p"/users/log-in" 208 assert %{"error" => message} = flash 209 assert message == "You must log in to access this page." 210 end 211 end 212 end