Files
FastapiAdmin/backend/tests/test_unit.py
T
zhangtao 53d2a9d13e chore: cleanup old frontend code and update project configs
This commit removes the deprecated frontend/web-old directory, updates various project configuration files including tsconfig, vite config, environment variables, and backend data models. It also fixes several API paths, adds tenant awareness to multiple models, and makes minor UI adjustments.
2026-05-27 01:12:03 +08:00

205 lines
6.9 KiB
Python

"""多租户多模块纯单元测试(不依赖数据库连接)。"""
import pytest
# ==================== 01. 租户 ContextVar ====================
class TestTenantContextVar:
"""租户上下文变量读写与清理。"""
def test_initially_none(self) -> None:
from app.core.tenant import get_current_tenant_id, get_is_super_admin
assert get_current_tenant_id() is None
assert get_is_super_admin() is False
def test_set_and_get(self) -> None:
from app.core.tenant import (
clear_current_tenant,
get_current_tenant_id,
get_is_super_admin,
set_current_tenant,
)
set_current_tenant(42, True)
assert get_current_tenant_id() == 42
assert get_is_super_admin() is True
clear_current_tenant()
assert get_current_tenant_id() is None
# ==================== 02. ORM 模型定义 ====================
class TestModels:
"""核心业务模型表名与字段完整性。"""
def test_tenant_model(self) -> None:
from app.api.v1.module_system.tenant.model import TenantModel
assert TenantModel.__tablename__ == "sys_tenant"
assert hasattr(TenantModel, "name")
assert hasattr(TenantModel, "code")
assert hasattr(TenantModel, "status")
assert hasattr(TenantModel, "end_time")
def test_tenant_quota_model(self) -> None:
from app.api.v1.module_system.tenant.model import TenantQuotaModel
assert TenantQuotaModel.__tablename__ == "sys_tenant_quota"
assert hasattr(TenantQuotaModel, "max_users")
assert hasattr(TenantQuotaModel, "max_roles")
def test_tenant_config_model(self) -> None:
from app.api.v1.module_system.tenant.model import TenantConfigModel
assert TenantConfigModel.__tablename__ == "sys_tenant_config"
assert hasattr(TenantConfigModel, "config_key")
def test_tenant_menu_model(self) -> None:
from app.api.v1.module_system.tenant.model import TenantMenuModel
assert TenantMenuModel.__tablename__ == "sys_tenant_menu"
assert hasattr(TenantMenuModel, "menu_id")
def test_tenant_user_model(self) -> None:
from app.api.v1.module_system.tenant.model import TenantUserModel
assert TenantUserModel.__tablename__ == "sys_user_tenant"
assert hasattr(TenantUserModel, "role")
assert hasattr(TenantUserModel, "is_default")
def test_user_model_has_tenant_id(self) -> None:
from app.api.v1.module_system.user.model import UserModel
assert hasattr(UserModel, "tenant_id")
assert hasattr(UserModel, "is_superuser")
def test_role_model_has_tenant_id(self) -> None:
from app.api.v1.module_system.role.model import RoleModel
assert hasattr(RoleModel, "tenant_id")
assert hasattr(RoleModel, "menus")
def test_menu_model_has_tenant_id(self) -> None:
from app.api.v1.module_system.menu.model import MenuModel
assert hasattr(MenuModel, "tenant_id")
assert hasattr(MenuModel, "type")
def test_notice_model(self) -> None:
from app.api.v1.module_system.notice.model import NoticeModel
assert NoticeModel.__tablename__ == "sys_notice"
assert hasattr(NoticeModel, "notice_title")
assert hasattr(NoticeModel, "status")
def test_plugin_model(self) -> None:
from app.api.v1.module_system.plugin.model import PluginModel
assert PluginModel.__tablename__ == "sys_plugin"
assert hasattr(PluginModel, "code")
def test_tenant_plugin_model(self) -> None:
from app.api.v1.module_system.plugin.model import TenantPluginModel
assert TenantPluginModel.__tablename__ == "sys_tenant_plugin"
def test_ticket_model(self) -> None:
from app.plugin.module_ticket.ticket.model import TicketModel
assert TicketModel.__tablename__ == "sys_ticket"
assert hasattr(TicketModel, "ticket_type")
assert hasattr(TicketModel, "reply")
# ==================== 03. Pydantic Schema ====================
class TestSchemas:
"""请求/响应Schema字段验证。"""
def test_tenant_create_schema(self) -> None:
from app.api.v1.module_system.tenant.schema import TenantCreateSchema
s = TenantCreateSchema(name="test", code="test001", status="0")
assert s.name == "test"
assert s.code == "test001"
def test_tenant_update_schema_partial(self) -> None:
from app.api.v1.module_system.tenant.schema import TenantUpdateSchema
s = TenantUpdateSchema(name="renamed")
assert s.name == "renamed"
assert s.code is None # 未传则为 None
def test_tenant_quota_schema_validation(self) -> None:
from app.api.v1.module_system.tenant.schema import TenantQuotaUpdateSchema
s = TenantQuotaUpdateSchema(max_users=100, max_roles=30)
assert s.max_users == 100
# 负数应被拒绝
with pytest.raises(Exception):
TenantQuotaUpdateSchema(max_users=-1)
def test_ticket_schema(self) -> None:
from app.plugin.module_ticket.ticket.schema import TicketCreateSchema
s = TicketCreateSchema(title="test", content="content", ticket_type="suggestion")
assert s.title == "test"
assert s.ticket_type == "suggestion"
def test_menu_type_enum(self) -> None:
"""菜单类型: 1=目录 2=菜单 3=按钮 4=链接"""
from app.api.v1.module_system.menu.model import MenuModel
assert hasattr(MenuModel, "type")
# type 是 int 字段
# ==================== 04. 配置类 ====================
class TestSettings:
"""配置默认值与环境变量覆盖。"""
def test_settings_defaults(self) -> None:
from app.config.setting import settings
assert settings.DATABASE_HOST
assert settings.DATABASE_PORT > 0
assert settings.SERVER_PORT > 0
def test_redis_config(self) -> None:
from app.config.setting import settings
assert isinstance(settings.REDIS_ENABLE, bool)
assert settings.REDIS_PORT == 6379
def test_database_password_empty_by_default(self) -> None:
"""密码默认值为空,需通过 .env 或环境变量提供。"""
from app.config.setting import Settings
# 检查字段默认值(不依赖运行时环境变量)
assert Settings.model_fields["DATABASE_PASSWORD"].default == ""
# ==================== 05. 常量与枚举 ====================
class TestEnums:
"""业务枚举值完整性。"""
def test_status_operate_enum(self) -> None:
from app.common.enums import BusinessType
assert hasattr(BusinessType, "OTHER")
def test_menu_type_values(self) -> None:
"""type: 1=目录 2=菜单 3=按钮 4=链接"""
from app.api.v1.module_system.menu.model import MenuModel
assert MenuModel.__tablename__ == "sys_menu"
# type 字段是 int 类型
col = next((c for c in MenuModel.__table__.columns if c.name == "type"), None)
assert col is not None