统一测试辅助函数到 conftest.py,消除代码重复

This commit is contained in:
2026-07-26 01:23:12 +08:00
parent 6b1f0d5f5f
commit 12d15878da
7 changed files with 276 additions and 421 deletions
+103 -14
View File
@@ -16,6 +16,31 @@ TEST_ID = uuid.uuid4().hex
TEST_DB = Path(tempfile.gettempdir()) / f"opencloud-{TEST_ID}.sqlite3"
TEST_UPLOADS = Path(tempfile.gettempdir()) / f"opencloud-{TEST_ID}-uploads"
ADMIN_EMAIL = "admin@example.com"
ADMIN_PASSWORD = "admin-password-123"
os.environ["ENVIRONMENT"] = "test"
os.environ["DATABASE_URL"] = f"sqlite+aiosqlite:///{TEST_DB}"
os.environ["SECRET_KEY"] = "test-secret-key-that-is-long-enough-for-opencloud"
os.environ["PUBLIC_BASE_URL"] = "http://testserver"
os.environ["FRONTEND_URL"] = "http://testserver"
os.environ["CORS_ORIGINS"] = "http://testserver"
os.environ["UPLOAD_DIR"] = str(TEST_UPLOADS)
os.environ["EMAIL_DELIVERY_MODE"] = "console"
os.environ["ADMIN_EMAIL"] = ADMIN_EMAIL
os.environ["ADMIN_PASSWORD"] = ADMIN_PASSWORD
os.environ["ADMIN_USERNAME"] = "测试管理员"
from app.database import Base, engine # noqa: E402
from app.main import app # noqa: E402
from app.routers import auth as auth_router # noqa: E402
from app.seed import seed # noqa: E402
# ---------------------------------------------------------------------------
# shared helpers — usable from any test file
# ---------------------------------------------------------------------------
def bearer(token: str) -> dict[str, str]:
return {"Authorization": f"Bearer {token}"}
@@ -26,21 +51,85 @@ def png_bytes() -> bytes:
Image.new("RGB", (200, 200), color=(125, 196, 240)).save(output, format="PNG")
return output.getvalue()
os.environ["ENVIRONMENT"] = "test"
os.environ["DATABASE_URL"] = f"sqlite+aiosqlite:///{TEST_DB}"
os.environ["SECRET_KEY"] = "test-secret-key-that-is-long-enough-for-opencloud"
os.environ["PUBLIC_BASE_URL"] = "http://testserver"
os.environ["FRONTEND_URL"] = "http://testserver"
os.environ["CORS_ORIGINS"] = "http://testserver"
os.environ["UPLOAD_DIR"] = str(TEST_UPLOADS)
os.environ["EMAIL_DELIVERY_MODE"] = "console"
os.environ["ADMIN_EMAIL"] = "admin@example.com"
os.environ["ADMIN_PASSWORD"] = "admin-password-123"
os.environ["ADMIN_USERNAME"] = "测试管理员"
from app.database import Base, engine # noqa: E402
from app.main import app # noqa: E402
from app.seed import seed # noqa: E402
def capture_email(monkeypatch) -> dict[str, str]:
"""Patch send_confirmation_email and return a dict that will hold the token."""
captured: dict[str, str] = {}
async def capture(recipient: str, token: str) -> None:
captured["token"] = token
monkeypatch.setattr(auth_router, "send_confirmation_email", capture)
return captured
def register_user(client: TestClient, email: str, password: str, username: str):
return client.post(
"/api/v1/auth/register",
json={"email": email, "password": password, "username": username},
)
def confirm_email(client: TestClient, token: str):
return client.post("/api/v1/auth/confirm-email", json={"token": token})
def login_user(client: TestClient, email: str, password: str):
return client.post(
"/api/v1/auth/login",
json={"email": email, "password": password},
)
def register_and_confirm(
client: TestClient,
monkeypatch,
email: str,
password: str,
username: str,
) -> dict[str, str]:
"""Create a fully registered + confirmed user. Returns token & user_id."""
captured = capture_email(monkeypatch)
r = register_user(client, email, password, username)
assert r.status_code == 201
token = captured.get("token")
assert token
cr = confirm_email(client, token)
assert cr.status_code == 200
lr = login_user(client, email, password)
assert lr.status_code == 200
body = lr.json()
return {"token": body["access_token"], "user_id": body["user"]["id"]}
def admin_token(client: TestClient) -> str:
r = login_user(client, ADMIN_EMAIL, ADMIN_PASSWORD)
return r.json()["access_token"]
def upload_cloud(client: TestClient, token: str, **overrides):
data = {"cloud_type_id": "1", "is_hidden": "false"}
data.update(overrides)
return client.post(
"/api/v1/clouds",
headers=bearer(token),
files={"image": ("cloud.png", png_bytes(), "image/png")},
data=data,
)
def approve_cloud(client: TestClient, admin_tok: str, cloud_id: str) -> None:
r = client.patch(
"/api/v1/admin/clouds/status",
headers=bearer(admin_tok),
json={"ids": [cloud_id], "status": "approved"},
)
assert r.status_code == 200
# ---------------------------------------------------------------------------
# fixtures
# ---------------------------------------------------------------------------
async def _prepare_database() -> None: