Files
outlookEmailPlus/tests/test_smoke_contract.py
T
胡绍康andCopilot c70d2b97dd chore: 代码质量修复 + CI升级
- black 格式化 (1 file)
- isort 排序修复 (30 files, --profile black)
- 升级 actions/checkout v4 → v6 (全部 3 个 workflow)
- 添加 pyproject.toml (black/isort 配置)
- isort CI 命令添加 --profile black 参数
- 114 测试全部通过

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 21:52:44 +08:00

132 lines
4.8 KiB
Python

import unittest
from tests._import_app import clear_login_attempts, import_web_app_module
class SmokeContractTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.module = import_web_app_module()
cls.app = cls.module.app
def setUp(self):
# 每个测试前清理登录限制记录,避免测试间互相影响
with self.app.app_context():
clear_login_attempts()
def _login(self, client):
resp = client.post("/login", json={"password": "testpass123"})
self.assertEqual(resp.status_code, 200)
data = resp.get_json()
self.assertEqual(data.get("success"), True)
def test_healthz_contract(self):
client = self.app.test_client()
resp = client.get("/healthz")
self.assertEqual(resp.status_code, 200)
data = resp.get_json()
self.assertEqual(data.get("status"), "ok")
def test_pages_are_accessible(self):
client = self.app.test_client()
# 登录页(未登录也可访问)
resp = client.get("/login")
self.assertEqual(resp.status_code, 200)
self.assertIn("text/html", (resp.headers.get("Content-Type") or ""))
# 主页(需要登录)
self._login(client)
resp = client.get("/")
self.assertEqual(resp.status_code, 200)
self.assertIn("text/html", (resp.headers.get("Content-Type") or ""))
html = resp.get_data(as_text=True)
# 前端静态资源应已迁出(零构建):不再内联 style/script
self.assertNotIn("<style>", html)
self.assertNotIn("<script>", html)
self.assertIn("css/main.css", html)
self.assertIn("js/main.js", html)
self.assertIn("js/features/groups.js", html)
self.assertIn("js/features/accounts.js", html)
def test_static_asset_is_accessible(self):
client = self.app.test_client()
resp = client.get("/static/health.txt")
self.assertEqual(resp.status_code, 200)
self.assertIn("ok", resp.get_data(as_text=True))
resp.close()
# 新增静态资源(P0-5):CSS/JS 迁出与拆分
resp = client.get("/static/css/main.css")
self.assertEqual(resp.status_code, 200)
self.assertIn(".navbar", resp.get_data(as_text=True))
resp.close()
resp = client.get("/static/js/main.js")
self.assertEqual(resp.status_code, 200)
self.assertIn("initCSRFToken", resp.get_data(as_text=True))
resp.close()
resp = client.get("/static/js/features/groups.js")
self.assertEqual(resp.status_code, 200)
self.assertIn("loadGroups", resp.get_data(as_text=True))
resp.close()
def test_contract_sampled_endpoints_after_login(self):
client = self.app.test_client()
self._login(client)
resp = client.get("/api/system/health")
self.assertEqual(resp.status_code, 200)
data = resp.get_json()
self.assertEqual(data.get("success"), True)
health = data.get("health") or {}
self.assertIn("service", health)
self.assertIn("database", health)
self.assertIn("scheduler", health)
self.assertIn("refresh", health)
resp = client.get("/api/scheduler/status")
self.assertEqual(resp.status_code, 200)
data = resp.get_json()
self.assertEqual(data.get("success"), True)
self.assertIn("scheduler", data)
self.assertIn("refresh", data)
resp = client.get("/api/system/upgrade-status")
self.assertEqual(resp.status_code, 200)
data = resp.get_json()
self.assertEqual(data.get("success"), True)
upgrade = data.get("upgrade") or {}
self.assertIn("schema_version", upgrade)
self.assertIn("target_version", upgrade)
self.assertIn("up_to_date", upgrade)
self.assertIn("backup_hint", upgrade)
resp = client.get("/api/groups")
self.assertEqual(resp.status_code, 200)
data = resp.get_json()
self.assertEqual(data.get("success"), True)
self.assertIsInstance(data.get("groups"), list)
resp = client.get("/api/tags")
self.assertEqual(resp.status_code, 200)
data = resp.get_json()
self.assertEqual(data.get("success"), True)
self.assertIsInstance(data.get("tags"), list)
resp = client.get("/api/accounts")
self.assertEqual(resp.status_code, 200)
data = resp.get_json()
self.assertEqual(data.get("success"), True)
self.assertIsInstance(data.get("accounts"), list)
resp = client.get("/api/audit-logs")
self.assertEqual(resp.status_code, 200)
data = resp.get_json()
self.assertEqual(data.get("success"), True)
self.assertIsInstance(data.get("logs"), list)
self.assertIn("total", data)
self.assertIn("limit", data)
self.assertIn("offset", data)