Files
AstrBot/tests/dashboard/conftest.py

77 lines
2.7 KiB
Python

"""Shared fixtures for dashboard API tests."""
import asyncio
import os
import pytest
import pytest_asyncio
from quart import Quart
from astrbot.core import LogBroker
from astrbot.core.core_lifecycle import AstrBotCoreLifecycle
from astrbot.core.db.sqlite import SQLiteDatabase
from astrbot.dashboard.server import AstrBotDashboard
@pytest_asyncio.fixture(scope="module")
async def core_lifecycle_td(tmp_path_factory):
"""Creates and initializes a core lifecycle instance with a temporary database."""
# Set the global config password to the HASH of "astrbot" so auth works
from astrbot.core import astrbot_config as global_cfg
from astrbot.core.utils.auth_password import hash_dashboard_password
global_cfg["dashboard"]["password"] = hash_dashboard_password("astrbot")
global_cfg["dashboard"]["username"] = "astrbot"
tmp_root = tmp_path_factory.mktemp("astrbot_root")
tmp_db_path = tmp_root / "test_data_v3.db"
db = SQLiteDatabase(str(tmp_db_path))
log_broker = LogBroker()
core_lifecycle = AstrBotCoreLifecycle(log_broker, db)
await core_lifecycle.initialize()
# Mark runtime as ready so the dashboard stops returning 503.
# In production ``start()`` triggers this; in tests we skip the full startup.
core_lifecycle.runtime_ready = True
core_lifecycle.runtime_ready_event.set()
try:
yield core_lifecycle
finally:
try:
_stop_res = core_lifecycle.stop()
if asyncio.iscoroutine(_stop_res):
await _stop_res
except Exception:
pass
@pytest.fixture(scope="module")
def app(core_lifecycle_td: AstrBotCoreLifecycle):
"""Creates a Quart app instance for testing."""
shutdown_event = asyncio.Event()
server = AstrBotDashboard(core_lifecycle_td, core_lifecycle_td.db, shutdown_event)
return server.app
def _resolve_dashboard_password(core_lifecycle_td: AstrBotCoreLifecycle) -> str:
"""Return the raw password (not hash) for the test config."""
from astrbot.core.utils.auth_password import DEFAULT_DASHBOARD_PASSWORD
return DEFAULT_DASHBOARD_PASSWORD
@pytest_asyncio.fixture(scope="module")
async def authenticated_header(app: Quart, core_lifecycle_td: AstrBotCoreLifecycle):
"""Handles login and returns an authenticated header."""
test_client = app.test_client()
response = await test_client.post(
"/api/auth/login",
json={
"username": core_lifecycle_td.astrbot_config["dashboard"]["username"],
"password": _resolve_dashboard_password(core_lifecycle_td),
},
)
data = await response.get_json()
assert data["status"] == "ok", str(data)
token = data["data"]["token"]
return {"Authorization": f"Bearer {token}"}