统一测试辅助函数到 conftest.py,消除代码重复
This commit is contained in:
+103
-14
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user