Files
aurum/backend/tests/test_insights.py
2026-09-08 20:03:13 +03:00

84 lines
2.9 KiB
Python

"""Proactive alerts (services/insights_service.py): only the idle-cash
signal is covered here — the other three (negative cash flow, net worth
decline, over-budget) predate this test file and aren't touched by this
change.
"""
from datetime import date, timedelta
from httpx import AsyncClient
from tests.helpers import txn_payload as _txn
STALE_DATE = (date.today() - timedelta(days=400)).isoformat()
RECENT_DATE = date.today().isoformat()
async def _alert_keys(client: AsyncClient) -> set[str]:
resp = await client.get("/insights/alerts")
return {alert["key"] for alert in resp.json()["alerts"]}
async def test_idle_cash_flags_a_stale_large_balance(client: AsyncClient, account_id, categories):
await client.post(
"/transactions",
json=_txn(account_id, type="income", amount="5000.00", category_id=categories["Salary"]["id"], date=STALE_DATE),
)
assert "idle_cash" in await _alert_keys(client)
async def test_idle_cash_ignores_a_recently_touched_account(client: AsyncClient, account_id, categories):
await client.post(
"/transactions",
json=_txn(account_id, type="income", amount="5000.00", category_id=categories["Salary"]["id"], date=STALE_DATE),
)
await client.post(
"/transactions",
json=_txn(account_id, type="expense", amount="1.00", category_id=categories["Groceries"]["id"], date=RECENT_DATE),
)
assert "idle_cash" not in await _alert_keys(client)
async def test_idle_cash_ignores_investment_accounts(client: AsyncClient, categories):
investment = await client.post("/accounts", json={"name": "Brokerage", "type": "investment", "currency": "USD"})
investment_id = investment.json()["id"]
await client.post(
"/transactions",
json=_txn(investment_id, type="income", amount="5000.00", category_id=categories["Salary"]["id"], date=STALE_DATE),
)
assert "idle_cash" not in await _alert_keys(client)
async def test_idle_cash_includes_debit_cards(client: AsyncClient, categories):
debit_card = await client.post(
"/accounts", json={"name": "Debit card", "type": "debit_card", "currency": "USD"}
)
debit_card_id = debit_card.json()["id"]
await client.post(
"/transactions",
json=_txn(
debit_card_id,
type="income",
amount="5000.00",
category_id=categories["Salary"]["id"],
date=STALE_DATE,
),
)
assert "idle_cash" in await _alert_keys(client)
async def test_idle_cash_respects_custom_threshold(client: AsyncClient, account_id, categories):
await client.post(
"/transactions",
json=_txn(account_id, type="income", amount="5000.00", category_id=categories["Salary"]["id"], date=STALE_DATE),
)
assert "idle_cash" in await _alert_keys(client)
resp = await client.patch("/settings", json={"idle_cash_threshold_amount": "10000.00"})
assert resp.status_code == 200
assert "idle_cash" not in await _alert_keys(client)