287 lines
8.9 KiB
Python
287 lines
8.9 KiB
Python
import uuid
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from tests.conftest import (
|
|
admin_token,
|
|
approve_cloud,
|
|
bearer,
|
|
png_bytes,
|
|
register_and_confirm,
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# get profile
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_get_profile(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"prof-{uuid.uuid4().hex[:8]}@example.com",
|
|
"profpass1", "资料展示",
|
|
)
|
|
r = client.get(f"/api/v1/profiles/{info['user_id']}")
|
|
assert r.status_code == 200
|
|
assert r.json()["username"] == "资料展示"
|
|
|
|
|
|
def test_get_nonexistent_profile(client: TestClient) -> None:
|
|
r = client.get(f"/api/v1/profiles/{uuid.uuid4()}")
|
|
assert r.status_code == 404
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# update my profile
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_update_me(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"updme-{uuid.uuid4().hex[:8]}@example.com",
|
|
"updmepass", "原昵称",
|
|
)
|
|
r = client.patch(
|
|
"/api/v1/profiles/me",
|
|
headers=bearer(info["token"]),
|
|
json={"username": "新昵称"},
|
|
)
|
|
assert r.status_code == 200
|
|
assert r.json()["username"] == "新昵称"
|
|
|
|
|
|
def test_update_me_short_username(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"shortname-{uuid.uuid4().hex[:8]}@example.com",
|
|
"shortname", "短名字测试",
|
|
)
|
|
r = client.patch(
|
|
"/api/v1/profiles/me",
|
|
headers=bearer(info["token"]),
|
|
json={"username": "A"},
|
|
)
|
|
assert r.status_code == 422
|
|
|
|
|
|
def test_update_me_duplicate_username(client: TestClient, monkeypatch) -> None:
|
|
register_and_confirm(
|
|
client, monkeypatch,
|
|
f"dupname-u1-{uuid.uuid4().hex[:8]}@example.com",
|
|
"pass11112", "已占用的名字",
|
|
)
|
|
info2 = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"dupname-u2-{uuid.uuid4().hex[:8]}@example.com",
|
|
"pass22223", "第二人",
|
|
)
|
|
r = client.patch(
|
|
"/api/v1/profiles/me",
|
|
headers=bearer(info2["token"]),
|
|
json={"username": "已占用的名字"},
|
|
)
|
|
assert r.status_code == 409
|
|
assert "昵称" in r.json()["detail"]
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# get user clouds
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_get_user_clouds_public(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"pubcloud-{uuid.uuid4().hex[:8]}@example.com",
|
|
"pubcloud1", "公开云主",
|
|
)
|
|
ur = client.post(
|
|
"/api/v1/clouds",
|
|
headers=bearer(info["token"]),
|
|
files={"image": ("cloud.png", png_bytes(), "image/png")},
|
|
data={"cloud_type_id": "1", "is_hidden": "false"},
|
|
)
|
|
approve_cloud(client, admin_token(client), ur.json()["cloud"]["id"])
|
|
r = client.get(f"/api/v1/profiles/{info['user_id']}/clouds")
|
|
assert r.status_code == 200
|
|
assert r.json()["total"] >= 1
|
|
for item in r.json()["items"]:
|
|
assert item["status"] == "approved"
|
|
|
|
|
|
def test_get_user_clouds_as_owner(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"owncloud-{uuid.uuid4().hex[:8]}@example.com",
|
|
"owncloud1", "私有云主",
|
|
)
|
|
ur = client.post(
|
|
"/api/v1/clouds",
|
|
headers=bearer(info["token"]),
|
|
files={"image": ("cloud.png", png_bytes(), "image/png")},
|
|
data={"cloud_type_id": "1", "is_hidden": "false"},
|
|
)
|
|
approve_cloud(client, admin_token(client), ur.json()["cloud"]["id"])
|
|
r = client.get(
|
|
f"/api/v1/profiles/{info['user_id']}/clouds",
|
|
headers=bearer(info["token"]),
|
|
)
|
|
assert r.status_code == 200
|
|
assert r.json()["total"] >= 1
|
|
|
|
|
|
def test_get_nonexistent_user_clouds(client: TestClient) -> None:
|
|
r = client.get(f"/api/v1/profiles/{uuid.uuid4()}/clouds")
|
|
assert r.status_code == 404
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# stats (admin only)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_get_user_stats_admin(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"stats-{uuid.uuid4().hex[:8]}@example.com",
|
|
"statspass", "统计用户",
|
|
)
|
|
# upload one cloud and approve it, upload another pending
|
|
ur1 = client.post(
|
|
"/api/v1/clouds",
|
|
headers=bearer(info["token"]),
|
|
files={"image": ("cloud.png", png_bytes(), "image/png")},
|
|
data={"cloud_type_id": "1", "is_hidden": "false"},
|
|
)
|
|
approve_cloud(client, admin_token(client), ur1.json()["cloud"]["id"])
|
|
client.post(
|
|
"/api/v1/clouds",
|
|
headers=bearer(info["token"]),
|
|
files={"image": ("cloud.png", png_bytes(), "image/png")},
|
|
data={"cloud_type_id": "2", "is_hidden": "false"},
|
|
)
|
|
|
|
r = client.get(
|
|
f"/api/v1/profiles/{info['user_id']}/stats",
|
|
headers=bearer(admin_token(client)),
|
|
)
|
|
assert r.status_code == 200
|
|
body = r.json()
|
|
assert body["cloud_count"] == 2
|
|
assert body["public_cloud_count"] == 1
|
|
assert body["collection_count"] == 2
|
|
assert body["username"] == "统计用户"
|
|
|
|
|
|
def test_get_user_stats_non_admin(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"stats-na-{uuid.uuid4().hex[:8]}@example.com",
|
|
"statsnap", "非管理员统计",
|
|
)
|
|
r = client.get(
|
|
f"/api/v1/profiles/{info['user_id']}/stats",
|
|
headers=bearer(info["token"]),
|
|
)
|
|
assert r.status_code == 403
|
|
|
|
|
|
def test_get_user_stats_unauthenticated(client: TestClient) -> None:
|
|
r = client.get(f"/api/v1/profiles/{uuid.uuid4()}/stats")
|
|
assert r.status_code == 401
|
|
|
|
|
|
def test_get_user_stats_nonexistent(client: TestClient) -> None:
|
|
r = client.get(
|
|
f"/api/v1/profiles/{uuid.uuid4()}/stats",
|
|
headers=bearer(admin_token(client)),
|
|
)
|
|
assert r.status_code == 404
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# avatar
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_upload_avatar(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"avatar-{uuid.uuid4().hex[:8]}@example.com",
|
|
"avatarp12", "头像用户",
|
|
)
|
|
r = client.post(
|
|
"/api/v1/profiles/me/avatar",
|
|
headers=bearer(info["token"]),
|
|
files={"image": ("avatar.png", png_bytes(), "image/png")},
|
|
)
|
|
assert r.status_code == 200
|
|
body = r.json()
|
|
assert body["avatar_url"] is not None
|
|
assert "avatars/" in body["avatar_url"]
|
|
|
|
|
|
def test_replace_avatar(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"avat2-{uuid.uuid4().hex[:8]}@example.com",
|
|
"avat2p12", "换头像",
|
|
)
|
|
r1 = client.post(
|
|
"/api/v1/profiles/me/avatar",
|
|
headers=bearer(info["token"]),
|
|
files={"image": ("avatar.png", png_bytes(), "image/png")},
|
|
)
|
|
assert r1.status_code == 200
|
|
assert r1.json()["avatar_url"] is not None
|
|
|
|
r2 = client.post(
|
|
"/api/v1/profiles/me/avatar",
|
|
headers=bearer(info["token"]),
|
|
files={"image": ("avatar2.png", png_bytes(), "image/png")},
|
|
)
|
|
assert r2.status_code == 200
|
|
assert r2.json()["avatar_url"] is not None
|
|
|
|
|
|
def test_delete_avatar(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"avat3-{uuid.uuid4().hex[:8]}@example.com",
|
|
"avat3p12", "删头像",
|
|
)
|
|
client.post(
|
|
"/api/v1/profiles/me/avatar",
|
|
headers=bearer(info["token"]),
|
|
files={"image": ("avatar.png", png_bytes(), "image/png")},
|
|
)
|
|
r = client.delete("/api/v1/profiles/me/avatar", headers=bearer(info["token"]))
|
|
assert r.status_code == 200
|
|
assert r.json()["avatar_url"] is None
|
|
|
|
|
|
def test_delete_avatar_not_found(client: TestClient, monkeypatch) -> None:
|
|
info = register_and_confirm(
|
|
client, monkeypatch,
|
|
f"avat4-{uuid.uuid4().hex[:8]}@example.com",
|
|
"avat4p12", "没头像删",
|
|
)
|
|
r = client.delete("/api/v1/profiles/me/avatar", headers=bearer(info["token"]))
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_upload_avatar_unauthenticated(client: TestClient) -> None:
|
|
r = client.post(
|
|
"/api/v1/profiles/me/avatar",
|
|
files={"image": ("avatar.png", png_bytes(), "image/png")},
|
|
)
|
|
assert r.status_code == 401
|
|
|
|
|
|
def test_delete_avatar_unauthenticated(client: TestClient) -> None:
|
|
r = client.delete("/api/v1/profiles/me/avatar")
|
|
assert r.status_code == 401
|