defmodule BerrypodWeb.Admin.AccountTest do use BerrypodWeb.ConnCase, async: false import Phoenix.LiveViewTest import Berrypod.AccountsFixtures alias Berrypod.Accounts setup do user = user_fixture() %{user: user} end describe "unauthenticated" do test "redirects to login", %{conn: conn} do {:error, redirect} = live(conn, ~p"/admin/account") assert {:redirect, %{to: path}} = redirect assert path == ~p"/users/log-in" end end describe "account page" do setup %{conn: conn, user: user} do conn = log_in_user(conn, user) %{conn: conn, user: user} end test "renders email and password forms", %{conn: conn, user: user} do {:ok, view, html} = live(conn, ~p"/admin/account") assert html =~ "Account" assert html =~ user.email assert has_element?(view, "#email_form") assert has_element?(view, "#password_form") end test "validates email change", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/account") result = view |> element("#email_form") |> render_change(%{"user" => %{"email" => "with spaces"}}) assert result =~ "must have the @ sign and no spaces" end test "submits email change", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/account") result = view |> form("#email_form", %{"user" => %{"email" => unique_user_email()}}) |> render_submit() assert result =~ "A link to confirm your email" end test "validates password", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/account") result = view |> element("#password_form") |> render_change(%{ "user" => %{ "password" => "short", "password_confirmation" => "mismatch" } }) assert result =~ "should be at least 12 character(s)" end test "submits valid password change", %{conn: conn, user: user} do new_password = valid_user_password() {:ok, view, _html} = live(conn, ~p"/admin/account") form = form(view, "#password_form", %{ "user" => %{ "email" => user.email, "password" => new_password, "password_confirmation" => new_password } }) render_submit(form) new_password_conn = follow_trigger_action(form, conn) assert redirected_to(new_password_conn) == ~p"/admin/account" assert Accounts.get_user_by_email_and_password(user.email, new_password) end end describe "two-factor authentication" do setup %{conn: conn, user: user} do conn = log_in_user(conn, user) %{conn: conn, user: user} end test "shows 2FA section", %{conn: conn} do {:ok, _view, html} = live(conn, ~p"/admin/account") assert html =~ "Two-factor authentication" assert html =~ "Off" assert html =~ "Enable 2FA" end test "shows enabled state when TOTP is enabled", %{conn: conn, user: user} do # Enable TOTP for the user secret = NimbleTOTP.secret() code = NimbleTOTP.verification_code(secret) {:ok, _user, _codes} = Accounts.enable_totp(user, secret, code) {:ok, _view, html} = live(conn, ~p"/admin/account") assert html =~ "Two-factor authentication" assert html =~ "Enabled" assert html =~ "Disable 2FA" end end end