"""Обратная связь и права администратора портала (настройки сервера, ответы обратной связи).""" import os import tempfile os.environ.setdefault("DATABASE_URL", os.environ.get("TEST_DATABASE_URL") or "sqlite:///" + os.path.join(tempfile.mkdtemp(), "fb.db").replace("\\", "/")) os.environ.setdefault("SCHEDULER_INTERVAL", "3600") os.environ.setdefault("SECRET_KEY", "test-secret-key-for-pytest-0123456789abcdef") os.environ.setdefault("DATA_DIR", tempfile.mkdtemp()) from fastapi.testclient import TestClient # noqa: E402 from app.main import app # noqa: E402 V1 = "/api/v1" PW = "Pass1234567" def test_feedback_and_portal_admin(): with TestClient(app) as c: login = lambda u, p=PW: {"Authorization": "Bearer " + c.post(f"{V1}/auth/login", json={"username": u, "password": p}).json()["access_token"]} root = login("admin", "admin") me = c.get(f"{V1}/me", headers=root).json() assert me["is_root"] and me["portal_admin"] a2 = c.post(f"{V1}/users", headers=root, json={"username": "fb_adm", "full_name": "Второй админ", "password": PW, "is_admin": True}).json() c.post(f"{V1}/users", headers=root, json={"username": "fb_t", "full_name": "Техник", "password": PW}) adm2, t = login("fb_adm"), login("fb_t") # обычный администратор: настроек сервера и обратной связи нет, мастер работает (только setup_done) assert c.get(f"{V1}/me", headers=adm2).json()["portal_admin"] is False lim = c.get(f"{V1}/settings", headers=adm2).json() assert lim.get("limited") and "photo_dir" not in lim assert c.put(f"{V1}/settings", headers=adm2, json={"setup_done": "users"}).status_code == 200 assert c.put(f"{V1}/settings", headers=adm2, json={"max_photo_mb": 5}).status_code == 403 assert c.get(f"{V1}/api-keys", headers=adm2).status_code == 403 assert c.get(f"{V1}/assistant/config", headers=adm2).status_code == 403 assert c.get(f"{V1}/feedback", headers=adm2).status_code == 403 # выдать права может только admin; admin не может лишиться прав assert c.patch(f"{V1}/users/{a2['id']}", headers=adm2, json={"portal_admin": True}).status_code == 403 assert c.patch(f"{V1}/users/{me['id']}", headers=adm2, json={"is_admin": False}).status_code == 403 assert c.patch(f"{V1}/users/{a2['id']}", headers=root, json={"portal_admin": True}).json()["portal_admin"] is True assert c.get(f"{V1}/settings", headers=adm2).json().get("photo_dir") # обратная связь: отправляет любой, видят администраторы портала r = c.post(f"{V1}/feedback", headers=t, json={"kind": "bug", "text": "Кнопка не видна на телефоне", "page": "#/work", "client": "m"}) assert r.status_code == 201 assert c.get(f"{V1}/feedback", headers=t).status_code == 403 lst = c.get(f"{V1}/feedback", headers=root, params={"status": "open"}).json() fb = next(x for x in lst if x["text"].startswith("Кнопка")) assert fb["user_name"] == "Техник" and fb["kind"] == "bug" and fb["page"] == "#/work" u = c.patch(f"{V1}/feedback/{fb['id']}", headers=adm2, json={"status": "done", "answer": "Исправлено"}).json() assert u["status"] == "done" and u["answered_by_name"] == "Второй админ" assert c.post(f"{V1}/feedback", headers=t, json={"text": "x"}).status_code == 422