mirror of
https://github.com/Zproger/Aurum.git
synced 2026-10-13 02:56:39 +07:00
84 lines
2.9 KiB
Python
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)
|