"""Config类的单元测试"""
import os
from collections.abc import Generator
from pathlib import Path
from typing import Any
import pytest
import toml
from pytest_mock import MockerFixture
from apps.common.config import Config
from apps.common.singleton import SingletonMeta
from apps.schemas.config import ConfigModel
MOCK_CONFIG_DATA: dict[str, Any] = {
"deploy": {"mode": "local", "cookie": "domain", "data_dir": "/app/data"},
"login": {
"provider": "authhub",
"settings": {
"host": "http://localhost",
"host_inner": "http://localhost",
"login_api": "http://localhost/api/auth/login",
"app_id": "test_id",
"app_secret": "test_secret",
},
},
"embedding": {
"type": "openai",
"endpoint": "http://localhost",
"api_key": "test_key",
"model": "test_model",
},
"rag": {"rag_service": "http://localhost"},
"fastapi": {"domain": "localhost", "session_ttl": 30, "csrf": False},
"minio": {
"endpoint": "localhost:9000",
"access_key": "test_key",
"secret_key": "test_secret",
"secure": False,
},
"mongodb": {
"host": "localhost",
"port": 27017,
"user": "test_user",
"password": "test_password",
"database": "test_db",
},
"llm": {
"key": "test_key",
"endpoint": "http://localhost",
"model": "test_model",
"max_tokens": 8192,
"temperature": 0.7,
},
"function_call": {
"backend": "test_backend",
"model": "test_model",
"endpoint": "http://localhost",
"api_key": "test_key",
"max_tokens": 8192,
"temperature": 0.7,
},
"security": {
"half_key1": "test_key1",
"half_key2": "test_key2",
"half_key3": "test_key3",
"jwt_key": "test_jwt_key",
},
"check": {"enable": False, "words_list": ""},
"extra": {"sql_url": "http://localhost"},
}
@pytest.fixture(autouse=True)
def setup_teardown() -> Generator[None, None, None]:
"""测试前的准备工作和清理工作"""
SingletonMeta._instances.clear()
if "CONFIG" in os.environ:
del os.environ["CONFIG"]
if "PROD" in os.environ:
del os.environ["PROD"]
yield
SingletonMeta._instances.clear()
def test_init_with_default_config(mocker: MockerFixture) -> None:
"""测试使用默认配置文件路径初始化"""
mocker.patch("builtins.open", mocker.mock_open(read_data=toml.dumps(MOCK_CONFIG_DATA)))
config = Config()
assert isinstance(config._config, ConfigModel)
assert config._config.deploy.mode == "local"
def test_init_with_custom_config_path(mocker: MockerFixture) -> None:
"""测试使用自定义配置文件路径初始化"""
custom_path = "/custom/path/config.toml"
os.environ["CONFIG"] = custom_path
mocker.patch("builtins.open", mocker.mock_open(read_data=toml.dumps(MOCK_CONFIG_DATA)))
config = Config()
assert isinstance(config._config, ConfigModel)
assert config._config.deploy.mode == "local"
def test_init_with_prod_env(mocker: MockerFixture) -> None:
"""测试在PROD环境下初始化"""
os.environ["PROD"] = "true"
mocker.patch("builtins.open", mocker.mock_open(read_data=toml.dumps(MOCK_CONFIG_DATA)))
mock_unlink = mocker.patch.object(Path, "unlink")
config = Config()
assert isinstance(config._config, ConfigModel)
mock_unlink.assert_called_once()
def test_get_config(mocker: MockerFixture) -> None:
"""测试获取配置"""
mocker.patch("builtins.open", mocker.mock_open(read_data=toml.dumps(MOCK_CONFIG_DATA)))
config = Config()
config_copy = config.get_config()
assert isinstance(config_copy, ConfigModel)
assert config_copy is not config._config
if __name__ == "__main__":
pytest.main([__file__, "-v"])