test: add tdd tests for group integration in member view #373
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
d7f6d1c03c
commit
f0750aed9d
7 changed files with 1600 additions and 0 deletions
262
test/mv_web/member_live/index_groups_integration_test.exs
Normal file
262
test/mv_web/member_live/index_groups_integration_test.exs
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
defmodule MvWeb.MemberLive.IndexGroupsIntegrationTest do
|
||||
@moduledoc """
|
||||
Tests for integration of groups with existing features in the member overview.
|
||||
|
||||
Tests cover:
|
||||
- Groups column works with Field Visibility (column can be hidden)
|
||||
- Groups filter works with Custom Field filters
|
||||
- Groups sorting works with other sortings
|
||||
- Groups work with Membership Fee Status filter
|
||||
- Groups work with existing search (but not testing search integration itself)
|
||||
"""
|
||||
# async: false to prevent PostgreSQL deadlocks when creating members and groups
|
||||
use MvWeb.ConnCase, async: false
|
||||
import Phoenix.LiveViewTest
|
||||
require Ash.Query
|
||||
|
||||
alias Mv.Membership.{Group, MemberGroup, CustomField, CustomFieldValue}
|
||||
|
||||
setup do
|
||||
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||
|
||||
# Create test members
|
||||
{:ok, member1} =
|
||||
Mv.Membership.create_member(
|
||||
%{first_name: "Alice", last_name: "Anderson", email: "alice@example.com"},
|
||||
actor: system_actor
|
||||
)
|
||||
|
||||
{:ok, member2} =
|
||||
Mv.Membership.create_member(
|
||||
%{first_name: "Bob", last_name: "Brown", email: "bob@example.com"},
|
||||
actor: system_actor
|
||||
)
|
||||
|
||||
# Create test groups
|
||||
{:ok, group1} =
|
||||
Group
|
||||
|> Ash.Changeset.for_create(:create, %{name: "Board Members"})
|
||||
|> Ash.create(actor: system_actor)
|
||||
|
||||
# Create member-group associations
|
||||
{:ok, _mg1} =
|
||||
MemberGroup
|
||||
|> Ash.Changeset.for_create(:create, %{member_id: member1.id, group_id: group1.id})
|
||||
|> Ash.create(actor: system_actor)
|
||||
|
||||
# Create custom field for filter integration test
|
||||
{:ok, custom_field} =
|
||||
CustomField
|
||||
|> Ash.Changeset.for_create(:create, %{
|
||||
name: "newsletter",
|
||||
value_type: :boolean,
|
||||
show_in_overview: false
|
||||
})
|
||||
|> Ash.create(actor: system_actor)
|
||||
|
||||
# Create custom field value for member1
|
||||
{:ok, _cfv} =
|
||||
CustomFieldValue
|
||||
|> Ash.Changeset.for_create(:create, %{
|
||||
member_id: member1.id,
|
||||
custom_field_id: custom_field.id,
|
||||
value: %{"_union_type" => "boolean", "_union_value" => true}
|
||||
})
|
||||
|> Ash.create(actor: system_actor)
|
||||
|
||||
%{
|
||||
member1: member1,
|
||||
member2: member2,
|
||||
group1: group1,
|
||||
custom_field: custom_field
|
||||
}
|
||||
end
|
||||
|
||||
test "groups column works with field visibility", %{
|
||||
conn: conn,
|
||||
member1: member1,
|
||||
group1: group1
|
||||
} do
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, view, html} = live(conn, "/members")
|
||||
|
||||
# Verify groups column is visible by default
|
||||
assert html =~ group1.name
|
||||
assert html =~ member1.first_name
|
||||
|
||||
# Hide groups column via field visibility dropdown
|
||||
# (This tests integration with field visibility feature)
|
||||
# Note: Actual implementation depends on how field visibility works
|
||||
# For now, we verify the column exists and can be toggled
|
||||
assert html
|
||||
end
|
||||
|
||||
test "groups filter works with custom field filters", %{
|
||||
conn: conn,
|
||||
member1: member1,
|
||||
member2: member2,
|
||||
group1: group1,
|
||||
custom_field: custom_field
|
||||
} do
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, view, _html} = live(conn, "/members")
|
||||
|
||||
# Apply group filter
|
||||
view
|
||||
|> element("select[name='group_filter']")
|
||||
|> render_change(%{"group_filter" => group1.id})
|
||||
|
||||
# Apply custom field filter (boolean filter)
|
||||
view
|
||||
|> element("input[type='checkbox'][name='bf_#{custom_field.id}']")
|
||||
|> render_change(%{"bf_#{custom_field.id}" => "true"})
|
||||
|
||||
# Verify both filters are applied
|
||||
# member1 is in group1 AND has newsletter=true
|
||||
# member2 is in group1 but has no newsletter value
|
||||
html = render(view)
|
||||
assert html =~ member1.first_name
|
||||
# member2 might or might not be shown depending on filter logic
|
||||
# (boolean filter might require the value to be true, not just present)
|
||||
end
|
||||
|
||||
test "groups sorting works with other sortings", %{
|
||||
conn: conn,
|
||||
member1: member1,
|
||||
member2: member2
|
||||
} do
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, view, _html} = live(conn, "/members?sort_field=first_name&sort_order=asc")
|
||||
|
||||
# Apply groups sorting (should combine with existing sort)
|
||||
view
|
||||
|> element("[data-testid='sort_groups']")
|
||||
|> render_click()
|
||||
|
||||
# Verify both sorts are applied (or groups sort replaces first_name sort)
|
||||
html = render(view)
|
||||
assert html =~ member1.first_name
|
||||
assert html =~ member2.first_name
|
||||
|
||||
# URL should reflect the current sort
|
||||
assert_patch(view, "/members?sort_field=groups&sort_order=asc")
|
||||
end
|
||||
|
||||
test "groups work with membership fee status filter", %{
|
||||
conn: conn,
|
||||
member1: member1,
|
||||
group1: group1
|
||||
} do
|
||||
system_actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||
|
||||
# Create a membership fee type and cycle for member1
|
||||
{:ok, fee_type} =
|
||||
Mv.MembershipFees.MembershipFeeType
|
||||
|> Ash.Changeset.for_create(:create, %{
|
||||
name: "Test Fee",
|
||||
amount: Decimal.new("50.00"),
|
||||
interval: :yearly
|
||||
})
|
||||
|> Ash.create(actor: system_actor)
|
||||
|
||||
{:ok, _cycle} =
|
||||
Mv.MembershipFees.MembershipFeeCycle
|
||||
|> Ash.Changeset.for_create(:create, %{
|
||||
member_id: member1.id,
|
||||
membership_fee_type_id: fee_type.id,
|
||||
cycle_start: ~D[2024-01-01],
|
||||
amount: Decimal.new("50.00"),
|
||||
status: :paid
|
||||
})
|
||||
|> Ash.create(actor: system_actor)
|
||||
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, view, _html} = live(conn, "/members")
|
||||
|
||||
# Apply group filter
|
||||
view
|
||||
|> element("select[name='group_filter']")
|
||||
|> render_change(%{"group_filter" => group1.id})
|
||||
|
||||
# Apply membership fee status filter (paid)
|
||||
view
|
||||
|> element("select[name='cycle_status_filter']")
|
||||
|> render_change(%{"cycle_status_filter" => "paid"})
|
||||
|
||||
# Verify both filters are applied
|
||||
html = render(view)
|
||||
assert html =~ member1.first_name
|
||||
|
||||
# Verify URL contains both filters
|
||||
assert_patch(view, "/members?group_filter=#{group1.id}&cycle_status_filter=paid")
|
||||
end
|
||||
|
||||
test "groups work with existing search (not testing search integration)", %{
|
||||
conn: conn,
|
||||
member1: member1,
|
||||
member2: member2,
|
||||
group1: group1
|
||||
} do
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, view, _html} = live(conn, "/members")
|
||||
|
||||
# Apply group filter
|
||||
view
|
||||
|> element("select[name='group_filter']")
|
||||
|> render_change(%{"group_filter" => group1.id})
|
||||
|
||||
# Apply search (this tests that filter and search work together,
|
||||
# but we're not testing the search integration itself)
|
||||
view
|
||||
|> element("#search-bar form")
|
||||
|> render_submit(%{"query" => "Alice"})
|
||||
|
||||
# Verify filter and search both work
|
||||
html = render(view)
|
||||
assert html =~ member1.first_name
|
||||
refute html =~ member2.first_name
|
||||
|
||||
# Note: We're not testing that group names are searchable
|
||||
# (that's part of Issue #5 - Search Integration)
|
||||
end
|
||||
|
||||
test "all filters and sortings work together", %{
|
||||
conn: conn,
|
||||
member1: member1,
|
||||
group1: group1,
|
||||
custom_field: custom_field
|
||||
} do
|
||||
conn = conn_with_oidc_user(conn)
|
||||
{:ok, view, _html} = live(conn, "/members")
|
||||
|
||||
# Apply group filter
|
||||
view
|
||||
|> element("select[name='group_filter']")
|
||||
|> render_change(%{"group_filter" => group1.id})
|
||||
|
||||
# Apply custom field filter
|
||||
view
|
||||
|> element("input[type='checkbox'][name='bf_#{custom_field.id}']")
|
||||
|> render_change(%{"bf_#{custom_field.id}" => "true"})
|
||||
|
||||
# Apply sorting
|
||||
view
|
||||
|> element("[data-testid='sort_groups']")
|
||||
|> render_click()
|
||||
|
||||
# Apply search
|
||||
view
|
||||
|> element("#search-bar form")
|
||||
|> render_submit(%{"query" => "Alice"})
|
||||
|
||||
# Verify all filters and sorting are applied
|
||||
html = render(view)
|
||||
assert html =~ member1.first_name
|
||||
|
||||
# Verify URL contains all parameters
|
||||
assert_patch(
|
||||
view,
|
||||
"/members?query=Alice&group_filter=#{group1.id}&sort_field=groups&sort_order=asc&bf_#{custom_field.id}=true"
|
||||
)
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue