defmodule MvWeb.MemberLive.ShowTest do @moduledoc """ Tests for the member show page. Tests cover: - Displaying member information - Custom Fields section visibility (Issue #282 regression test) - Custom field values formatting ## Note on async: false Tests use `async: false` (not `async: true`) to prevent PostgreSQL deadlocks when creating members and custom fields concurrently. This is intentional and documented here to avoid confusion in commit messages. """ # async: false to prevent PostgreSQL deadlocks when creating members and custom fields use MvWeb.ConnCase, async: false import Phoenix.LiveViewTest require Ash.Query use Gettext, backend: MvWeb.Gettext alias Mv.Membership.{CustomField, CustomFieldValue, Member} setup do # Create test member {:ok, member} = Member |> Ash.Changeset.for_create(:create_member, %{ first_name: "Alice", last_name: "Anderson", email: "alice@example.com" }) |> Ash.create() %{member: member} end describe "custom fields section visibility (Issue #282)" do test "displays Custom Fields section even when member has no custom field values", %{ conn: conn, member: member } do # Create a custom field but no value for the member {:ok, custom_field} = CustomField |> Ash.Changeset.for_create(:create, %{ name: "phone_mobile", value_type: :string }) |> Ash.create() conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/members/#{member}") # Custom Fields section should be visible assert html =~ gettext("Custom Fields") # Custom field label should be visible assert html =~ custom_field.name # Value should show placeholder for empty value assert html =~ "—" or html =~ gettext("Not set") end test "displays Custom Fields section with multiple custom fields, some without values", %{ conn: conn, member: member } do # Create multiple custom fields {:ok, field1} = CustomField |> Ash.Changeset.for_create(:create, %{ name: "phone_mobile", value_type: :string }) |> Ash.create() {:ok, field2} = CustomField |> Ash.Changeset.for_create(:create, %{ name: "membership_number", value_type: :integer }) |> Ash.create() # Create value only for first field {:ok, _cfv} = CustomFieldValue |> Ash.Changeset.for_create(:create, %{ member_id: member.id, custom_field_id: field1.id, value: %{"_union_type" => "string", "_union_value" => "+49123456789"} }) |> Ash.create() conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/members/#{member}") # Custom Fields section should be visible assert html =~ gettext("Custom Fields") # Both field labels should be visible assert html =~ field1.name assert html =~ field2.name # First field should show value assert html =~ "+49123456789" # Second field should show placeholder assert html =~ "—" or html =~ gettext("Not set") end test "does not display Custom Fields section when no custom fields exist", %{ conn: conn, member: member } do conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/members/#{member}") # Custom Fields section should NOT be visible refute html =~ gettext("Custom Fields") end end describe "custom field value formatting" do test "formats string custom field values", %{conn: conn, member: member} do {:ok, custom_field} = CustomField |> Ash.Changeset.for_create(:create, %{ name: "phone_mobile", value_type: :string }) |> Ash.create() {:ok, _cfv} = CustomFieldValue |> Ash.Changeset.for_create(:create, %{ member_id: member.id, custom_field_id: custom_field.id, value: %{"_union_type" => "string", "_union_value" => "+49123456789"} }) |> Ash.create() conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/members/#{member}") assert html =~ "+49123456789" end test "formats email custom field values as mailto links", %{conn: conn, member: member} do {:ok, custom_field} = CustomField |> Ash.Changeset.for_create(:create, %{ name: "private_email", value_type: :email }) |> Ash.create() {:ok, _cfv} = CustomFieldValue |> Ash.Changeset.for_create(:create, %{ member_id: member.id, custom_field_id: custom_field.id, value: %{"_union_type" => "email", "_union_value" => "private@example.com"} }) |> Ash.create() conn = conn_with_oidc_user(conn) {:ok, _view, html} = live(conn, ~p"/members/#{member}") # Should contain mailto link assert html =~ ~s(href="mailto:private@example.com") assert html =~ "private@example.com" end end end