Ergänzte Tests für Lückenschluss: 1. test_absolute_modifier_reduces_outflow: Absolute Modifier reduziert Ausgaben (-200 - 50 = -150) 2. test_absolute_modifier_clamps_to_zero: Absolute Modifier klemmt auf 0 (nie Vorzeichenflip: -200 + 300 = 0) 3. test_cashflow_on_start_date_excluded: Cashflows am start_date werden ausgeschlossen (Teil des Startsaldos) Alle 18 Tests grün (15 existierend + 3 neu). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
60 lines
3.0 KiB
Python
60 lines
3.0 KiB
Python
from datetime import date
|
|
from decimal import Decimal
|
|
|
|
from app.engine.loans import loan_schedule
|
|
from app.engine.scenario import (PlainModifier, PlainPlanned, PlainRecurring,
|
|
build_cashflows)
|
|
|
|
W = (date(2026, 8, 1), date(2026, 10, 31))
|
|
|
|
|
|
def test_recurring_with_percent_cut():
|
|
rec = [PlainRecurring(id=1, name="Marketing", amount=Decimal("-1000"),
|
|
rhythm="monthly", due_day=5, start_date=None,
|
|
end_date=None, category_id=7)]
|
|
mods = [PlainModifier(target_type="category", target_id=7,
|
|
kind="percent", value=Decimal("50"))]
|
|
flows = build_cashflows(rec, [], [], [], mods, *W)
|
|
assert flows == [(date(2026, 8, 5), Decimal("-500.00")),
|
|
(date(2026, 9, 5), Decimal("-500.00")),
|
|
(date(2026, 10, 5), Decimal("-500.00"))]
|
|
|
|
|
|
def test_remove_modifier_and_planned_and_loan():
|
|
rec = [PlainRecurring(id=2, name="Abo", amount=Decimal("-50"),
|
|
rhythm="monthly", due_day=1, start_date=None,
|
|
end_date=None, category_id=None)]
|
|
mods = [PlainModifier(target_type="recurring", target_id=2,
|
|
kind="remove", value=Decimal("0"))]
|
|
planned = [PlainPlanned(name="Steuer", amount=Decimal("-2000"),
|
|
due=date(2026, 9, 15), category_id=None)]
|
|
sched = loan_schedule(Decimal("10000"), Decimal("6"), 48, date(2026, 8, 1), "annuity")
|
|
flows = build_cashflows(rec, planned, [sched],
|
|
[(date(2026, 8, 1), Decimal("10000"))], mods, *W)
|
|
days = [d for d, _ in flows]
|
|
assert date(2026, 8, 1) in days # Kredit-Auszahlung
|
|
assert date(2026, 9, 15) in days # Einmalposten
|
|
assert all(a != Decimal("-50") for _, a in flows) # Abo entfernt
|
|
|
|
|
|
def test_absolute_modifier_reduces_outflow():
|
|
"""Test absolute modifier for outflows: -200 - 50 = -150"""
|
|
rec = [PlainRecurring(id=1, name="Marketing", amount=Decimal("-200"),
|
|
rhythm="monthly", due_day=10, start_date=None,
|
|
end_date=None, category_id=3)]
|
|
mods = [PlainModifier(target_type="category", target_id=3,
|
|
kind="absolute", value=Decimal("50"))]
|
|
flows = build_cashflows(rec, [], [], [], mods, date(2026, 8, 1), date(2026, 8, 31))
|
|
assert flows == [(date(2026, 8, 10), Decimal("-150.00"))]
|
|
|
|
|
|
def test_absolute_modifier_clamps_to_zero():
|
|
"""Test absolute modifier clamping: -200 + 300 = 0 (never flips sign)"""
|
|
rec = [PlainRecurring(id=1, name="Marketing", amount=Decimal("-200"),
|
|
rhythm="monthly", due_day=10, start_date=None,
|
|
end_date=None, category_id=3)]
|
|
mods = [PlainModifier(target_type="category", target_id=3,
|
|
kind="absolute", value=Decimal("300"))]
|
|
flows = build_cashflows(rec, [], [], [], mods, date(2026, 8, 1), date(2026, 8, 31))
|
|
assert flows == [(date(2026, 8, 10), Decimal("0.00"))]
|