Files
gsfdc/server/tests/test_party_building.py

225 lines
8.8 KiB
Python

"""行业党建:支部介绍单篇 + 党建活动栏目文章。"""
import pytest
from fastapi.testclient import TestClient
from app.core.config import get_settings
from app.core.security import create_access_token
@pytest.fixture
def client(monkeypatch):
monkeypatch.setenv("JWT_SECRET", "test-secret-must-be-32-characters!")
monkeypatch.setenv("API_PAYLOAD_ENCRYPT", "false")
get_settings.cache_clear()
if not get_settings().database_url.strip():
pytest.skip("DATABASE_URL 为空")
from app.main import create_app
with TestClient(create_app()) as api:
yield api
get_settings.cache_clear()
def _headers(token_type: str) -> dict[str, str]:
return {"Authorization": f"Bearer {create_access_token('1', token_type)}"}
def _minio_ready() -> bool:
try:
from app.services.storage import ensure_buckets
ensure_buckets()
return True
except Exception:
return False
def _clear_category(client, staff: dict[str, str], category: str) -> None:
listed = client.get(f"/api/admin/about/articles/{category}", headers=staff)
assert listed.status_code == 200, listed.text
for item in listed.json().get("items") or []:
deleted = client.delete(f"/api/admin/home/articles/{item['id']}", headers=staff)
assert deleted.status_code in (200, 204), deleted.text
def _png() -> bytes:
return (
b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01"
b"\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\x0cIDATx\x9cc\xf8\x0f"
b"\x00\x00\x01\x01\x00\x05\x18\xd8N\x00\x00\x00\x00IEND\xaeB`\x82"
)
def test_party_branch_page_and_activities(client):
if not _minio_ready():
pytest.skip("MinIO 不可达")
staff = _headers("staff")
article_ids: list[int] = []
file_ids: list[int] = []
try:
_clear_category(client, staff, "party_activities")
empty_page = client.get("/api/site/about/pages/party_branch")
assert empty_page.status_code == 200, empty_page.text
assert "协会党支部介绍整理中" in empty_page.text
empty_list = client.get("/api/site/about/articles/party_activities")
assert empty_list.status_code == 200, empty_list.text
assert "暂无党建活动" in empty_list.text
pdf = client.post(
"/api/admin/files",
headers=staff,
data={"bucket": "public"},
files={"file": ("党支部制度.pdf", b"%PDF-1.4\ncharter", "application/pdf")},
)
assert pdf.status_code == 200, pdf.text
file_ids.append(pdf.json()["id"])
saved_page = client.put(
"/api/admin/about/pages/party_branch",
headers=staff,
json={
"published": True,
"bodyHtml": "<p>党建引领行业发展</p><script>alert(1)</script>",
"attachmentFileIds": [file_ids[0]],
},
)
assert saved_page.status_code == 200, saved_page.text
public_page = client.get("/api/site/about/pages/party_branch")
assert public_page.status_code == 200, public_page.text
assert "党建引领行业发展" in public_page.json()["bodyHtml"]
lowered = public_page.json()["bodyHtml"].lower()
assert "script" not in lowered
assert "alert" not in lowered
assert [item["filename"] for item in public_page.json()["attachments"]] == ["党支部制度.pdf"]
assert "协会党支部介绍整理中" not in public_page.text
cover = client.post(
"/api/admin/files",
headers=staff,
data={"bucket": "public"},
files={"file": ("cover.png", _png(), "image/png")},
)
assert cover.status_code == 200, cover.text
file_ids.append(cover.json()["id"])
activity_pdf = client.post(
"/api/admin/files",
headers=staff,
data={"bucket": "public"},
files={"file": ("学习纪要.pdf", b"%PDF-1.4\nnotes", "application/pdf")},
)
assert activity_pdf.status_code == 200, activity_pdf.text
file_ids.append(activity_pdf.json()["id"])
published = client.post(
"/api/admin/home/articles",
headers=staff,
json={
"category": "party_activities",
"title": "主题党日:学习估价行业诚信自律要求",
"publishedAt": "2025-10-12T08:00:00",
"published": True,
"bodyHtml": "<p>主题党日学习</p><script>alert(1)</script>",
"imageFileId": file_ids[1],
"attachmentFileIds": [file_ids[2]],
},
)
assert published.status_code == 200, published.text
article_ids.append(published.json()["id"])
draft = client.post(
"/api/admin/home/articles",
headers=staff,
json={
"category": "party_activities",
"title": "内部筹备党建活动",
"publishedAt": "2025-10-13T08:00:00",
"published": False,
"bodyHtml": "<p>内部</p>",
"attachmentFileIds": [],
},
)
assert draft.status_code == 200, draft.text
article_ids.append(draft.json()["id"])
listed = client.get("/api/site/about/articles/party_activities")
assert listed.status_code == 200, listed.text
assert "主题党日:学习估价行业诚信自律要求" in listed.text
assert "内部筹备党建活动" not in listed.text
assert listed.json()["items"][0].get("imageUrl")
detail = client.get(f"/api/site/home/articles/{article_ids[0]}")
assert detail.status_code == 200, detail.text
assert "主题党日学习" in detail.json()["bodyHtml"]
body = detail.json()["bodyHtml"].lower()
assert "script" not in body
assert detail.json().get("imageUrl")
assert [item["filename"] for item in detail.json()["attachments"]] == ["学习纪要.pdf"]
assert client.get(f"/api/site/home/articles/{article_ids[1]}").status_code == 404
for index in range(10):
created = client.post(
"/api/admin/home/articles",
headers=staff,
json={
"category": "party_activities",
"title": f"党建分页样例-{index:02d}",
"publishedAt": f"2025-01-{index + 1:02d}T08:00:00",
"published": True,
"bodyHtml": f"<p>党建分页样例-{index:02d}</p>",
"attachmentFileIds": [],
},
)
assert created.status_code == 200, created.text
article_ids.append(created.json()["id"])
page1 = client.get("/api/site/about/articles/party_activities?current=1&size=10")
assert page1.json()["total"] == 11
assert page1.json()["size"] == 10
assert len(page1.json()["items"]) == 10
assert len(client.get("/api/site/about/articles/party_activities?current=2&size=10").json()["items"]) == 1
assert client.get("/api/site/about/articles/party_activities?current=1&size=20").json()["size"] == 20
assert client.get("/api/site/about/articles/party_activities?current=1&size=15").json()["size"] == 10
home = client.get("/api/admin/home", headers=staff)
assert home.status_code == 200, home.text
categories = {item["category"] for item in home.json()["articles"]}
assert "party_activities" not in categories
rejected = client.post(
"/api/admin/home/articles",
headers=_headers("member"),
json={
"category": "party_activities",
"title": "会员不得发布党建",
"published": True,
"bodyHtml": "<p>x</p>",
"attachmentFileIds": [],
},
)
assert rejected.status_code in (401, 403)
assert "会员不得发布党建" not in client.get("/api/site/about/articles/party_activities").text
emptied = client.put(
"/api/admin/about/pages/party_branch",
headers=staff,
json={"published": False, "bodyHtml": "<p></p>", "attachmentFileIds": []},
)
assert emptied.status_code == 200, emptied.text
assert "协会党支部介绍整理中" in client.get("/api/site/about/pages/party_branch").text
finally:
for article_id in article_ids:
client.delete(f"/api/admin/home/articles/{article_id}", headers=staff)
client.put(
"/api/admin/about/pages/party_branch",
headers=staff,
json={"published": False, "bodyHtml": "<p></p>", "attachmentFileIds": []},
)
for file_id in file_ids:
client.delete(f"/api/admin/files/{file_id}", headers=staff)