"""Тесты админки: каркас, раздел «Сообщения» (без БД — репозиторий подменяется).""" from __future__ import annotations from datetime import UTC, datetime from typing import Any import pytest from fastapi.testclient import TestClient from admin.app import create_app from common.config import AdminSettings from common.repositories import templates_repo TEMPLATE: dict[str, Any] = { "key": "info.help", "text": "Справка по командам", "description": "Справка (/помощь)", "enabled": True, "updated_at": datetime(2026, 1, 1, 12, 0, tzinfo=UTC), "updated_by": None, } def _client() -> TestClient: settings = AdminSettings(_env_file=None, bot_token="", db_password="test", app_env="dev") return TestClient(create_app(settings, init_db=False)) def test_healthz() -> None: response = _client().get("/healthz") assert response.status_code == 200 payload = response.json() assert payload["status"] == "ok" assert payload["app_env"] == "dev" def test_index_renders_sections() -> None: response = _client().get("/") assert response.status_code == 200 assert "Панель администрирования" in response.text assert "Расписания" in response.text def test_messages_list(monkeypatch: pytest.MonkeyPatch) -> None: async def fake_list() -> list[dict[str, Any]]: return [{**TEMPLATE, "text_length": len(TEMPLATE["text"])}] monkeypatch.setattr(templates_repo, "list_templates", fake_list) response = _client().get("/messages") assert response.status_code == 200 assert "info.help" in response.text assert "Справка (/помощь)" in response.text def test_message_editor_and_history(monkeypatch: pytest.MonkeyPatch) -> None: async def fake_get(key: str) -> dict[str, Any] | None: return TEMPLATE if key == TEMPLATE["key"] else None async def fake_history(key: str, *, limit: int = 10) -> list[dict[str, Any]]: return [] monkeypatch.setattr(templates_repo, "get_template", fake_get) monkeypatch.setattr(templates_repo, "template_history", fake_history) response = _client().get("/messages/info.help") assert response.status_code == 200 assert "Справка по командам" in response.text assert "Доступные теги" in response.text def test_message_editor_404(monkeypatch: pytest.MonkeyPatch) -> None: async def fake_get(key: str) -> dict[str, Any] | None: return None monkeypatch.setattr(templates_repo, "get_template", fake_get) assert _client().get("/messages/unknown").status_code == 404 def test_preview_renders_tags() -> None: response = _client().post("/messages/preview", data={"text": "Привет, {nick}!"}) assert response.status_code == 200 assert "ТестовыйНик" in response.text assert " None: response = _client().post("/messages/preview", data={"text": "Привет, {unknown_tag}!"}) assert response.status_code == 200 assert "Неизвестные теги" in response.text def test_save_rejects_unknown_tag(monkeypatch: pytest.MonkeyPatch) -> None: async def fake_get(key: str) -> dict[str, Any] | None: return TEMPLATE async def fake_history(key: str, *, limit: int = 10) -> list[dict[str, Any]]: return [] monkeypatch.setattr(templates_repo, "get_template", fake_get) monkeypatch.setattr(templates_repo, "template_history", fake_history) response = _client().post("/messages/info.help", data={"text": "текст {unknown_tag}"}) assert response.status_code == 400 assert "Неизвестные теги" in response.text def test_save_updates_template(monkeypatch: pytest.MonkeyPatch) -> None: saved: dict[str, Any] = {} async def fake_get(key: str) -> dict[str, Any] | None: return TEMPLATE async def fake_history(key: str, *, limit: int = 10) -> list[dict[str, Any]]: return [] async def fake_update(key: str, text: str, *, editor_id: int | None = None) -> dict[str, Any]: saved.update(key=key, text=text) return {"key": key, "text": text, "old_text": TEMPLATE["text"], "changed": True} monkeypatch.setattr(templates_repo, "get_template", fake_get) monkeypatch.setattr(templates_repo, "template_history", fake_history) monkeypatch.setattr(templates_repo, "update_template", fake_update) response = _client().post("/messages/info.help", data={"text": "Новая справка"}) assert response.status_code == 200 assert "Текст сохранён" in response.text assert saved == {"key": "info.help", "text": "Новая справка"}