towerops/test/towerops_web/live/user_settings_live_test.exs

233 lines
6.8 KiB
Elixir

defmodule ToweropsWeb.UserSettingsLiveTest do
use ToweropsWeb.ConnCase, async: true
import Phoenix.LiveViewTest
import Towerops.AccountsFixtures
alias Towerops.Accounts
describe "UserSettingsLive without sudo mode" do
setup :register_and_log_in_user
test "redirects to sudo mode verification", %{conn: conn} do
# Without sudo mode, should redirect to sudo verification
{:error, {:redirect, %{to: path}}} = live(conn, ~p"/users/settings")
assert path == ~p"/users/sudo-verify"
end
end
describe "UserSettingsLive with sudo mode" do
setup :register_and_log_in_user_with_sudo
test "renders settings page", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/users/settings")
assert html =~ "Account Settings"
assert html =~ "Personal Information"
end
test "allows updating profile", %{conn: conn, user: user} do
{:ok, view, _html} = live(conn, ~p"/users/settings")
# Update profile
result =
view
|> form("#profile-form", user: %{name: "Updated Name"})
|> render_submit()
assert result =~ "Profile updated successfully"
# Verify database was updated
updated_user = Accounts.get_user!(user.id)
assert updated_user.name == "Updated Name"
end
test "allows updating email", %{conn: conn, user: user} do
new_email = unique_user_email()
{:ok, view, _html} = live(conn, ~p"/users/settings")
# Update email
result =
view
|> form("#email-form", user: %{email: new_email})
|> render_submit()
assert result =~ "A link to confirm your email"
# Old email should still be in use
assert Accounts.get_user_by_email(user.email)
end
test "allows updating password", %{conn: conn} do
new_password = valid_user_password()
{:ok, view, _html} = live(conn, ~p"/users/settings")
# Update password
result =
view
|> form("#password-form",
user: %{
password: new_password,
password_confirmation: new_password,
current_password: valid_user_password()
}
)
|> render_submit()
assert result =~ "Password updated successfully"
end
test "requires current password for password update", %{conn: conn} do
new_password = valid_user_password()
{:ok, view, _html} = live(conn, ~p"/users/settings")
# Try to update password without current password
result =
view
|> form("#password-form",
user: %{
password: new_password,
password_confirmation: new_password,
current_password: "wrong"
}
)
|> render_submit()
assert result =~ "is not valid"
end
test "shows tabs navigation", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/users/settings")
# Check for tab navigation
assert html =~ "Personal"
assert html =~ "Security"
assert html =~ "Organizations"
assert html =~ "API Tokens"
assert html =~ "Sessions"
assert html =~ "Activity"
end
test "allows switching tabs via params", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/users/settings?tab=security")
assert html =~ "Account Settings"
# Security tab should be active (would need to check for active class in real template)
end
end
describe "UserSettingsLive TOTP management with sudo mode" do
setup :register_and_log_in_user_with_sudo
test "shows enrolled TOTP devices", %{conn: conn, user: user} do
# Create a TOTP device
Accounts.create_user_totp_device(user, %{name: "Test Authenticator"})
{:ok, _view, html} = live(conn, ~p"/users/settings?tab=security")
assert html =~ "Test Authenticator"
end
test "allows removing TOTP devices", %{conn: conn, user: user} do
# Create two TOTP devices (can't remove the last one)
{:ok, device1} = Accounts.create_user_totp_device(user, %{name: "Device 1"})
{:ok, _device2} = Accounts.create_user_totp_device(user, %{name: "Device 2"})
{:ok, view, _html} = live(conn, ~p"/users/settings?tab=security")
# Remove device 1
view
|> element("#remove-totp-device-#{device1.id}")
|> render_click()
# Verify device was removed
assert Accounts.get_user_totp_device(device1.id) == nil
end
end
describe "UserSettingsLive mobile sessions with sudo mode" do
setup :register_and_log_in_user_with_sudo
test "shows mobile sessions", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/users/settings?tab=sessions")
assert html =~ "Browser Sessions"
assert html =~ "Mobile Sessions"
end
end
describe "UserSettingsLive API tokens with sudo mode" do
setup :register_and_log_in_user_with_sudo
test "shows API tokens tab", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/users/settings?tab=api-tokens")
assert html =~ "API Tokens"
assert html =~ "Create New Token"
end
test "allows creating API tokens", %{conn: conn, user: user} do
{:ok, view, _html} = live(conn, ~p"/users/settings?tab=api-tokens")
# Open create token modal
view
|> element("button", "Create New Token")
|> render_click()
# Submit token creation form
result =
view
|> form("#token-form", token: %{name: "Test Token"})
|> render_submit()
assert result =~ "API token created successfully"
# Verify token was created
tokens = Accounts.list_user_api_tokens(user)
assert Enum.any?(tokens, fn t -> t.name == "Test Token" end)
end
end
describe "UserSettingsLive organizations with sudo mode" do
setup :register_and_log_in_user_with_sudo
test "shows user organizations", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/users/settings?tab=organizations")
assert html =~ "Organizations"
end
end
describe "UserSettingsLive activity with sudo mode" do
setup :register_and_log_in_user_with_sudo
test "shows login history", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/users/settings?tab=activity")
assert html =~ "Login History"
assert html =~ "Security Alerts"
end
test "paginates login history", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/users/settings?tab=activity&page=1")
assert html =~ "Login History"
end
end
# Helper to register user and grant sudo mode
# Note: user_fixture() already creates users with TOTP enabled by default
defp register_and_log_in_user_with_sudo(%{conn: conn}) do
user = user_fixture()
# Log in and grant sudo mode
conn =
conn
|> log_in_user(user)
|> init_test_session(%{})
|> put_session(:user_sudo_granted_at, System.system_time(:second))
%{conn: conn, user: user}
end
end