refactor
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing

This commit is contained in:
carla 2026-02-04 15:52:00 +01:00
parent e0f0ca369c
commit d34ff57531
6 changed files with 127 additions and 391 deletions

View file

@ -1,6 +1,10 @@
defmodule Mv.MembershipFees.MembershipFeeTypeTest do
@moduledoc """
Tests for MembershipFeeType resource.
Tests for MembershipFeeType business rules only.
We test: required fields, allowed interval values, uniqueness, amount constraints,
interval immutability, and referential integrity (cannot delete when in use).
We do not test: standard CRUD (create/update/delete when no constraints apply).
"""
use Mv.DataCase, async: true
@ -11,34 +15,7 @@ defmodule Mv.MembershipFees.MembershipFeeTypeTest do
%{actor: system_actor}
end
describe "create MembershipFeeType" do
test "can create membership fee type with valid attributes", %{actor: actor} do
attrs = %{
name: "Standard Membership",
amount: Decimal.new("120.00"),
interval: :yearly,
description: "Standard yearly membership fee"
}
assert {:ok, %MembershipFeeType{} = fee_type} =
Ash.create(MembershipFeeType, attrs, actor: actor)
assert fee_type.name == "Standard Membership"
assert Decimal.equal?(fee_type.amount, Decimal.new("120.00"))
assert fee_type.interval == :yearly
assert fee_type.description == "Standard yearly membership fee"
end
test "can create membership fee type without description", %{actor: actor} do
attrs = %{
name: "Basic",
amount: Decimal.new("60.00"),
interval: :monthly
}
assert {:ok, %MembershipFeeType{}} = Ash.create(MembershipFeeType, attrs, actor: actor)
end
describe "create MembershipFeeType - business rules" do
test "requires name", %{actor: actor} do
attrs = %{
amount: Decimal.new("100.00"),
@ -69,28 +46,24 @@ defmodule Mv.MembershipFees.MembershipFeeTypeTest do
assert error_on_field?(error, :interval)
end
test "validates interval enum values - monthly", %{actor: actor} do
attrs = %{name: "Monthly", amount: Decimal.new("10.00"), interval: :monthly}
assert {:ok, fee_type} = Ash.create(MembershipFeeType, attrs, actor: actor)
assert fee_type.interval == :monthly
end
test "accepts valid interval values (monthly, quarterly, half_yearly, yearly)", %{
actor: actor
} do
for {interval, name} <- [
monthly: "Monthly",
quarterly: "Quarterly",
half_yearly: "Half Yearly",
yearly: "Yearly"
] do
attrs = %{
name: "#{name} #{System.unique_integer([:positive])}",
amount: Decimal.new("10.00"),
interval: interval
}
test "validates interval enum values - quarterly", %{actor: actor} do
attrs = %{name: "Quarterly", amount: Decimal.new("30.00"), interval: :quarterly}
assert {:ok, fee_type} = Ash.create(MembershipFeeType, attrs, actor: actor)
assert fee_type.interval == :quarterly
end
test "validates interval enum values - half_yearly", %{actor: actor} do
attrs = %{name: "Half Yearly", amount: Decimal.new("60.00"), interval: :half_yearly}
assert {:ok, fee_type} = Ash.create(MembershipFeeType, attrs, actor: actor)
assert fee_type.interval == :half_yearly
end
test "validates interval enum values - yearly", %{actor: actor} do
attrs = %{name: "Yearly", amount: Decimal.new("120.00"), interval: :yearly}
assert {:ok, fee_type} = Ash.create(MembershipFeeType, attrs, actor: actor)
assert fee_type.interval == :yearly
assert {:ok, fee_type} = Ash.create(MembershipFeeType, attrs, actor: actor)
assert fee_type.interval == interval
end
end
test "rejects invalid interval values", %{actor: actor} do
@ -128,13 +101,13 @@ defmodule Mv.MembershipFees.MembershipFeeTypeTest do
end
end
describe "update MembershipFeeType" do
describe "update MembershipFeeType - business rules" do
setup %{actor: actor} do
{:ok, fee_type} =
Ash.create(
MembershipFeeType,
%{
name: "Original Name",
name: "Original Name #{System.unique_integer([:positive])}",
amount: Decimal.new("100.00"),
interval: :yearly,
description: "Original description"
@ -145,28 +118,6 @@ defmodule Mv.MembershipFees.MembershipFeeTypeTest do
%{fee_type: fee_type}
end
test "can update name", %{actor: actor, fee_type: fee_type} do
assert {:ok, updated} = Ash.update(fee_type, %{name: "Updated Name"}, actor: actor)
assert updated.name == "Updated Name"
end
test "can update amount", %{actor: actor, fee_type: fee_type} do
assert {:ok, updated} = Ash.update(fee_type, %{amount: Decimal.new("150.00")}, actor: actor)
assert Decimal.equal?(updated.amount, Decimal.new("150.00"))
end
test "can update description", %{actor: actor, fee_type: fee_type} do
assert {:ok, updated} =
Ash.update(fee_type, %{description: "Updated description"}, actor: actor)
assert updated.description == "Updated description"
end
test "can clear description", %{actor: actor, fee_type: fee_type} do
assert {:ok, updated} = Ash.update(fee_type, %{description: nil}, actor: actor)
assert updated.description == nil
end
test "interval immutability: update fails when interval is changed", %{
actor: actor,
fee_type: fee_type
@ -179,7 +130,7 @@ defmodule Mv.MembershipFees.MembershipFeeTypeTest do
end
end
describe "delete MembershipFeeType" do
describe "delete MembershipFeeType - business rules (referential integrity)" do
setup %{actor: actor} do
{:ok, fee_type} =
Ash.create(
@ -195,12 +146,6 @@ defmodule Mv.MembershipFees.MembershipFeeTypeTest do
%{fee_type: fee_type}
end
test "can delete when not in use", %{actor: actor, fee_type: fee_type} do
result = Ash.destroy(fee_type, actor: actor)
# Ash.destroy returns :ok or {:ok, _} depending on version
assert result == :ok or match?({:ok, _}, result)
end
test "cannot delete when members are assigned", %{actor: actor, fee_type: fee_type} do
alias Mv.Membership.Member