From 2dd5ef99263ffb5e1c648ff6c19b1c7f2b2c634b Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 21 Jan 2026 01:14:26 +0100 Subject: [PATCH] test: add more filter component tests --- .../member_filter_component_test.exs | 33 ++++++++ test/mv_web/member_live/index_test.exs | 81 +++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/test/mv_web/components/member_filter_component_test.exs b/test/mv_web/components/member_filter_component_test.exs index e2f2e64..a3a3846 100644 --- a/test/mv_web/components/member_filter_component_test.exs +++ b/test/mv_web/components/member_filter_component_test.exs @@ -263,5 +263,38 @@ defmodule MvWeb.Components.MemberFilterComponentTest do # (String fields should not appear in boolean filter section) refute dropdown_html =~ "String Field" end + + test "dropdown shows scrollbar when many boolean custom fields exist", %{conn: conn} do + conn = conn_with_oidc_user(conn) + + # Create 15 boolean custom fields (more than typical, should trigger scrollbar) + boolean_fields = + Enum.map(1..15, fn i -> + create_boolean_custom_field(%{name: "Field #{i}"}) + end) + + {:ok, view, _html} = live(conn, "/members") + + # Open dropdown + view + |> element("#member-filter button[aria-haspopup='true']") + |> render_click() + + # Extract dropdown panel HTML + dropdown_html = + view + |> element("#member-filter div[role='dialog']") + |> render() + + # Should have scrollbar classes: max-h-60 overflow-y-auto pr-2 + # Check for the scrollable container (the div with max-h-60 and overflow-y-auto) + assert dropdown_html =~ "max-h-60" + assert dropdown_html =~ "overflow-y-auto" + + # Verify all fields are present in the dropdown + Enum.each(boolean_fields, fn field -> + assert dropdown_html =~ field.name + end) + end end end diff --git a/test/mv_web/member_live/index_test.exs b/test/mv_web/member_live/index_test.exs index 97dbd39..1663fc0 100644 --- a/test/mv_web/member_live/index_test.exs +++ b/test/mv_web/member_live/index_test.exs @@ -1525,5 +1525,86 @@ defmodule MvWeb.MemberLive.IndexTest do assert html =~ "TrueMember" refute html =~ "FalseMember" end + + test "boolean custom field appears in filter dropdown after being added", %{conn: conn} do + conn = conn_with_oidc_user(conn) + + # Start with no boolean custom fields + {:ok, view, _html} = live(conn, "/members") + + state_before = :sys.get_state(view.pid) + boolean_fields_before = state_before.socket.assigns.boolean_custom_fields + assert length(boolean_fields_before) == 0 + + # Create a new boolean custom field + new_boolean_field = create_boolean_custom_field(%{name: "Newly Added Field"}) + + # Navigate again - the new field should appear + {:ok, view2, _html} = live(conn, "/members") + + state_after = :sys.get_state(view2.pid) + boolean_fields_after = state_after.socket.assigns.boolean_custom_fields + + # New boolean field should be present + assert length(boolean_fields_after) == 1 + assert Enum.any?(boolean_fields_after, &(&1.id == new_boolean_field.id)) + assert Enum.any?(boolean_fields_after, &(&1.name == "Newly Added Field")) + end + + test "boolean filter performance with 150 members", %{conn: conn} do + conn = conn_with_oidc_user(conn) + boolean_field = create_boolean_custom_field() + + # Create 150 members - 75 with true, 75 with false + members_with_true = + Enum.map(1..75, fn i -> + create_member_with_boolean_value( + %{ + first_name: "TrueMember#{i}", + email: "truemember#{i}@example.com" + }, + boolean_field, + true + ) + end) + + members_with_false = + Enum.map(1..75, fn i -> + create_member_with_boolean_value( + %{ + first_name: "FalseMember#{i}", + email: "falsemember#{i}@example.com" + }, + boolean_field, + false + ) + end) + + # Verify all members were created + assert length(members_with_true) == 75 + assert length(members_with_false) == 75 + + # Test filter performance - should complete in reasonable time (< 1 second) + start_time = System.monotonic_time(:millisecond) + + {:ok, _view, html} = + live(conn, "/members?bf_#{boolean_field.id}=true") + + end_time = System.monotonic_time(:millisecond) + duration = end_time - start_time + + # Should complete in less than 1 second (1000ms) + assert duration < 1000, "Filter took #{duration}ms, expected < 1000ms" + + # Verify filtering worked correctly - should show all true members + Enum.each(1..75, fn i -> + assert html =~ "TrueMember#{i}" + end) + + # Should not show false members + Enum.each(1..75, fn i -> + refute html =~ "FalseMember#{i}" + end) + end end end