test_admin_feedback.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. """管理端台账 / 办理 / 配置 API 测试"""
  2. import pytest
  3. from app.core.security import hash_password
  4. from app.crud import user as user_crud
  5. from app.main import app as fastapi_app
  6. from app.core.database import get_db
  7. def _login(client, username: str, password: str) -> dict:
  8. r = client.post(
  9. "/api/web/auth/login", json={"username": username, "password": password}
  10. )
  11. assert r.status_code == 200, r.text
  12. token = r.json()["data"]["token"]
  13. return {"Authorization": f"Bearer {token}"}
  14. def _ensure_role_user(client, username: str, role_code: str, password: str = "Pass@123"):
  15. """在 client fixture 共享的 session 上插入角色用户。"""
  16. # 取出 override 的 session
  17. gen = fastapi_app.dependency_overrides[get_db]()
  18. db = next(gen)
  19. role = user_crud.get_role_by_code(db, role_code)
  20. assert role is not None
  21. existing = user_crud.get_user_by_username(db, username)
  22. if not existing:
  23. user_crud.create_user(
  24. db,
  25. username=username,
  26. password_hash=hash_password(password),
  27. display_name=username,
  28. role_id=role.id,
  29. )
  30. return _login(client, username, password)
  31. @pytest.fixture()
  32. def admin_headers(client):
  33. return _login(client, "admin", "Admin@123")
  34. @pytest.fixture()
  35. def handler_headers(client):
  36. return _ensure_role_user(client, "handler1", "handler")
  37. @pytest.fixture()
  38. def viewer_headers(client):
  39. return _ensure_role_user(client, "viewer1", "viewer")
  40. def test_viewer_cannot_handle(client, viewer_headers):
  41. fb = client.post(
  42. "/api/public/feedback", json={"fbType": "投诉", "content": "xxxx"}
  43. ).json()["data"]
  44. r = client.put(
  45. f"/api/web/admin/feedbacks/{fb['id']}/status",
  46. headers=viewer_headers,
  47. json={"status": "处理中"},
  48. )
  49. assert r.status_code == 403
  50. assert r.json()["code"] == 403
  51. def test_handler_can_handle_feedback(client, handler_headers):
  52. fb = client.post(
  53. "/api/public/feedback", json={"fbType": "投诉", "content": "需要办理的内容"}
  54. ).json()["data"]
  55. r = client.put(
  56. f"/api/web/admin/feedbacks/{fb['id']}/status",
  57. headers=handler_headers,
  58. json={"status": "处理中", "handleRemark": "已接单"},
  59. )
  60. assert r.status_code == 200
  61. assert r.json()["data"]["status"] == "处理中"
  62. assert r.json()["data"]["handleRemark"] == "已接单"
  63. def test_invalid_feedback_transition(client, handler_headers):
  64. fb = client.post(
  65. "/api/public/feedback", json={"fbType": "表扬", "content": "好评内容测试"}
  66. ).json()["data"]
  67. # 待处理不能直接回到非法状态(例如空跳转到不存在状态)
  68. r = client.put(
  69. f"/api/web/admin/feedbacks/{fb['id']}/status",
  70. headers=handler_headers,
  71. json={"status": "已办结"},
  72. )
  73. assert r.status_code == 200 # 待处理→已办结 允许
  74. r2 = client.put(
  75. f"/api/web/admin/feedbacks/{fb['id']}/status",
  76. headers=handler_headers,
  77. json={"status": "待处理"},
  78. )
  79. assert r2.status_code == 400
  80. def test_handler_cannot_update_hotline(client, handler_headers):
  81. r = client.put(
  82. "/api/web/admin/hotline",
  83. headers=handler_headers,
  84. json={"phone": "10086"},
  85. )
  86. assert r.status_code == 403
  87. def test_admin_update_hotline(client, admin_headers):
  88. r = client.put(
  89. "/api/web/admin/hotline",
  90. headers=admin_headers,
  91. json={"phone": "0551-88888888", "workTime": "工作日 9-17"},
  92. )
  93. assert r.status_code == 200
  94. assert r.json()["data"]["phone"] == "0551-88888888"
  95. pub = client.get("/api/public/hotline")
  96. assert pub.json()["data"]["phone"] == "0551-88888888"
  97. def test_dashboard(client, admin_headers):
  98. client.post(
  99. "/api/public/feedback", json={"fbType": "投诉", "content": "仪表盘反馈一条"}
  100. )
  101. r = client.get("/api/web/admin/dashboard", headers=admin_headers)
  102. assert r.status_code == 200
  103. data = r.json()["data"]
  104. assert data["feedbackTotal"] >= 1
  105. assert "recentFeedback" in data
  106. assert "complaintPending" in data
  107. def test_list_feedbacks(client, admin_headers):
  108. client.post(
  109. "/api/public/feedback", json={"fbType": "投诉", "content": "列表筛选关键字甲"}
  110. )
  111. r = client.get(
  112. "/api/web/admin/feedbacks",
  113. headers=admin_headers,
  114. params={"keyword": "关键字甲", "page": 1, "pageSize": 10},
  115. )
  116. assert r.status_code == 200
  117. data = r.json()["data"]
  118. assert data["total"] >= 1
  119. assert data["list"][0]["content"].find("关键字甲") >= 0
  120. def test_suggestion_handle(client, handler_headers):
  121. sg = client.post(
  122. "/api/public/suggestion", json={"content": "一条建言内容足够长"}
  123. ).json()["data"]
  124. r = client.put(
  125. f"/api/web/admin/suggestions/{sg['id']}/status",
  126. headers=handler_headers,
  127. json={"status": "已采纳"},
  128. )
  129. assert r.status_code == 200
  130. assert r.json()["data"]["status"] == "已采纳"