DispelEvilBot/tests/test_admin_users.py

99 lines
3.3 KiB
Python

"""Тесты раздела «Пользователи» (без БД — репозиторий подменяется)."""
from __future__ import annotations
from datetime import UTC, datetime
from typing import Any
import pytest
from common.repositories import users_admin_repo
USER: dict[str, Any] = {
"id_user": 42,
"username": "test_user",
"first_name": "Test",
"last_name": None,
"nick": "ТестовыйНик",
"lvl": 3,
"expr": 120,
"expr_streak": 2,
"dt_create": datetime(2026, 1, 1, 12, 0, tzinfo=UTC),
"title": "Ветеран",
"msg_count": 42,
"last_message_at": datetime(2026, 10, 18, 20, 0, tzinfo=UTC),
"balance": 1500,
"eggs": 2,
"purification_count": 5,
"last_purification_at": datetime(2026, 10, 17, 16, 0, tzinfo=UTC),
"subscribed": True,
}
MONEY: list[dict[str, Any]] = [
{"id_money": 2, "amount": 50, "dt_action": datetime(2026, 10, 18, 16, 0, tzinfo=UTC), "action": "Очищение"},
{"id_money": 1, "amount": -20, "dt_action": datetime(2026, 10, 17, 12, 0, tzinfo=UTC), "action": "Покупка"},
]
@pytest.fixture
def fake_repo(monkeypatch: pytest.MonkeyPatch) -> dict[str, Any]:
state: dict[str, Any] = {"total": 1, "calls": []}
async def count_users(search: str = "") -> int:
state["search"] = search
return state["total"]
async def list_users(search: str = "", *, limit: int = 25, offset: int = 0) -> list[dict[str, Any]]:
state["calls"].append({"search": search, "limit": limit, "offset": offset})
return [USER]
async def get_user(user_id: int) -> dict[str, Any] | None:
return USER if user_id == USER["id_user"] else None
async def money_history(user_id: int, *, limit: int = 10) -> list[dict[str, Any]]:
return MONEY if user_id == USER["id_user"] else []
monkeypatch.setattr(users_admin_repo, "count_users", count_users)
monkeypatch.setattr(users_admin_repo, "list_users", list_users)
monkeypatch.setattr(users_admin_repo, "get_user", get_user)
monkeypatch.setattr(users_admin_repo, "money_history", money_history)
return state
def test_users_list(fake_repo: dict[str, Any], client_factory) -> None:
response = client_factory().get("/users")
assert response.status_code == 200
assert "ТестовыйНик" in response.text
assert "@test_user" in response.text
assert "1500" in response.text
def test_users_search_passed_to_repo(fake_repo: dict[str, Any], client_factory) -> None:
client_factory().get("/users", params={"q": "Тест"})
assert fake_repo["calls"][0]["search"] == "Тест"
def test_users_pagination(fake_repo: dict[str, Any], client_factory) -> None:
fake_repo["total"] = 30
response = client_factory().get("/users", params={"page": "2"})
assert "Страница 2 из 2" in response.text
assert fake_repo["calls"][0]["offset"] == 25
def test_user_card(fake_repo: dict[str, Any], client_factory) -> None:
response = client_factory().get("/users/42")
assert response.status_code == 200
assert "Ветеран" in response.text
assert "Очищение" in response.text
assert "+50" in response.text
assert "-20" in response.text
def test_user_card_404(fake_repo: dict[str, Any], client_factory) -> None:
assert client_factory().get("/users/99").status_code == 404