82 lines
3 KiB
Elixir
82 lines
3 KiB
Elixir
defmodule MvWeb.MemberLive.IndexFieldPickerTest do
|
|
@moduledoc """
|
|
§1.10 / §3.5 — the FilterDescriptor catalog behind the field picker.
|
|
|
|
Fields are grouped Quick / Membership / Custom fields; a group with no
|
|
available fields is omitted (renders no header). The catalog is derived
|
|
purely from the field context and is serializable (the persistence basis for
|
|
saved views, #549).
|
|
"""
|
|
use ExUnit.Case, async: true
|
|
|
|
alias MvWeb.MemberLive.Index.FilterDescriptor
|
|
|
|
defp group_keys(descriptors, group) do
|
|
descriptors
|
|
|> Enum.filter(&(&1.group == group))
|
|
|> Enum.map(& &1.key)
|
|
end
|
|
|
|
test "groups are ordered Quick / Membership / Custom fields" do
|
|
context = %{
|
|
groups: [%{id: Ecto.UUID.generate(), name: "Board"}],
|
|
fee_types: [%{id: Ecto.UUID.generate(), name: "Standard"}],
|
|
custom_fields: [%{id: Ecto.UUID.generate(), name: "Newsletter", value_type: :boolean}]
|
|
}
|
|
|
|
descriptors = FilterDescriptor.all(context)
|
|
|
|
assert Enum.map(FilterDescriptor.visible_groups(descriptors), &elem(&1, 0)) ==
|
|
[:quick, :membership, :custom_fields]
|
|
end
|
|
|
|
test "quick and membership fields are present with type-aware controls" do
|
|
descriptors = FilterDescriptor.all(%{groups: [%{id: Ecto.UUID.generate(), name: "G"}]})
|
|
|
|
assert group_keys(descriptors, :quick) == [:payment, :active_former]
|
|
assert :group in group_keys(descriptors, :membership)
|
|
assert :join_date in group_keys(descriptors, :membership)
|
|
assert :exit_date in group_keys(descriptors, :membership)
|
|
|
|
payment = Enum.find(descriptors, &(&1.key == :payment))
|
|
assert payment.control == :payment_count
|
|
end
|
|
|
|
test "empty custom-fields group is omitted (no header)" do
|
|
descriptors = FilterDescriptor.all(%{custom_fields: []})
|
|
|
|
groups = Enum.map(FilterDescriptor.visible_groups(descriptors), &elem(&1, 0))
|
|
refute :custom_fields in groups
|
|
end
|
|
|
|
test "membership omits Group/Fee type when the club has none" do
|
|
descriptors = FilterDescriptor.all(%{groups: [], fee_types: []})
|
|
|
|
membership_keys = group_keys(descriptors, :membership)
|
|
refute :group in membership_keys
|
|
refute :fee_type in membership_keys
|
|
# Join/exit date are always available.
|
|
assert :join_date in membership_keys
|
|
assert :exit_date in membership_keys
|
|
end
|
|
|
|
test "one custom-fields descriptor per filterable field; non-filterable types dropped" do
|
|
date_id = Ecto.UUID.generate()
|
|
bool_id = Ecto.UUID.generate()
|
|
|
|
context = %{
|
|
custom_fields: [
|
|
%{id: date_id, name: "Birthday", value_type: :date},
|
|
%{id: bool_id, name: "Consent", value_type: :boolean},
|
|
%{id: Ecto.UUID.generate(), name: "Phone", value_type: :string}
|
|
]
|
|
}
|
|
|
|
custom = Enum.filter(FilterDescriptor.all(context), &(&1.group == :custom_fields))
|
|
|
|
assert Enum.map(custom, & &1.key) == [to_string(date_id), to_string(bool_id)]
|
|
# Keys are plain strings — serializable for #549.
|
|
assert Enum.all?(custom, &is_binary(&1.key))
|
|
assert Enum.find(custom, &(&1.key == to_string(date_id))).control == :date_range
|
|
end
|
|
end
|