defmodule MvWeb.UserLive.ShowTest do @moduledoc """ Tests for the user show page. Tests cover: - Displaying user information - Authentication status display - Linked member display - Navigation - Error handling """ use MvWeb.ConnCase, async: true import Phoenix.LiveViewTest require Ash.Query use Gettext, backend: MvWeb.Gettext alias Mv.Membership.Member setup do # Create test user user = create_test_user(%{email: "test@example.com", oidc_id: "test123"}) %{user: user} end describe "mount and display" do @tag :ui test "mounts successfully and displays user information", %{conn: conn, user: user} do conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/users/#{user.id}") # Basic display assert html =~ to_string(user.email) assert html =~ gettext("Email") end test "displays password authentication status when enabled", %{conn: conn} do user = create_test_user(%{email: "password-user@example.com", password: "test123"}) conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/users/#{user.id}") assert html =~ gettext("Password Authentication") assert html =~ gettext("Enabled") end test "displays password authentication status when not enabled", %{conn: conn} do # User without password (only OIDC) - create user with OIDC only user = create_test_user(%{ email: "oidc-only#{System.unique_integer([:positive])}@example.com", oidc_id: "oidc#{System.unique_integer([:positive])}", hashed_password: nil }) conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/users/#{user.id}") assert html =~ gettext("Password Authentication") assert html =~ gettext("Not enabled") end @tag :slow test "displays linked member when present", %{conn: conn} do system_actor = Mv.Helpers.SystemActor.get_system_actor() # Create member {:ok, member} = Mv.Membership.create_member( %{first_name: "Alice", last_name: "Smith", email: "alice@example.com"}, actor: system_actor ) # Create user and link to member user = create_test_user(%{email: "user@example.com"}) {:ok, _updated_user} = user |> Ash.Changeset.for_update(:update, %{}) |> Ash.Changeset.manage_relationship(:member, member, type: :append_and_remove) |> Ash.update(actor: system_actor) conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/users/#{user.id}") assert html =~ gettext("Linked Member") assert html =~ "Alice Smith" assert html =~ ~r/href="[^"]*\/members\/#{member.id}"/ end test "displays 'No member linked' when no member is linked", %{conn: conn, user: user} do conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/users/#{user.id}") assert html =~ gettext("Linked Member") assert html =~ gettext("No member linked") end end describe "navigation" do @tag :ui test "navigation buttons work correctly", %{conn: conn, user: user} do conn = conn_with_oidc_user(conn) {:ok, view, _html} = live(conn, ~p"/users/#{user.id}") # Back button navigates to user list assert {:error, {:live_redirect, %{to: to}}} = view |> element( "a[aria-label='#{gettext("Back to users list")}'], button[aria-label='#{gettext("Back to users list")}']" ) |> render_click() assert to == "/users" # Edit button navigates to edit form {:ok, view, _html} = live(conn, ~p"/users/#{user.id}") assert {:error, {:live_redirect, %{to: to}}} = view |> element( "a[href='/users/#{user.id}/edit?return_to=show'], button[href='/users/#{user.id}/edit?return_to=show']" ) |> render_click() assert to == "/users/#{user.id}/edit?return_to=show" end end describe "page title" do @tag :ui test "sets correct page title", %{conn: conn, user: user} do conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/users/#{user.id}") # Check that page title is set (might be in title tag or header) assert html =~ gettext("Show User") || html =~ to_string(user.email) end end describe "error handling" do test "raises exception for invalid user ID", %{conn: conn} do invalid_id = Ecto.UUID.generate() conn = conn_with_oidc_user(conn) # The mount function uses Ash.get! which will raise an exception # This is expected behavior - the LiveView doesn't handle this case assert_raise Ash.Error.Invalid, fn -> live(conn, ~p"/users/#{invalid_id}") end end end describe "system actor user" do @tag :slow test "redirects to user list when viewing system actor user", %{conn: conn} do system_actor = Mv.Helpers.SystemActor.get_system_actor() conn = conn_with_oidc_user(conn) assert {:error, {:live_redirect, %{to: "/users"}}} = live(conn, ~p"/users/#{system_actor.id}") end end end