mitgliederverwaltung/test/membership/member_field_visibility_test.exs

151 lines
5.2 KiB
Elixir

defmodule Mv.Membership.MemberFieldVisibilityTest do
@moduledoc """
Tests for member field visibility configuration.
Tests cover:
- Member fields are visible by default (show_in_overview: true)
- Member fields can be hidden (show_in_overview: false)
- Checking if a specific field is visible
- Configuration is stored in Settings resource
"""
use Mv.DataCase, async: true
alias Mv.Membership.Member
describe "show_in_overview?/1" do
test "returns true for all member fields by default, except exit_date" do
# When no settings exist or member_field_visibility is not configured
# Test with fields from constants
# Note: exit_date defaults to false (hidden) by design
member_fields = Mv.Constants.member_fields()
Enum.each(member_fields, fn field ->
expected_visibility = if field == :exit_date, do: false, else: true
assert Member.show_in_overview?(field) == expected_visibility,
"Field #{field} should be #{if expected_visibility, do: "visible", else: "hidden"} by default"
end)
end
test "returns false for fields with show_in_overview: false in settings" do
# Get or create settings
{:ok, settings} = Mv.Membership.get_settings()
# Use a field that exists in member fields
member_fields = Mv.Constants.member_fields()
field_to_hide = List.first(member_fields)
field_to_show = List.last(member_fields)
# Update settings to hide a field (use string keys for JSONB)
{:ok, _updated_settings} =
Mv.Membership.update_settings(settings, %{
member_field_visibility: %{Atom.to_string(field_to_hide) => false}
})
# JSONB may convert atom keys to string keys, so we check via show_in_overview? instead
assert Member.show_in_overview?(field_to_hide) == false
assert Member.show_in_overview?(field_to_show) == true
end
test "returns true for non-configured fields (default)" do
# Get or create settings
{:ok, settings} = Mv.Membership.get_settings()
# Use fields that exist in member fields
member_fields = Mv.Constants.member_fields()
fields_to_hide = Enum.take(member_fields, 2)
fields_to_show = Enum.take(member_fields, -2)
# Update settings to hide some fields (use string keys for JSONB)
visibility_config =
Enum.reduce(fields_to_hide, %{}, fn field, acc ->
Map.put(acc, Atom.to_string(field), false)
end)
{:ok, _updated_settings} =
Mv.Membership.update_settings(settings, %{
member_field_visibility: visibility_config
})
# Hidden fields should be false
Enum.each(fields_to_hide, fn field ->
assert Member.show_in_overview?(field) == false,
"Field #{field} should be hidden"
end)
# Unconfigured fields should still be true (default)
Enum.each(fields_to_show, fn field ->
assert Member.show_in_overview?(field) == true,
"Field #{field} should be visible by default"
end)
end
end
describe "update_single_member_field_visibility/3" do
test "atomically updates a single field in member_field_visibility" do
{:ok, settings} = Mv.Membership.get_settings()
field_string = "street"
# Update single field
{:ok, updated_settings} =
Mv.Membership.update_single_member_field_visibility(
settings,
field: field_string,
show_in_overview: false
)
# Verify the field was updated
assert updated_settings.member_field_visibility[field_string] == false
# Verify other fields are not affected
other_fields =
Mv.Constants.member_fields()
|> Enum.reject(&(&1 == String.to_existing_atom(field_string)))
Enum.each(other_fields, fn field ->
field_string = Atom.to_string(field)
# Fields not explicitly set should default to true (except exit_date)
expected = if field == :exit_date, do: false, else: true
assert Map.get(updated_settings.member_field_visibility, field_string, expected) ==
expected
end)
end
test "returns error for invalid field name" do
{:ok, settings} = Mv.Membership.get_settings()
assert {:error, %Ash.Error.Invalid{errors: [%{field: :member_field_visibility}]}} =
Mv.Membership.update_single_member_field_visibility(
settings,
field: "invalid_field",
show_in_overview: false
)
end
test "handles concurrent updates atomically" do
{:ok, settings} = Mv.Membership.get_settings()
field1 = "street"
field2 = "house_number"
# Simulate concurrent updates by updating different fields
{:ok, updated1} =
Mv.Membership.update_single_member_field_visibility(
settings,
field: field1,
show_in_overview: false
)
{:ok, updated2} =
Mv.Membership.update_single_member_field_visibility(
updated1,
field: field2,
show_in_overview: true
)
# Both fields should be correctly updated
assert updated2.member_field_visibility[field1] == false
assert updated2.member_field_visibility[field2] == true
end
end
end