207 lines
6.7 KiB
Elixir
207 lines
6.7 KiB
Elixir
defmodule Mv.MembershipFees.MembershipFeeCycleTest do
|
|
@moduledoc """
|
|
Tests for MembershipFeeCycle resource, focusing on status management actions.
|
|
"""
|
|
use Mv.DataCase, async: true
|
|
|
|
alias Mv.MembershipFees.MembershipFeeCycle
|
|
alias Mv.MembershipFees.MembershipFeeType
|
|
alias Mv.Membership.Member
|
|
|
|
# Helper to create a membership fee type
|
|
defp create_fee_type(attrs) do
|
|
default_attrs = %{
|
|
name: "Test Fee Type #{System.unique_integer([:positive])}",
|
|
amount: Decimal.new("50.00"),
|
|
interval: :yearly
|
|
}
|
|
|
|
attrs = Map.merge(default_attrs, attrs)
|
|
|
|
MembershipFeeType
|
|
|> Ash.Changeset.for_create(:create, attrs)
|
|
|> Ash.create!()
|
|
end
|
|
|
|
# Helper to create a member
|
|
defp create_member(attrs) do
|
|
default_attrs = %{
|
|
first_name: "Test",
|
|
last_name: "Member",
|
|
email: "test.member.#{System.unique_integer([:positive])}@example.com"
|
|
}
|
|
|
|
attrs = Map.merge(default_attrs, attrs)
|
|
|
|
Member
|
|
|> Ash.Changeset.for_create(:create_member, attrs)
|
|
|> Ash.create!()
|
|
end
|
|
|
|
# Helper to create a cycle
|
|
defp create_cycle(member, fee_type, attrs) do
|
|
default_attrs = %{
|
|
cycle_start: ~D[2024-01-01],
|
|
amount: Decimal.new("50.00"),
|
|
member_id: member.id,
|
|
membership_fee_type_id: fee_type.id
|
|
}
|
|
|
|
attrs = Map.merge(default_attrs, attrs)
|
|
|
|
MembershipFeeCycle
|
|
|> Ash.Changeset.for_create(:create, attrs)
|
|
|> Ash.create!()
|
|
end
|
|
|
|
describe "status defaults" do
|
|
test "status defaults to :unpaid when creating a cycle" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
|
|
cycle =
|
|
MembershipFeeCycle
|
|
|> Ash.Changeset.for_create(:create, %{
|
|
cycle_start: ~D[2024-01-01],
|
|
amount: Decimal.new("50.00"),
|
|
member_id: member.id,
|
|
membership_fee_type_id: fee_type.id
|
|
})
|
|
|> Ash.create!()
|
|
|
|
assert cycle.status == :unpaid
|
|
end
|
|
end
|
|
|
|
describe "mark_as_paid" do
|
|
test "sets status to :paid" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
cycle = create_cycle(member, fee_type, %{status: :unpaid})
|
|
|
|
assert {:ok, updated} = Ash.update(cycle, %{}, action: :mark_as_paid)
|
|
assert updated.status == :paid
|
|
end
|
|
|
|
test "can set notes when marking as paid" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
cycle = create_cycle(member, fee_type, %{status: :unpaid})
|
|
|
|
assert {:ok, updated} =
|
|
Ash.update(cycle, %{notes: "Payment received via bank transfer"},
|
|
action: :mark_as_paid
|
|
)
|
|
|
|
assert updated.status == :paid
|
|
assert updated.notes == "Payment received via bank transfer"
|
|
end
|
|
|
|
test "can change from suspended to paid" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
cycle = create_cycle(member, fee_type, %{status: :suspended})
|
|
|
|
assert {:ok, updated} = Ash.update(cycle, %{}, action: :mark_as_paid)
|
|
assert updated.status == :paid
|
|
end
|
|
end
|
|
|
|
describe "mark_as_suspended" do
|
|
test "sets status to :suspended" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
cycle = create_cycle(member, fee_type, %{status: :unpaid})
|
|
|
|
assert {:ok, updated} = Ash.update(cycle, %{}, action: :mark_as_suspended)
|
|
assert updated.status == :suspended
|
|
end
|
|
|
|
test "can set notes when marking as suspended" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
cycle = create_cycle(member, fee_type, %{status: :unpaid})
|
|
|
|
assert {:ok, updated} =
|
|
Ash.update(cycle, %{notes: "Waived due to special circumstances"},
|
|
action: :mark_as_suspended
|
|
)
|
|
|
|
assert updated.status == :suspended
|
|
assert updated.notes == "Waived due to special circumstances"
|
|
end
|
|
|
|
test "can change from paid to suspended" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
cycle = create_cycle(member, fee_type, %{status: :paid})
|
|
|
|
assert {:ok, updated} = Ash.update(cycle, %{}, action: :mark_as_suspended)
|
|
assert updated.status == :suspended
|
|
end
|
|
end
|
|
|
|
describe "mark_as_unpaid" do
|
|
test "sets status to :unpaid" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
cycle = create_cycle(member, fee_type, %{status: :paid})
|
|
|
|
assert {:ok, updated} = Ash.update(cycle, %{}, action: :mark_as_unpaid)
|
|
assert updated.status == :unpaid
|
|
end
|
|
|
|
test "can set notes when marking as unpaid" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
cycle = create_cycle(member, fee_type, %{status: :paid})
|
|
|
|
assert {:ok, updated} =
|
|
Ash.update(cycle, %{notes: "Payment was reversed"}, action: :mark_as_unpaid)
|
|
|
|
assert updated.status == :unpaid
|
|
assert updated.notes == "Payment was reversed"
|
|
end
|
|
|
|
test "can change from suspended to unpaid" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
cycle = create_cycle(member, fee_type, %{status: :suspended})
|
|
|
|
assert {:ok, updated} = Ash.update(cycle, %{}, action: :mark_as_unpaid)
|
|
assert updated.status == :unpaid
|
|
end
|
|
end
|
|
|
|
describe "status transitions" do
|
|
test "all status transitions are allowed" do
|
|
fee_type = create_fee_type(%{interval: :yearly})
|
|
member = create_member(%{membership_fee_type_id: fee_type.id})
|
|
|
|
# unpaid -> paid
|
|
cycle1 = create_cycle(member, fee_type, %{status: :unpaid})
|
|
assert {:ok, c1} = Ash.update(cycle1, %{}, action: :mark_as_paid)
|
|
assert c1.status == :paid
|
|
|
|
# paid -> suspended
|
|
assert {:ok, c2} = Ash.update(c1, %{}, action: :mark_as_suspended)
|
|
assert c2.status == :suspended
|
|
|
|
# suspended -> unpaid
|
|
assert {:ok, c3} = Ash.update(c2, %{}, action: :mark_as_unpaid)
|
|
assert c3.status == :unpaid
|
|
|
|
# unpaid -> suspended
|
|
assert {:ok, c4} = Ash.update(c3, %{}, action: :mark_as_suspended)
|
|
assert c4.status == :suspended
|
|
|
|
# suspended -> paid
|
|
assert {:ok, c5} = Ash.update(c4, %{}, action: :mark_as_paid)
|
|
assert c5.status == :paid
|
|
|
|
# paid -> unpaid
|
|
assert {:ok, c6} = Ash.update(c5, %{}, action: :mark_as_unpaid)
|
|
assert c6.status == :unpaid
|
|
end
|
|
end
|
|
end
|