test: make CycleGenerator tests more robust
- Replace weak assertions (>= 0, if length > 0) with concrete expectations - Remove unnecessary Process.sleep calls (tests run synchronously) - Add get_member_cycles helper for direct cycle verification - Tests now validate actual generated cycles instead of relying on async behavior
This commit is contained in:
parent
cf8a1fa30d
commit
272a8a8afc
1 changed files with 42 additions and 42 deletions
|
|
@ -50,31 +50,43 @@ defmodule Mv.MembershipFees.CycleGeneratorTest do
|
|||
|> Ash.update!()
|
||||
end
|
||||
|
||||
# Helper to get cycles for a member
|
||||
defp get_member_cycles(member_id) do
|
||||
MembershipFeeCycle
|
||||
|> Ash.Query.filter(member_id == ^member_id)
|
||||
|> Ash.Query.sort(cycle_start: :asc)
|
||||
|> Ash.read!()
|
||||
end
|
||||
|
||||
describe "generate_cycles_for_member/2" do
|
||||
test "generates cycles from start date to today" do
|
||||
setup_settings(true)
|
||||
fee_type = create_fee_type(%{interval: :yearly})
|
||||
|
||||
# Create member WITHOUT fee type first, then assign it
|
||||
# This avoids the auto-generation on create and gives us control
|
||||
member =
|
||||
create_member_without_cycles(%{
|
||||
join_date: ~D[2022-03-15],
|
||||
membership_fee_type_id: fee_type.id
|
||||
membership_fee_start_date: ~D[2022-01-01]
|
||||
})
|
||||
|
||||
# Wait a moment for async task to complete or skip it
|
||||
Process.sleep(100)
|
||||
# Assign fee type, which will trigger auto-generation in test env
|
||||
member =
|
||||
member
|
||||
|> Ash.Changeset.for_update(:update_member, %{membership_fee_type_id: fee_type.id})
|
||||
|> Ash.update!()
|
||||
|
||||
# Generate cycles with specific "today" date
|
||||
today = ~D[2024-06-15]
|
||||
{:ok, cycles} = CycleGenerator.generate_cycles_for_member(member.id, today: today)
|
||||
# Verify cycles were generated
|
||||
all_cycles = get_member_cycles(member.id)
|
||||
cycle_years = Enum.map(all_cycles, & &1.cycle_start.year) |> Enum.sort() |> Enum.uniq()
|
||||
|
||||
# With include_joining_cycle=true and join_date=2022-03-15,
|
||||
# start_date should be 2022-01-01
|
||||
# Should generate cycles for 2022, 2023, 2024
|
||||
_cycle_years = Enum.map(cycles, & &1.cycle_start.year) |> Enum.sort()
|
||||
|
||||
# May already have some cycles from the async trigger, so check we have at least 3
|
||||
assert length(cycles) >= 0
|
||||
# Should have cycles for 2022, 2023, 2024
|
||||
assert 2022 in cycle_years
|
||||
assert 2023 in cycle_years
|
||||
assert 2024 in cycle_years
|
||||
end
|
||||
|
||||
test "generates cycles from last existing cycle" do
|
||||
|
|
@ -127,8 +139,6 @@ defmodule Mv.MembershipFees.CycleGeneratorTest do
|
|||
membership_fee_start_date: ~D[2022-01-01]
|
||||
})
|
||||
|
||||
Process.sleep(100)
|
||||
|
||||
# Generate cycles with specific "today" date far in the future
|
||||
today = ~D[2025-06-15]
|
||||
{:ok, cycles} = CycleGenerator.generate_cycles_for_member(member.id, today: today)
|
||||
|
|
@ -152,8 +162,6 @@ defmodule Mv.MembershipFees.CycleGeneratorTest do
|
|||
membership_fee_start_date: ~D[2023-01-01]
|
||||
})
|
||||
|
||||
Process.sleep(100)
|
||||
|
||||
today = ~D[2024-06-15]
|
||||
|
||||
# First generation
|
||||
|
|
@ -178,13 +186,12 @@ defmodule Mv.MembershipFees.CycleGeneratorTest do
|
|||
membership_fee_start_date: ~D[2024-01-01]
|
||||
})
|
||||
|
||||
Process.sleep(100)
|
||||
|
||||
today = ~D[2024-06-15]
|
||||
{:ok, cycles} = CycleGenerator.generate_cycles_for_member(member.id, today: today)
|
||||
# Verify cycles were generated with correct amount
|
||||
all_cycles = get_member_cycles(member.id)
|
||||
refute Enum.empty?(all_cycles), "Expected cycles to be generated"
|
||||
|
||||
# All cycles should have the correct amount
|
||||
Enum.each(cycles, fn cycle ->
|
||||
Enum.each(all_cycles, fn cycle ->
|
||||
assert Decimal.equal?(cycle.amount, amount)
|
||||
end)
|
||||
end
|
||||
|
|
@ -193,7 +200,8 @@ defmodule Mv.MembershipFees.CycleGeneratorTest do
|
|||
setup_settings(true)
|
||||
fee_type = create_fee_type(%{interval: :quarterly})
|
||||
|
||||
# Create member without membership_fee_start_date
|
||||
# Create member without membership_fee_start_date - it will be auto-calculated
|
||||
# and cycles will be auto-generated
|
||||
member =
|
||||
create_member_without_cycles(%{
|
||||
join_date: ~D[2024-02-15],
|
||||
|
|
@ -201,33 +209,29 @@ defmodule Mv.MembershipFees.CycleGeneratorTest do
|
|||
# No membership_fee_start_date - should be calculated
|
||||
})
|
||||
|
||||
Process.sleep(100)
|
||||
|
||||
today = ~D[2024-06-15]
|
||||
{:ok, cycles} = CycleGenerator.generate_cycles_for_member(member.id, today: today)
|
||||
# Verify cycles were auto-generated
|
||||
all_cycles = get_member_cycles(member.id)
|
||||
|
||||
# With include_joining_cycle=true and join_date=2024-02-15 (quarterly),
|
||||
# start_date should be 2024-01-01
|
||||
# Should have Q1 and Q2 2024 cycles
|
||||
unless Enum.empty?(cycles) do
|
||||
cycle_starts = Enum.map(cycles, & &1.cycle_start) |> Enum.sort(Date)
|
||||
first_cycle_start = List.first(cycle_starts)
|
||||
# start_date should be 2024-01-01 (Q1 start)
|
||||
# Should have Q1, Q2, Q3, Q4 2024 cycles (based on current date)
|
||||
refute Enum.empty?(all_cycles), "Expected cycles to be generated"
|
||||
|
||||
# First cycle should start in Q1 2024
|
||||
assert first_cycle_start.year == 2024
|
||||
assert first_cycle_start.month in [1, 4]
|
||||
end
|
||||
cycle_starts = Enum.map(all_cycles, & &1.cycle_start) |> Enum.sort(Date)
|
||||
first_cycle_start = List.first(cycle_starts)
|
||||
|
||||
# First cycle should start in Q1 2024 (2024-01-01)
|
||||
assert first_cycle_start == ~D[2024-01-01]
|
||||
end
|
||||
|
||||
test "returns error when member has no membership_fee_type" do
|
||||
# Create member without fee type - no auto-generation will occur
|
||||
member =
|
||||
create_member_without_cycles(%{
|
||||
join_date: ~D[2024-03-15]
|
||||
# No membership_fee_type_id
|
||||
})
|
||||
|
||||
Process.sleep(100)
|
||||
|
||||
{:error, reason} = CycleGenerator.generate_cycles_for_member(member.id)
|
||||
assert reason == :no_membership_fee_type
|
||||
end
|
||||
|
|
@ -235,14 +239,14 @@ defmodule Mv.MembershipFees.CycleGeneratorTest do
|
|||
test "returns error when member has no join_date" do
|
||||
fee_type = create_fee_type(%{interval: :yearly})
|
||||
|
||||
# Create member without join_date - no auto-generation will occur
|
||||
# (after_action hook checks for join_date)
|
||||
member =
|
||||
create_member_without_cycles(%{
|
||||
membership_fee_type_id: fee_type.id
|
||||
# No join_date
|
||||
})
|
||||
|
||||
Process.sleep(100)
|
||||
|
||||
{:error, reason} = CycleGenerator.generate_cycles_for_member(member.id)
|
||||
assert reason == :no_join_date
|
||||
end
|
||||
|
|
@ -312,8 +316,6 @@ defmodule Mv.MembershipFees.CycleGeneratorTest do
|
|||
membership_fee_start_date: ~D[2024-01-01]
|
||||
})
|
||||
|
||||
Process.sleep(200)
|
||||
|
||||
today = ~D[2024-06-15]
|
||||
{:ok, results} = CycleGenerator.generate_cycles_for_all_members(today: today)
|
||||
|
||||
|
|
@ -336,8 +338,6 @@ defmodule Mv.MembershipFees.CycleGeneratorTest do
|
|||
membership_fee_start_date: ~D[2022-01-01]
|
||||
})
|
||||
|
||||
Process.sleep(100)
|
||||
|
||||
today = ~D[2024-06-15]
|
||||
|
||||
# Run two concurrent generations
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue