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
|
|
@ -5,6 +5,7 @@ defmodule MvWeb.MemberLive.IndexPaymentPeriodTest do
|
|||
backs the badge tooltip (unpaid cycles for the period; suspended shown apart).
|
||||
"""
|
||||
use Mv.DataCase, async: false
|
||||
use ExUnitProperties
|
||||
|
||||
import Mv.Fixtures, only: [create_fee_type: 2, member_fixture_with_actor: 2, create_cycle: 4]
|
||||
|
||||
|
|
@ -39,6 +40,58 @@ defmodule MvWeb.MemberLive.IndexPaymentPeriodTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "payment-count filter codec" do
|
||||
test "round-trips fully_paid and has-unpaid thresholds" do
|
||||
for state <- [:fully_paid, {:has_unpaid, 1}, {:has_unpaid, 2}, {:has_unpaid, 3}] do
|
||||
params = PaymentAging.filter_to_params(state)
|
||||
assert PaymentAging.parse_filter_params(params) == state
|
||||
end
|
||||
end
|
||||
|
||||
test "nil filter serializes to no params and unknown values parse to nil" do
|
||||
assert PaymentAging.filter_to_params(nil) == %{}
|
||||
assert PaymentAging.parse_filter_params(%{}) == nil
|
||||
assert PaymentAging.parse_filter_params(%{"pay_filter" => "bogus"}) == nil
|
||||
end
|
||||
|
||||
test "serializes to stable string tokens" do
|
||||
assert PaymentAging.filter_to_params(:fully_paid) == %{"pay_filter" => "fully_paid"}
|
||||
assert PaymentAging.filter_to_params({:has_unpaid, 2}) == %{"pay_filter" => "unpaid_2"}
|
||||
end
|
||||
end
|
||||
|
||||
describe "payment URL round-trip (§2.1, payment keys)" do
|
||||
@dates [nil, ~D[2020-01-01], ~D[2024-06-30], ~D[2025-12-31]]
|
||||
@filters [nil, :fully_paid, {:has_unpaid, 1}, {:has_unpaid, 2}, {:has_unpaid, 3}]
|
||||
|
||||
property "decode∘encode is canonical and idempotent for period + payment filter" do
|
||||
check all(
|
||||
from <- StreamData.member_of(@dates),
|
||||
to <- StreamData.member_of(@dates),
|
||||
filter <- StreamData.member_of(@filters)
|
||||
) do
|
||||
period = %{from: from, to: to}
|
||||
|
||||
params =
|
||||
period
|
||||
|> PaymentAging.to_params()
|
||||
|> Map.merge(PaymentAging.filter_to_params(filter))
|
||||
|
||||
assert PaymentAging.parse_period(params) == period
|
||||
assert PaymentAging.parse_filter_params(params) == filter
|
||||
|
||||
# Idempotence: re-encoding the decoded state yields the same params.
|
||||
reencoded =
|
||||
params
|
||||
|> PaymentAging.parse_period()
|
||||
|> PaymentAging.to_params()
|
||||
|> Map.merge(PaymentAging.filter_to_params(PaymentAging.parse_filter_params(params)))
|
||||
|
||||
assert reencoded == params
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "badge/1" do
|
||||
test "0 renders as Paid (success)" do
|
||||
badge = PaymentAging.badge(0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue