227 lines
8.4 KiB
Python
227 lines
8.4 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 _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_library_publish_kind_search_and_cases(client):
|
|
if not _minio_ready():
|
|
pytest.skip("MinIO 不可达")
|
|
staff = _headers("staff")
|
|
article_ids: list[int] = []
|
|
file_ids: list[int] = []
|
|
try:
|
|
empty_policy = client.get("/api/site/about/articles/policy_analyses")
|
|
assert empty_policy.status_code == 200, empty_policy.text
|
|
assert "暂无政策分析" in empty_policy.text
|
|
|
|
empty_cases = client.get("/api/site/about/articles/case_library")
|
|
assert empty_cases.status_code == 200, empty_cases.text
|
|
assert "暂无案例库" in empty_cases.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"])
|
|
pdf = client.post(
|
|
"/api/admin/files",
|
|
headers=staff,
|
|
data={"bucket": "public"},
|
|
files={"file": ("政策.pdf", b"%PDF-1.4\npolicy", "application/pdf")},
|
|
)
|
|
assert pdf.status_code == 200, pdf.text
|
|
file_ids.append(pdf.json()["id"])
|
|
|
|
published = client.post(
|
|
"/api/admin/home/articles",
|
|
headers=staff,
|
|
json={
|
|
"category": "policy_analyses",
|
|
"kind": "national",
|
|
"title": "资料库检索样例-民法典导读",
|
|
"published": True,
|
|
"publishedAt": "2025-09-12T08:00:00",
|
|
"bodyHtml": "<p>本条标注:现行有效。</p>",
|
|
"imageFileId": cover.json()["id"],
|
|
"attachmentFileIds": [pdf.json()["id"]],
|
|
},
|
|
)
|
|
assert published.status_code == 200, published.text
|
|
article_ids.append(published.json()["id"])
|
|
|
|
local = client.post(
|
|
"/api/admin/home/articles",
|
|
headers=staff,
|
|
json={
|
|
"category": "policy_analyses",
|
|
"kind": "local",
|
|
"title": "资料库检索样例-地方配套",
|
|
"published": True,
|
|
"publishedAt": "2025-03-08T08:00:00",
|
|
"bodyHtml": "<p>仅收录本地区政策。</p>",
|
|
"attachmentFileIds": [],
|
|
},
|
|
)
|
|
assert local.status_code == 200, local.text
|
|
article_ids.append(local.json()["id"])
|
|
|
|
hidden = client.post(
|
|
"/api/admin/home/articles",
|
|
headers=staff,
|
|
json={
|
|
"category": "policy_analyses",
|
|
"kind": "expert",
|
|
"title": "资料库检索样例-未发布解读",
|
|
"published": False,
|
|
"bodyHtml": "<p>正文里有未发布机密词。</p>",
|
|
"attachmentFileIds": [],
|
|
},
|
|
)
|
|
assert hidden.status_code == 200, hidden.text
|
|
article_ids.append(hidden.json()["id"])
|
|
|
|
bad_kind = client.post(
|
|
"/api/admin/home/articles",
|
|
headers=staff,
|
|
json={
|
|
"category": "policy_analyses",
|
|
"kind": "residential",
|
|
"title": "资料库检索样例-错误分类",
|
|
"published": True,
|
|
"bodyHtml": "<p>x</p>",
|
|
"attachmentFileIds": [],
|
|
},
|
|
)
|
|
assert bad_kind.status_code == 400
|
|
|
|
case_with_kind = client.post(
|
|
"/api/admin/home/articles",
|
|
headers=staff,
|
|
json={
|
|
"category": "case_library",
|
|
"kind": "national",
|
|
"title": "资料库检索样例-案例不分类",
|
|
"published": True,
|
|
"bodyHtml": "<p>案例正文</p>",
|
|
"attachmentFileIds": [],
|
|
},
|
|
)
|
|
assert case_with_kind.status_code == 400
|
|
|
|
case = client.post(
|
|
"/api/admin/home/articles",
|
|
headers=staff,
|
|
json={
|
|
"category": "case_library",
|
|
"title": "资料库检索样例-城关区案例",
|
|
"published": True,
|
|
"publishedAt": "2025-08-16T08:00:00",
|
|
"bodyHtml": "<p>可比案例说明。</p>",
|
|
"imageFileId": cover.json()["id"],
|
|
"attachmentFileIds": [pdf.json()["id"]],
|
|
},
|
|
)
|
|
assert case.status_code == 200, case.text
|
|
article_ids.append(case.json()["id"])
|
|
|
|
listed = client.get("/api/site/about/articles/policy_analyses")
|
|
titles = [item["title"] for item in listed.json()["items"]]
|
|
assert "资料库检索样例-民法典导读" in titles
|
|
assert "资料库检索样例-未发布解读" not in titles
|
|
national = next(item for item in listed.json()["items"] if item["title"] == "资料库检索样例-民法典导读")
|
|
assert national["kind"] == "national"
|
|
assert national["kindLabel"] == "国家级"
|
|
assert national["imageUrl"]
|
|
|
|
only_local = client.get("/api/site/about/articles/policy_analyses?kind=local")
|
|
assert [item["title"] for item in only_local.json()["items"]] == ["资料库检索样例-地方配套"]
|
|
|
|
by_title = client.get("/api/site/about/articles/policy_analyses?q=民法典")
|
|
assert [item["title"] for item in by_title.json()["items"]] == ["资料库检索样例-民法典导读"]
|
|
|
|
by_body = client.get("/api/site/about/articles/policy_analyses?q=现行有效")
|
|
assert [item["title"] for item in by_body.json()["items"]] == ["资料库检索样例-民法典导读"]
|
|
|
|
hidden_body = client.get("/api/site/about/articles/policy_analyses?q=未发布机密词")
|
|
assert hidden_body.json()["placeholder"] == "未找到相关政策"
|
|
assert hidden_body.json()["items"] == []
|
|
|
|
unknown = client.get("/api/site/about/articles/policy_analyses?kind=unknown")
|
|
assert unknown.status_code == 404
|
|
|
|
cases = client.get("/api/site/about/articles/case_library")
|
|
assert cases.json()["items"][0]["title"] == "资料库检索样例-城关区案例"
|
|
assert "kind" not in cases.json()["items"][0]
|
|
|
|
detail = client.get(f"/api/site/home/articles/{national['id']}")
|
|
assert detail.status_code == 200, detail.text
|
|
assert "现行有效" in detail.text
|
|
assert "政策.pdf" in detail.text
|
|
|
|
home = client.get("/api/admin/home", headers=staff)
|
|
categories = {item["category"] for item in home.json()["articles"]}
|
|
assert "policy_analyses" not in categories
|
|
assert "case_library" not in categories
|
|
|
|
rejected = client.post(
|
|
"/api/admin/home/articles",
|
|
headers=_headers("member"),
|
|
json={
|
|
"category": "policy_analyses",
|
|
"kind": "national",
|
|
"title": "会员不得发布政策",
|
|
"published": True,
|
|
"bodyHtml": "<p>x</p>",
|
|
"attachmentFileIds": [],
|
|
},
|
|
)
|
|
assert rejected.status_code in (401, 403)
|
|
finally:
|
|
for article_id in article_ids:
|
|
client.delete(f"/api/admin/home/articles/{article_id}", headers=staff)
|
|
for file_id in file_ids:
|
|
client.delete(f"/api/admin/files/{file_id}", headers=staff)
|