refactor(overview): use English identifier as_of_date for point-in-time filter
This commit is contained in:
parent
ce877463d6
commit
0acd12360f
11 changed files with 113 additions and 112 deletions
|
|
@ -62,16 +62,16 @@ defmodule MvWeb.MemberLive.IndexActiveFormerTest do
|
|||
assert has_element?(view, "#row-#{ctx.former.id}")
|
||||
end
|
||||
|
||||
describe "Stichtag paragraph (§1.24)" do
|
||||
describe "as-of-date paragraph (§1.24)" do
|
||||
test "the active/former control carries a separate 'active on reference date' input", ctx do
|
||||
{:ok, view, _html} = live(ctx.conn, ~p"/members")
|
||||
|
||||
pick_field(view, "active_former")
|
||||
|
||||
# The Stichtag input sits in its own paragraph, not inside the
|
||||
# The as-of-date input sits in its own paragraph, not inside the
|
||||
# Active/Former button-join.
|
||||
assert has_element?(view, "[data-testid='stichtag-paragraph'] input[name='stichtag']")
|
||||
refute has_element?(view, ".join input[name='stichtag']")
|
||||
assert has_element?(view, "[data-testid='as-of-date-paragraph'] input[name='as_of_date']")
|
||||
refute has_element?(view, ".join input[name='as_of_date']")
|
||||
end
|
||||
|
||||
test "setting a reference date activates the point-in-time membership filter", ctx do
|
||||
|
|
@ -81,22 +81,22 @@ defmodule MvWeb.MemberLive.IndexActiveFormerTest do
|
|||
|
||||
view
|
||||
|> element("[data-testid='value-control-active-former']")
|
||||
|> render_change(%{"quick" => "active", "stichtag" => "2024-06-15"})
|
||||
|> render_change(%{"quick" => "active", "as_of_date" => "2024-06-15"})
|
||||
|
||||
_ = render(view)
|
||||
path = assert_patch(view)
|
||||
assert path =~ "stichtag=2024-06-15"
|
||||
assert path =~ "as_of_date=2024-06-15"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Eigener Zeitraum exit-date range (§1.24)" do
|
||||
describe "custom exit-date range (§1.24)" do
|
||||
test "the exit-date control carries a separate native From/To range paragraph", ctx do
|
||||
{:ok, view, _html} = live(ctx.conn, ~p"/members")
|
||||
|
||||
pick_field(view, "active_former")
|
||||
|
||||
# Third paragraph, same native two-input range control the join-date
|
||||
# builder uses — separate from the Active/Former join and the Stichtag box.
|
||||
# builder uses — separate from the Active/Former join and the as-of-date box.
|
||||
assert has_element?(view, "[data-testid='value-control-exit-range']")
|
||||
|
||||
assert has_element?(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
defmodule MvWeb.MemberLive.IndexStichtagPropertyTest do
|
||||
defmodule MvWeb.MemberLive.IndexAsOfDatePropertyTest do
|
||||
@moduledoc """
|
||||
§2.6 — Point-in-time membership ("member on the reference date X").
|
||||
|
||||
For arbitrary (join_date, exit_date) pairs and reference dates X, the Stichtag
|
||||
For arbitrary (join_date, exit_date) pairs and reference dates X, the as-of-date
|
||||
filter keeps a member iff `join_date <= X and (exit_date is nil or exit_date > X)`.
|
||||
Verified at the `OverviewQuery` layer against an in-memory oracle.
|
||||
"""
|
||||
|
|
@ -42,7 +42,7 @@ defmodule MvWeb.MemberLive.IndexStichtagPropertyTest do
|
|||
end)
|
||||
end
|
||||
|
||||
property "Stichtag filter keeps exactly the members active on X" do
|
||||
property "as-of-date filter keeps exactly the members active on X" do
|
||||
actor = Mv.Helpers.SystemActor.get_system_actor()
|
||||
|
||||
check all(
|
||||
|
|
@ -67,7 +67,7 @@ defmodule MvWeb.MemberLive.IndexStichtagPropertyTest do
|
|||
do: id
|
||||
|
||||
actual =
|
||||
%{stichtag: x}
|
||||
%{as_of_date: x}
|
||||
|> OverviewQuery.build()
|
||||
|> Ash.read!(actor: actor)
|
||||
|> MapSet.new(& &1.id)
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
defmodule MvWeb.MemberLive.IndexFilterUrlRoundtripTest do
|
||||
@moduledoc """
|
||||
§2.1 (extended) — the v2 filter keys survive the LiveView decode→encode round
|
||||
trip. Loading `/members` with a Stichtag date, the suspended flag, and a
|
||||
trip. Loading `/members` with an as-of date, the suspended flag, and a
|
||||
two-sided payment count range, then triggering an unrelated re-patch (a sort
|
||||
click), preserves every one of those keys in the pushed URL.
|
||||
"""
|
||||
|
|
@ -21,15 +21,15 @@ defmodule MvWeb.MemberLive.IndexFilterUrlRoundtripTest do
|
|||
%{conn: conn_with_oidc_user(conn)}
|
||||
end
|
||||
|
||||
test "stichtag, suspended and payment count range persist through a re-patch", %{conn: conn} do
|
||||
url = "/members?stichtag=2026-03-15&suspended=1&pay_filter=has_unpaid&pay_min=2&pay_max=4"
|
||||
test "as-of date, suspended and payment count range persist through a re-patch", %{conn: conn} do
|
||||
url = "/members?as_of_date=2026-03-15&suspended=1&pay_filter=has_unpaid&pay_min=2&pay_max=4"
|
||||
{:ok, view, _html} = live(conn, url)
|
||||
|
||||
# Trigger an unrelated URL re-patch by sorting a stable column.
|
||||
view |> element("[data-testid='payment']") |> render_click()
|
||||
path = assert_patch(view)
|
||||
|
||||
assert path =~ "stichtag=2026-03-15"
|
||||
assert path =~ "as_of_date=2026-03-15"
|
||||
assert path =~ "suspended=1"
|
||||
assert path =~ "pay_filter=has_unpaid"
|
||||
assert path =~ "pay_min=2"
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
defmodule MvWeb.MemberLive.IndexStatusParamsCodecTest do
|
||||
@moduledoc """
|
||||
§2.1 (extended) — URL codec round-trip for the new v2 filter keys: the
|
||||
point-in-time Stichtag date and the suspended-status flag. Encoding a state to
|
||||
point-in-time as-of date and the suspended-status flag. Encoding a state to
|
||||
params then decoding yields the canonical state, and the default (no filter)
|
||||
encodes to the empty map so a fresh URL is canonical.
|
||||
"""
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias MvWeb.MemberLive.Index.AsOfDate
|
||||
alias MvWeb.MemberLive.Index.PaymentAging
|
||||
alias MvWeb.MemberLive.Index.Stichtag
|
||||
|
||||
describe "Stichtag date" do
|
||||
describe "as-of date" do
|
||||
test "a set date round-trips" do
|
||||
date = ~D[2026-03-15]
|
||||
assert date |> Stichtag.to_params() |> Stichtag.parse() == date
|
||||
assert date |> AsOfDate.to_params() |> AsOfDate.parse() == date
|
||||
end
|
||||
|
||||
test "nil encodes to the empty map and decodes to nil" do
|
||||
assert Stichtag.to_params(nil) == %{}
|
||||
assert Stichtag.parse(%{}) == nil
|
||||
assert AsOfDate.to_params(nil) == %{}
|
||||
assert AsOfDate.parse(%{}) == nil
|
||||
end
|
||||
|
||||
test "a malformed date param decodes to nil" do
|
||||
assert Stichtag.parse(%{"stichtag" => "not-a-date"}) == nil
|
||||
assert AsOfDate.parse(%{"as_of_date" => "not-a-date"}) == nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue