diff --git a/test/mv_web/member_live/show_test.exs b/test/mv_web/member_live/show_test.exs new file mode 100644 index 0000000..6ee9b50 --- /dev/null +++ b/test/mv_web/member_live/show_test.exs @@ -0,0 +1,174 @@ +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 + + 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