189 lines
6.9 KiB
Python
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)
|