feat(overview): add period-scoped payment filter and field-picker descriptor
This commit is contained in:
parent
95ef3177ac
commit
7d1a71b1fd
12 changed files with 654 additions and 0 deletions
82
test/mv_web/member_live/index_field_picker_test.exs
Normal file
82
test/mv_web/member_live/index_field_picker_test.exs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue