mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-07-17 17:08:47 +02:00
by-category and daily-spending accept start_date/end_date (range wins over cycle); Analytics gets a two-month calendar range picker beside the cycle selector. Fixes a latent float/Decimal TypeError that 500'd spending_by_category whenever it had data — the category donut had never rendered. Regression + range tests added. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
"""Analytics endpoints: category aggregation (Decimal regression) and the
|
|
arbitrary date-range filters added for the Analytics range picker."""
|
|
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
|
|
from app.api.v1.endpoints.analytics import daily_spending, spending_by_category
|
|
from app.models.models import Category, Transaction
|
|
|
|
from tests.test_installments import make_cc_tx
|
|
|
|
|
|
def seed(session):
|
|
cat = Category(name="Groceries")
|
|
session.add(cat)
|
|
session.commit()
|
|
make_cc_tx(session, merchant="A", amount="1000.50", reference="a1",
|
|
date=datetime(2026, 6, 2), category_id=cat.id)
|
|
make_cc_tx(session, merchant="B", amount="2000.00", reference="b1",
|
|
date=datetime(2026, 6, 20))
|
|
return cat
|
|
|
|
|
|
class TestSpendingByCategory:
|
|
def test_decimal_sum_does_not_crash_and_percentages_add_up(self, session):
|
|
"""Regression: Decimal grand total vs float row total raised
|
|
TypeError, 500ing the endpoint whenever it had data."""
|
|
seed(session)
|
|
rows = spending_by_category(session=session, _user="t")
|
|
assert {r.category_name for r in rows} == {"Groceries", "Uncategorized"}
|
|
assert sum(r.percentage for r in rows) == 100.0
|
|
|
|
def test_date_range_overrides_cycle(self, session):
|
|
seed(session)
|
|
rows = spending_by_category(
|
|
start_date="2026-06-01",
|
|
end_date="2026-06-10",
|
|
cycle_year=2026,
|
|
cycle_month=1, # would match nothing; range must win
|
|
session=session,
|
|
_user="t",
|
|
)
|
|
assert len(rows) == 1
|
|
assert rows[0].category_name == "Groceries"
|
|
assert rows[0].total == 1000.50
|
|
|
|
|
|
class TestDailySpending:
|
|
def test_date_range_filter(self, session):
|
|
seed(session)
|
|
rows = daily_spending(
|
|
start_date="2026-06-15", end_date="2026-07-01",
|
|
session=session, _user="t",
|
|
)
|
|
assert [r.date for r in rows] == ["2026-06-20"]
|
|
assert rows[0].total == 2000.00
|
|
|
|
def test_future_cuotas_excluded(self, session):
|
|
make_cc_tx(session, merchant="FUTURE", amount="500.00",
|
|
reference="f1", date=datetime(2030, 1, 19))
|
|
rows = daily_spending(session=session, _user="t")
|
|
assert rows == []
|