"""Тесты ручной отправки сообщения из админки.""" from __future__ import annotations from typing import Any import pytest from fastapi.testclient import TestClient from admin import telegram from common.repositories import admin_messages_repo @pytest.fixture def fake_send(monkeypatch: pytest.MonkeyPatch) -> dict[str, Any]: state: dict[str, Any] = {} async def recent(*, limit: int = 10) -> list[dict[str, Any]]: return [] async def log_message(**kwargs: Any) -> None: state["audit"] = kwargs async def send_to_chat(settings: Any, *, text: str, buttons: list, photo: Any = None) -> None: state["send"] = {"text": text, "buttons": buttons, "photo": photo} monkeypatch.setattr(admin_messages_repo, "recent", recent) monkeypatch.setattr(admin_messages_repo, "log_message", log_message) monkeypatch.setattr(telegram, "send_to_chat", send_to_chat) return state def _client(client_factory, settings_factory) -> TestClient: return client_factory(settings=settings_factory(chat_id=-100123), follow_redirects=False) def test_send_form(fake_send: dict[str, Any], client_factory, settings_factory) -> None: response = _client(client_factory, settings_factory).get("/send") assert response.status_code == 200 assert 'data-tag="b"' in response.text assert "-100123" in response.text def test_send_text(fake_send: dict[str, Any], client_factory, settings_factory, csrf_token) -> None: client = _client(client_factory, settings_factory) token = csrf_token(client.get("/send").text) response = client.post( "/send", data={"text": "Привет, клан!", "buttons": "Канал | https://t.me/x", "csrf_token": token}, ) assert response.status_code == 303 assert response.headers["location"] == "/send?saved=true" assert fake_send["send"]["text"] == "Привет, клан!" assert fake_send["send"]["buttons"] == [("Канал", "https://t.me/x")] assert fake_send["send"]["photo"] is None assert fake_send["audit"]["success"] is True def test_send_rejects_bad_buttons(fake_send: dict[str, Any], client_factory, settings_factory, csrf_token) -> None: client = _client(client_factory, settings_factory) token = csrf_token(client.get("/send").text) response = client.post("/send", data={"text": "Текст", "buttons": "без ссылки", "csrf_token": token}) assert response.status_code == 400 assert "Кнопка без разделителя" in response.text assert "send" not in fake_send def test_send_requires_text_or_image(fake_send: dict[str, Any], client_factory, settings_factory, csrf_token) -> None: client = _client(client_factory, settings_factory) token = csrf_token(client.get("/send").text) response = client.post("/send", data={"text": " ", "csrf_token": token}) assert response.status_code == 400 assert "Нужен текст или картинка" in response.text def test_send_with_image(fake_send: dict[str, Any], client_factory, settings_factory, csrf_token) -> None: client = _client(client_factory, settings_factory) token = csrf_token(client.get("/send").text) response = client.post( "/send", data={"text": "С картинкой", "csrf_token": token}, files={"image": ("pic.png", b"fake-png", "image/png")}, ) assert response.status_code == 303 assert fake_send["send"]["photo"] is not None assert fake_send["send"]["photo"][1] == "image/png" assert fake_send["audit"]["has_image"] is True def test_send_telegram_error( fake_send: dict[str, Any], client_factory, settings_factory, csrf_token, monkeypatch: pytest.MonkeyPatch, ) -> None: async def send_to_chat(*args: Any, **kwargs: Any) -> None: raise telegram.TelegramError("chat not found") monkeypatch.setattr(telegram, "send_to_chat", send_to_chat) client = _client(client_factory, settings_factory) token = csrf_token(client.get("/send").text) response = client.post("/send", data={"text": "Текст", "csrf_token": token}) assert response.status_code == 400 assert "chat not found" in response.text assert fake_send["audit"]["success"] is False assert fake_send["audit"]["error"] == "chat not found"