75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.bot import parse_transaction
|
|
from app.db import Database
|
|
|
|
|
|
def make_database(tmp_path: Path) -> Database:
|
|
database = Database(tmp_path / "test.sqlite3")
|
|
database.initialize()
|
|
return database
|
|
|
|
|
|
def add_user(database: Database, user_id: int, name: str) -> None:
|
|
database.upsert_user(
|
|
user_id=user_id,
|
|
first_name=name,
|
|
last_name=None,
|
|
username=None,
|
|
)
|
|
|
|
|
|
def test_transaction_and_leaderboard(tmp_path: Path) -> None:
|
|
database = make_database(tmp_path)
|
|
add_user(database, 1, "Аня")
|
|
item = parse_transaction(
|
|
'{"v":1,"type":"transaction","kind":"income","amount":"1000.50","category":"Зарплата","occurred_at":"2026-01-01T00:00:00Z"}'
|
|
)
|
|
database.add_transaction(1, item)
|
|
expense = parse_transaction(
|
|
'{"v":1,"type":"transaction","kind":"expense","amount":"250.25","category":"Еда","occurred_at":"2026-01-02T00:00:00Z"}'
|
|
)
|
|
database.add_transaction(1, expense)
|
|
|
|
summary = database.summary(1)
|
|
assert summary is not None
|
|
assert summary["income_cents"] == 100_050
|
|
assert summary["expense_cents"] == 25_025
|
|
assert summary["saved_percent"] == 75.0
|
|
assert database.leaderboard()[0]["nickname"] == "Аня"
|
|
|
|
|
|
def test_friendship_is_symmetric_and_idempotent(tmp_path: Path) -> None:
|
|
database = make_database(tmp_path)
|
|
add_user(database, 3, "Три")
|
|
add_user(database, 7, "Семь")
|
|
|
|
assert database.add_friendship(7, 3)
|
|
assert not database.add_friendship(3, 7)
|
|
assert database.friend_ids(3) == [7]
|
|
assert database.friend_ids(7) == [3]
|
|
|
|
|
|
def test_filtered_leaderboard(tmp_path: Path) -> None:
|
|
database = make_database(tmp_path)
|
|
for user_id in (1, 2, 3):
|
|
add_user(database, user_id, str(user_id))
|
|
|
|
result = database.leaderboard(user_ids=[1, 3])
|
|
assert [item["user_id"] for item in result] == [1, 3]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"payload",
|
|
[
|
|
"not-json",
|
|
'{"v":1,"type":"transaction","kind":"other","amount":"10","category":"Еда"}',
|
|
'{"v":1,"type":"transaction","kind":"income","amount":"-1","category":"Зарплата"}',
|
|
'{"v":1,"type":"transaction","kind":"income","amount":"10","category":""}',
|
|
],
|
|
)
|
|
def test_rejects_invalid_webapp_payload(payload: str) -> None:
|
|
with pytest.raises(ValueError):
|
|
parse_transaction(payload)
|