Files
gsfdc/server/tests/test_about_pages.py

189 lines
6.9 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 test_association_intro_page_publish_filter_and_placeholder(client):
if not _minio_ready():
pytest.skip("MinIO 不可达")
staff = _headers("staff")
file_id = None
try:
before = client.get("/api/site/about/pages/intro")
assert before.status_code == 200, before.text
assert "协会简介整理中" in before.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_id = pdf.json()["id"]
saved = client.put(
"/api/admin/about/pages/intro",
headers=staff,
json={
"published": True,
"bodyHtml": "<p>服务会员与规范执业</p><script>alert(1)</script>",
"attachmentFileIds": [file_id],
},
)
assert saved.status_code == 200, saved.text
public = client.get("/api/site/about/pages/intro")
assert public.status_code == 200, public.text
data = public.json()
assert "服务会员与规范执业" in data["bodyHtml"]
lowered = data["bodyHtml"].lower()
assert "script" not in lowered
assert "alert" not in lowered
assert [item["filename"] for item in data["attachments"]] == ["协会章程.pdf"]
assert "协会简介整理中" not in public.text
emptied = client.put(
"/api/admin/about/pages/intro",
headers=staff,
json={"published": True, "bodyHtml": "", "attachmentFileIds": []},
)
assert emptied.status_code == 200, emptied.text
empty_public = client.get("/api/site/about/pages/intro")
assert empty_public.status_code == 200, empty_public.text
assert "协会简介整理中" in empty_public.text
published_again = client.put(
"/api/admin/about/pages/intro",
headers=staff,
json={
"published": True,
"bodyHtml": "<p>服务会员与规范执业</p>",
"attachmentFileIds": [file_id],
},
)
assert published_again.status_code == 200, published_again.text
before_member = client.get("/api/site/about/pages/intro").json()
rejected = client.put(
"/api/admin/about/pages/intro",
headers=_headers("member"),
json={"published": True, "bodyHtml": "<p>会员篡改</p>", "attachmentFileIds": []},
)
assert rejected.status_code in (401, 403)
after_member = client.get("/api/site/about/pages/intro")
assert after_member.status_code == 200
assert after_member.json()["bodyHtml"] == before_member["bodyHtml"]
assert "会员篡改" not in after_member.text
finally:
client.put(
"/api/admin/about/pages/intro",
headers=staff,
json={"published": False, "bodyHtml": "", "attachmentFileIds": []},
)
if file_id is not None:
client.delete(f"/api/admin/files/{file_id}", headers=staff)
def test_org_structure_page_unpublished_placeholder(client):
staff = _headers("staff")
client.put(
"/api/admin/about/pages/org",
headers=staff,
json={"published": False, "bodyHtml": "<p>草稿架构</p>", "attachmentFileIds": []},
)
public = client.get("/api/site/about/pages/org")
assert public.status_code == 200, public.text
assert "组织机构整理中" in public.text
assert "草稿架构" not in public.text
rejected = client.put(
"/api/admin/about/pages/org",
headers=_headers("member"),
json={"published": True, "bodyHtml": "<p>会员</p>", "attachmentFileIds": []},
)
assert rejected.status_code in (401, 403)
def test_contact_cooperation_page_without_forms(client):
if not _minio_ready():
pytest.skip("MinIO 不可达")
staff = _headers("staff")
file_id = None
try:
unpublished = client.get("/api/site/about/pages/contact")
# reset first
client.put(
"/api/admin/about/pages/contact",
headers=staff,
json={"published": False, "bodyHtml": "", "attachmentFileIds": []},
)
unpublished = client.get("/api/site/about/pages/contact")
assert "联系与合作信息整理中" in unpublished.text
doc = client.post(
"/api/admin/files",
headers=staff,
data={"bucket": "public"},
files={"file": ("入会申请表.docx", b"PK\x03\x04join", "application/octet-stream")},
)
assert doc.status_code == 200, doc.text
file_id = doc.json()["id"]
saved = client.put(
"/api/admin/about/pages/contact",
headers=staff,
json={
"published": True,
"bodyHtml": "<p>来访请先电话预约</p>",
"attachmentFileIds": [file_id],
},
)
assert saved.status_code == 200, saved.text
public = client.get("/api/site/about/pages/contact")
assert public.status_code == 200, public.text
data = public.json()
assert "来访请先电话预约" in data["bodyHtml"]
assert [item["filename"] for item in data["attachments"]] == ["入会申请表.docx"]
assert "formFields" not in data
assert "signupUrl" not in data
assert client.post("/api/site/about/pages/contact/intent", json={}).status_code == 404
assert client.post("/api/site/about/pages/contact/join", json={}).status_code == 404
finally:
client.put(
"/api/admin/about/pages/contact",
headers=staff,
json={"published": False, "bodyHtml": "", "attachmentFileIds": []},
)
if file_id is not None:
client.delete(f"/api/admin/files/{file_id}", headers=staff)