Add unit tests for models and services
- Implemented unit tests for Object model including folder and file creation, properties, and path retrieval. - Added unit tests for Setting model covering creation, unique constraints, and type enumeration. - Created unit tests for User model focusing on user creation, uniqueness, and group relationships. - Developed unit tests for Login service to validate login functionality, including 2FA and token generation. - Added utility tests for JWT creation and verification, ensuring token integrity and expiration handling. - Implemented password utility tests for password generation, hashing, and TOTP verification.
This commit is contained in:
14
tests/fixtures/__init__.py
vendored
Normal file
14
tests/fixtures/__init__.py
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
测试数据工厂模块
|
||||
|
||||
提供便捷的测试数据创建工具,用于在测试中快速生成用户、用户组、对象等数据。
|
||||
"""
|
||||
from .users import UserFactory
|
||||
from .groups import GroupFactory
|
||||
from .objects import ObjectFactory
|
||||
|
||||
__all__ = [
|
||||
"UserFactory",
|
||||
"GroupFactory",
|
||||
"ObjectFactory",
|
||||
]
|
||||
202
tests/fixtures/groups.py
vendored
Normal file
202
tests/fixtures/groups.py
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
"""
|
||||
用户组测试数据工厂
|
||||
|
||||
提供创建测试用户组的便捷方法。
|
||||
"""
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
from models.group import Group, GroupOptions
|
||||
|
||||
|
||||
class GroupFactory:
|
||||
"""用户组工厂类,用于创建各种类型的测试用户组"""
|
||||
|
||||
@staticmethod
|
||||
async def create(
|
||||
session: AsyncSession,
|
||||
name: str | None = None,
|
||||
**kwargs
|
||||
) -> Group:
|
||||
"""
|
||||
创建用户组
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
name: 用户组名称(默认: test_group_{随机})
|
||||
**kwargs: 其他用户组字段
|
||||
|
||||
返回:
|
||||
Group: 创建的用户组实例
|
||||
"""
|
||||
import uuid
|
||||
|
||||
if name is None:
|
||||
name = f"test_group_{uuid.uuid4().hex[:8]}"
|
||||
|
||||
group = Group(
|
||||
name=name,
|
||||
max_storage=kwargs.get("max_storage", 1024 * 1024 * 1024 * 10), # 默认 10GB
|
||||
share_enabled=kwargs.get("share_enabled", True),
|
||||
web_dav_enabled=kwargs.get("web_dav_enabled", True),
|
||||
admin=kwargs.get("admin", False),
|
||||
speed_limit=kwargs.get("speed_limit", 0),
|
||||
)
|
||||
|
||||
group = await group.save(session)
|
||||
|
||||
# 如果提供了选项参数,创建 GroupOptions
|
||||
if kwargs.get("create_options", False):
|
||||
options = GroupOptions(
|
||||
group_id=group.id,
|
||||
share_download=kwargs.get("share_download", True),
|
||||
share_free=kwargs.get("share_free", False),
|
||||
relocate=kwargs.get("relocate", True),
|
||||
source_batch=kwargs.get("source_batch", 10),
|
||||
select_node=kwargs.get("select_node", False),
|
||||
advance_delete=kwargs.get("advance_delete", False),
|
||||
)
|
||||
await options.save(session)
|
||||
|
||||
return group
|
||||
|
||||
@staticmethod
|
||||
async def create_admin_group(
|
||||
session: AsyncSession,
|
||||
name: str | None = None
|
||||
) -> Group:
|
||||
"""
|
||||
创建管理员组
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
name: 用户组名称(默认: admin_group_{随机})
|
||||
|
||||
返回:
|
||||
Group: 创建的管理员组实例
|
||||
"""
|
||||
import uuid
|
||||
|
||||
if name is None:
|
||||
name = f"admin_group_{uuid.uuid4().hex[:8]}"
|
||||
|
||||
admin_group = Group(
|
||||
name=name,
|
||||
max_storage=0, # 无限制
|
||||
share_enabled=True,
|
||||
web_dav_enabled=True,
|
||||
admin=True,
|
||||
speed_limit=0,
|
||||
)
|
||||
|
||||
admin_group = await admin_group.save(session)
|
||||
|
||||
# 创建管理员组选项
|
||||
admin_options = GroupOptions(
|
||||
group_id=admin_group.id,
|
||||
share_download=True,
|
||||
share_free=True,
|
||||
relocate=True,
|
||||
source_batch=100,
|
||||
select_node=True,
|
||||
advance_delete=True,
|
||||
archive_download=True,
|
||||
archive_task=True,
|
||||
webdav_proxy=True,
|
||||
aria2=True,
|
||||
redirected_source=True,
|
||||
)
|
||||
await admin_options.save(session)
|
||||
|
||||
return admin_group
|
||||
|
||||
@staticmethod
|
||||
async def create_limited_group(
|
||||
session: AsyncSession,
|
||||
max_storage: int,
|
||||
name: str | None = None
|
||||
) -> Group:
|
||||
"""
|
||||
创建有存储限制的用户组
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
max_storage: 最大存储空间(字节)
|
||||
name: 用户组名称(默认: limited_group_{随机})
|
||||
|
||||
返回:
|
||||
Group: 创建的用户组实例
|
||||
"""
|
||||
import uuid
|
||||
|
||||
if name is None:
|
||||
name = f"limited_group_{uuid.uuid4().hex[:8]}"
|
||||
|
||||
limited_group = Group(
|
||||
name=name,
|
||||
max_storage=max_storage,
|
||||
share_enabled=True,
|
||||
web_dav_enabled=False,
|
||||
admin=False,
|
||||
speed_limit=1024, # 1MB/s
|
||||
)
|
||||
|
||||
limited_group = await limited_group.save(session)
|
||||
|
||||
# 创建限制组选项
|
||||
limited_options = GroupOptions(
|
||||
group_id=limited_group.id,
|
||||
share_download=False,
|
||||
share_free=False,
|
||||
relocate=False,
|
||||
source_batch=0,
|
||||
select_node=False,
|
||||
advance_delete=False,
|
||||
)
|
||||
await limited_options.save(session)
|
||||
|
||||
return limited_group
|
||||
|
||||
@staticmethod
|
||||
async def create_free_group(
|
||||
session: AsyncSession,
|
||||
name: str | None = None
|
||||
) -> Group:
|
||||
"""
|
||||
创建免费用户组(无特殊权限)
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
name: 用户组名称(默认: free_group_{随机})
|
||||
|
||||
返回:
|
||||
Group: 创建的用户组实例
|
||||
"""
|
||||
import uuid
|
||||
|
||||
if name is None:
|
||||
name = f"free_group_{uuid.uuid4().hex[:8]}"
|
||||
|
||||
free_group = Group(
|
||||
name=name,
|
||||
max_storage=1024 * 1024 * 1024, # 1GB
|
||||
share_enabled=False,
|
||||
web_dav_enabled=False,
|
||||
admin=False,
|
||||
speed_limit=512, # 512KB/s
|
||||
)
|
||||
|
||||
free_group = await free_group.save(session)
|
||||
|
||||
# 创建免费组选项
|
||||
free_options = GroupOptions(
|
||||
group_id=free_group.id,
|
||||
share_download=False,
|
||||
share_free=False,
|
||||
relocate=False,
|
||||
source_batch=0,
|
||||
select_node=False,
|
||||
advance_delete=False,
|
||||
)
|
||||
await free_options.save(session)
|
||||
|
||||
return free_group
|
||||
364
tests/fixtures/objects.py
vendored
Normal file
364
tests/fixtures/objects.py
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
"""
|
||||
对象(文件/目录)测试数据工厂
|
||||
|
||||
提供创建测试对象的便捷方法。
|
||||
"""
|
||||
from uuid import UUID
|
||||
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
from models.object import Object, ObjectType
|
||||
from models.user import User
|
||||
|
||||
|
||||
class ObjectFactory:
|
||||
"""对象工厂类,用于创建测试文件和目录"""
|
||||
|
||||
@staticmethod
|
||||
async def create_folder(
|
||||
session: AsyncSession,
|
||||
owner_id: UUID,
|
||||
policy_id: UUID,
|
||||
parent_id: UUID | None = None,
|
||||
name: str | None = None,
|
||||
**kwargs
|
||||
) -> Object:
|
||||
"""
|
||||
创建目录
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
owner_id: 所有者UUID
|
||||
policy_id: 存储策略UUID
|
||||
parent_id: 父目录UUID(None 表示根目录)
|
||||
name: 目录名称(默认: folder_{随机})
|
||||
**kwargs: 其他对象字段
|
||||
|
||||
返回:
|
||||
Object: 创建的目录实例
|
||||
"""
|
||||
import uuid
|
||||
|
||||
if name is None:
|
||||
name = f"folder_{uuid.uuid4().hex[:8]}"
|
||||
|
||||
folder = Object(
|
||||
name=name,
|
||||
type=ObjectType.FOLDER,
|
||||
parent_id=parent_id,
|
||||
owner_id=owner_id,
|
||||
policy_id=policy_id,
|
||||
size=0,
|
||||
password=kwargs.get("password"),
|
||||
)
|
||||
|
||||
folder = await folder.save(session)
|
||||
return folder
|
||||
|
||||
@staticmethod
|
||||
async def create_file(
|
||||
session: AsyncSession,
|
||||
owner_id: UUID,
|
||||
policy_id: UUID,
|
||||
parent_id: UUID,
|
||||
name: str | None = None,
|
||||
size: int = 1024,
|
||||
**kwargs
|
||||
) -> Object:
|
||||
"""
|
||||
创建文件
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
owner_id: 所有者UUID
|
||||
policy_id: 存储策略UUID
|
||||
parent_id: 父目录UUID
|
||||
name: 文件名称(默认: file_{随机}.txt)
|
||||
size: 文件大小(字节,默认: 1024)
|
||||
**kwargs: 其他对象字段
|
||||
|
||||
返回:
|
||||
Object: 创建的文件实例
|
||||
"""
|
||||
import uuid
|
||||
|
||||
if name is None:
|
||||
name = f"file_{uuid.uuid4().hex[:8]}.txt"
|
||||
|
||||
file = Object(
|
||||
name=name,
|
||||
type=ObjectType.FILE,
|
||||
parent_id=parent_id,
|
||||
owner_id=owner_id,
|
||||
policy_id=policy_id,
|
||||
size=size,
|
||||
source_name=kwargs.get("source_name", name),
|
||||
upload_session_id=kwargs.get("upload_session_id"),
|
||||
file_metadata=kwargs.get("file_metadata"),
|
||||
password=kwargs.get("password"),
|
||||
)
|
||||
|
||||
file = await file.save(session)
|
||||
return file
|
||||
|
||||
@staticmethod
|
||||
async def create_user_root(
|
||||
session: AsyncSession,
|
||||
user: User,
|
||||
policy_id: UUID
|
||||
) -> Object:
|
||||
"""
|
||||
为用户创建根目录
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
user: 用户实例
|
||||
policy_id: 存储策略UUID
|
||||
|
||||
返回:
|
||||
Object: 创建的根目录实例
|
||||
"""
|
||||
root = Object(
|
||||
name=user.username,
|
||||
type=ObjectType.FOLDER,
|
||||
parent_id=None,
|
||||
owner_id=user.id,
|
||||
policy_id=policy_id,
|
||||
size=0,
|
||||
)
|
||||
|
||||
root = await root.save(session)
|
||||
return root
|
||||
|
||||
@staticmethod
|
||||
async def create_directory_tree(
|
||||
session: AsyncSession,
|
||||
owner_id: UUID,
|
||||
policy_id: UUID,
|
||||
root_id: UUID,
|
||||
depth: int = 2,
|
||||
folders_per_level: int = 2
|
||||
) -> list[Object]:
|
||||
"""
|
||||
创建目录树结构(递归)
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
owner_id: 所有者UUID
|
||||
policy_id: 存储策略UUID
|
||||
root_id: 根目录UUID
|
||||
depth: 树的深度(默认: 2)
|
||||
folders_per_level: 每层的目录数量(默认: 2)
|
||||
|
||||
返回:
|
||||
list[Object]: 创建的所有目录列表
|
||||
"""
|
||||
folders = []
|
||||
|
||||
async def create_level(parent_id: UUID, current_depth: int):
|
||||
if current_depth <= 0:
|
||||
return
|
||||
|
||||
for i in range(folders_per_level):
|
||||
folder = await ObjectFactory.create_folder(
|
||||
session=session,
|
||||
owner_id=owner_id,
|
||||
policy_id=policy_id,
|
||||
parent_id=parent_id,
|
||||
name=f"level_{current_depth}_folder_{i}"
|
||||
)
|
||||
folders.append(folder)
|
||||
|
||||
# 递归创建子目录
|
||||
await create_level(folder.id, current_depth - 1)
|
||||
|
||||
await create_level(root_id, depth)
|
||||
return folders
|
||||
|
||||
@staticmethod
|
||||
async def create_files_in_folder(
|
||||
session: AsyncSession,
|
||||
owner_id: UUID,
|
||||
policy_id: UUID,
|
||||
parent_id: UUID,
|
||||
count: int = 5,
|
||||
size_range: tuple[int, int] = (1024, 1024 * 1024)
|
||||
) -> list[Object]:
|
||||
"""
|
||||
在指定目录中创建多个文件
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
owner_id: 所有者UUID
|
||||
policy_id: 存储策略UUID
|
||||
parent_id: 父目录UUID
|
||||
count: 文件数量(默认: 5)
|
||||
size_range: 文件大小范围(字节,默认: 1KB - 1MB)
|
||||
|
||||
返回:
|
||||
list[Object]: 创建的所有文件列表
|
||||
"""
|
||||
import random
|
||||
|
||||
files = []
|
||||
extensions = [".txt", ".pdf", ".jpg", ".png", ".mp4", ".zip", ".doc"]
|
||||
|
||||
for i in range(count):
|
||||
ext = random.choice(extensions)
|
||||
size = random.randint(size_range[0], size_range[1])
|
||||
|
||||
file = await ObjectFactory.create_file(
|
||||
session=session,
|
||||
owner_id=owner_id,
|
||||
policy_id=policy_id,
|
||||
parent_id=parent_id,
|
||||
name=f"test_file_{i}{ext}",
|
||||
size=size
|
||||
)
|
||||
files.append(file)
|
||||
|
||||
return files
|
||||
|
||||
@staticmethod
|
||||
async def create_large_file(
|
||||
session: AsyncSession,
|
||||
owner_id: UUID,
|
||||
policy_id: UUID,
|
||||
parent_id: UUID,
|
||||
size_mb: int = 100,
|
||||
name: str | None = None
|
||||
) -> Object:
|
||||
"""
|
||||
创建大文件(用于测试存储限制)
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
owner_id: 所有者UUID
|
||||
policy_id: 存储策略UUID
|
||||
parent_id: 父目录UUID
|
||||
size_mb: 文件大小(MB,默认: 100)
|
||||
name: 文件名称(默认: large_file_{size_mb}MB.bin)
|
||||
|
||||
返回:
|
||||
Object: 创建的大文件实例
|
||||
"""
|
||||
if name is None:
|
||||
name = f"large_file_{size_mb}MB.bin"
|
||||
|
||||
size_bytes = size_mb * 1024 * 1024
|
||||
|
||||
file = await ObjectFactory.create_file(
|
||||
session=session,
|
||||
owner_id=owner_id,
|
||||
policy_id=policy_id,
|
||||
parent_id=parent_id,
|
||||
name=name,
|
||||
size=size_bytes
|
||||
)
|
||||
|
||||
return file
|
||||
|
||||
@staticmethod
|
||||
async def create_nested_structure(
|
||||
session: AsyncSession,
|
||||
owner_id: UUID,
|
||||
policy_id: UUID,
|
||||
root_id: UUID
|
||||
) -> dict[str, UUID]:
|
||||
"""
|
||||
创建嵌套的目录和文件结构(用于测试路径解析)
|
||||
|
||||
创建结构:
|
||||
root/
|
||||
├── documents/
|
||||
│ ├── work/
|
||||
│ │ ├── report.pdf
|
||||
│ │ └── presentation.pptx
|
||||
│ └── personal/
|
||||
│ └── notes.txt
|
||||
└── media/
|
||||
├── images/
|
||||
│ ├── photo1.jpg
|
||||
│ └── photo2.png
|
||||
└── videos/
|
||||
└── clip.mp4
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
owner_id: 所有者UUID
|
||||
policy_id: 存储策略UUID
|
||||
root_id: 根目录UUID
|
||||
|
||||
返回:
|
||||
dict[str, UUID]: 创建的对象ID字典
|
||||
"""
|
||||
result = {"root": root_id}
|
||||
|
||||
# 创建 documents 目录
|
||||
documents = await ObjectFactory.create_folder(
|
||||
session, owner_id, policy_id, root_id, "documents"
|
||||
)
|
||||
result["documents"] = documents.id
|
||||
|
||||
# 创建 documents/work 目录
|
||||
work = await ObjectFactory.create_folder(
|
||||
session, owner_id, policy_id, documents.id, "work"
|
||||
)
|
||||
result["work"] = work.id
|
||||
|
||||
# 创建 documents/work 下的文件
|
||||
report = await ObjectFactory.create_file(
|
||||
session, owner_id, policy_id, work.id, "report.pdf", 1024 * 100
|
||||
)
|
||||
result["report"] = report.id
|
||||
|
||||
presentation = await ObjectFactory.create_file(
|
||||
session, owner_id, policy_id, work.id, "presentation.pptx", 1024 * 500
|
||||
)
|
||||
result["presentation"] = presentation.id
|
||||
|
||||
# 创建 documents/personal 目录
|
||||
personal = await ObjectFactory.create_folder(
|
||||
session, owner_id, policy_id, documents.id, "personal"
|
||||
)
|
||||
result["personal"] = personal.id
|
||||
|
||||
notes = await ObjectFactory.create_file(
|
||||
session, owner_id, policy_id, personal.id, "notes.txt", 1024
|
||||
)
|
||||
result["notes"] = notes.id
|
||||
|
||||
# 创建 media 目录
|
||||
media = await ObjectFactory.create_folder(
|
||||
session, owner_id, policy_id, root_id, "media"
|
||||
)
|
||||
result["media"] = media.id
|
||||
|
||||
# 创建 media/images 目录
|
||||
images = await ObjectFactory.create_folder(
|
||||
session, owner_id, policy_id, media.id, "images"
|
||||
)
|
||||
result["images"] = images.id
|
||||
|
||||
photo1 = await ObjectFactory.create_file(
|
||||
session, owner_id, policy_id, images.id, "photo1.jpg", 1024 * 200
|
||||
)
|
||||
result["photo1"] = photo1.id
|
||||
|
||||
photo2 = await ObjectFactory.create_file(
|
||||
session, owner_id, policy_id, images.id, "photo2.png", 1024 * 300
|
||||
)
|
||||
result["photo2"] = photo2.id
|
||||
|
||||
# 创建 media/videos 目录
|
||||
videos = await ObjectFactory.create_folder(
|
||||
session, owner_id, policy_id, media.id, "videos"
|
||||
)
|
||||
result["videos"] = videos.id
|
||||
|
||||
clip = await ObjectFactory.create_file(
|
||||
session, owner_id, policy_id, videos.id, "clip.mp4", 1024 * 1024 * 10
|
||||
)
|
||||
result["clip"] = clip.id
|
||||
|
||||
return result
|
||||
179
tests/fixtures/users.py
vendored
Normal file
179
tests/fixtures/users.py
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
"""
|
||||
用户测试数据工厂
|
||||
|
||||
提供创建测试用户的便捷方法。
|
||||
"""
|
||||
from uuid import UUID
|
||||
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
from models.user import User
|
||||
from utils.password.pwd import Password
|
||||
|
||||
|
||||
class UserFactory:
|
||||
"""用户工厂类,用于创建各种类型的测试用户"""
|
||||
|
||||
@staticmethod
|
||||
async def create(
|
||||
session: AsyncSession,
|
||||
group_id: UUID,
|
||||
username: str | None = None,
|
||||
password: str | None = None,
|
||||
**kwargs
|
||||
) -> User:
|
||||
"""
|
||||
创建普通用户
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
group_id: 用户组UUID
|
||||
username: 用户名(默认: test_user_{随机})
|
||||
password: 明文密码(默认: password123)
|
||||
**kwargs: 其他用户字段
|
||||
|
||||
返回:
|
||||
User: 创建的用户实例
|
||||
"""
|
||||
import uuid
|
||||
|
||||
if username is None:
|
||||
username = f"test_user_{uuid.uuid4().hex[:8]}"
|
||||
|
||||
if password is None:
|
||||
password = "password123"
|
||||
|
||||
user = User(
|
||||
username=username,
|
||||
nickname=kwargs.get("nickname", username),
|
||||
password=Password.hash(password),
|
||||
status=kwargs.get("status", True),
|
||||
storage=kwargs.get("storage", 0),
|
||||
score=kwargs.get("score", 100),
|
||||
group_id=group_id,
|
||||
two_factor=kwargs.get("two_factor"),
|
||||
avatar=kwargs.get("avatar", "default"),
|
||||
group_expires=kwargs.get("group_expires"),
|
||||
theme=kwargs.get("theme", "system"),
|
||||
language=kwargs.get("language", "zh-CN"),
|
||||
timezone=kwargs.get("timezone", 8),
|
||||
previous_group_id=kwargs.get("previous_group_id"),
|
||||
)
|
||||
|
||||
user = await user.save(session)
|
||||
return user
|
||||
|
||||
@staticmethod
|
||||
async def create_admin(
|
||||
session: AsyncSession,
|
||||
admin_group_id: UUID,
|
||||
username: str | None = None,
|
||||
password: str | None = None
|
||||
) -> User:
|
||||
"""
|
||||
创建管理员用户
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
admin_group_id: 管理员组UUID
|
||||
username: 用户名(默认: admin_{随机})
|
||||
password: 明文密码(默认: admin_password)
|
||||
|
||||
返回:
|
||||
User: 创建的管理员用户实例
|
||||
"""
|
||||
import uuid
|
||||
|
||||
if username is None:
|
||||
username = f"admin_{uuid.uuid4().hex[:8]}"
|
||||
|
||||
if password is None:
|
||||
password = "admin_password"
|
||||
|
||||
admin = User(
|
||||
username=username,
|
||||
nickname=f"管理员 {username}",
|
||||
password=Password.hash(password),
|
||||
status=True,
|
||||
storage=0,
|
||||
score=9999,
|
||||
group_id=admin_group_id,
|
||||
avatar="default",
|
||||
)
|
||||
|
||||
admin = await admin.save(session)
|
||||
return admin
|
||||
|
||||
@staticmethod
|
||||
async def create_banned(
|
||||
session: AsyncSession,
|
||||
group_id: UUID,
|
||||
username: str | None = None
|
||||
) -> User:
|
||||
"""
|
||||
创建被封禁用户
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
group_id: 用户组UUID
|
||||
username: 用户名(默认: banned_user_{随机})
|
||||
|
||||
返回:
|
||||
User: 创建的被封禁用户实例
|
||||
"""
|
||||
import uuid
|
||||
|
||||
if username is None:
|
||||
username = f"banned_user_{uuid.uuid4().hex[:8]}"
|
||||
|
||||
banned_user = User(
|
||||
username=username,
|
||||
nickname=f"封禁用户 {username}",
|
||||
password=Password.hash("banned_password"),
|
||||
status=False, # 封禁状态
|
||||
storage=0,
|
||||
score=0,
|
||||
group_id=group_id,
|
||||
avatar="default",
|
||||
)
|
||||
|
||||
banned_user = await banned_user.save(session)
|
||||
return banned_user
|
||||
|
||||
@staticmethod
|
||||
async def create_with_storage(
|
||||
session: AsyncSession,
|
||||
group_id: UUID,
|
||||
storage_bytes: int,
|
||||
username: str | None = None
|
||||
) -> User:
|
||||
"""
|
||||
创建已使用指定存储空间的用户
|
||||
|
||||
参数:
|
||||
session: 数据库会话
|
||||
group_id: 用户组UUID
|
||||
storage_bytes: 已使用的存储空间(字节)
|
||||
username: 用户名(默认: storage_user_{随机})
|
||||
|
||||
返回:
|
||||
User: 创建的用户实例
|
||||
"""
|
||||
import uuid
|
||||
|
||||
if username is None:
|
||||
username = f"storage_user_{uuid.uuid4().hex[:8]}"
|
||||
|
||||
user = User(
|
||||
username=username,
|
||||
nickname=username,
|
||||
password=Password.hash("password123"),
|
||||
status=True,
|
||||
storage=storage_bytes,
|
||||
score=100,
|
||||
group_id=group_id,
|
||||
avatar="default",
|
||||
)
|
||||
|
||||
user = await user.save(session)
|
||||
return user
|
||||
Reference in New Issue
Block a user