更新
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
|
||||
BACKEND_DIR = Path(__file__).resolve().parents[1]
|
||||
os.environ["KEFU_DB_TYPE"] = "sqlite"
|
||||
os.environ["KEFU_DATABASE_URL"] = ""
|
||||
os.environ["KEFU_DB_PATH"] = str(BACKEND_DIR / "kefu.db")
|
||||
if str(BACKEND_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(BACKEND_DIR))
|
||||
|
||||
import main
|
||||
from models.database import Base
|
||||
from models.models import Account
|
||||
|
||||
|
||||
class _CountResult:
|
||||
def __init__(self, count: int):
|
||||
self.count = count
|
||||
|
||||
def scalar_one(self):
|
||||
return self.count
|
||||
|
||||
|
||||
class _RowsResult:
|
||||
def __init__(self, rows):
|
||||
self.rows = list(rows)
|
||||
|
||||
def scalars(self):
|
||||
return self
|
||||
|
||||
def all(self):
|
||||
return list(self.rows)
|
||||
|
||||
|
||||
class AccountPaginationTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_paginated_list_counts_then_loads_only_current_page(self):
|
||||
page_rows = [
|
||||
SimpleNamespace(id=10, status="offline"),
|
||||
SimpleNamespace(id=11, status="online"),
|
||||
]
|
||||
db = SimpleNamespace(
|
||||
execute=AsyncMock(
|
||||
side_effect=[
|
||||
_CountResult(392),
|
||||
_RowsResult(page_rows),
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
with (
|
||||
patch.object(main.manager, "is_running", side_effect=[False, True]),
|
||||
patch.object(
|
||||
main,
|
||||
"_build_account_response",
|
||||
side_effect=lambda account: {"id": account.id, "status": account.status},
|
||||
) as build_response,
|
||||
):
|
||||
response = await main.get_accounts(
|
||||
page=20,
|
||||
page_size=20,
|
||||
q=None,
|
||||
status=None,
|
||||
db=db,
|
||||
user=SimpleNamespace(id=1, role="admin"),
|
||||
)
|
||||
|
||||
self.assertEqual(db.execute.await_count, 2)
|
||||
self.assertEqual(response["total"], 392)
|
||||
self.assertEqual(response["page"], 20)
|
||||
self.assertEqual(response["page_size"], 20)
|
||||
self.assertEqual([item["id"] for item in response["items"]], [10, 11])
|
||||
self.assertEqual(build_response.call_count, 2)
|
||||
|
||||
count_sql = str(db.execute.await_args_list[0].args[0]).upper()
|
||||
page_sql = str(db.execute.await_args_list[1].args[0]).upper()
|
||||
self.assertIn("COUNT", count_sql)
|
||||
self.assertNotIn(" LIMIT ", count_sql)
|
||||
self.assertIn(" LIMIT ", page_sql)
|
||||
self.assertIn(" OFFSET ", page_sql)
|
||||
|
||||
async def test_status_filter_uses_effective_runtime_worker_state(self):
|
||||
engine = create_async_engine("sqlite+aiosqlite:///:memory:")
|
||||
async with engine.begin() as connection:
|
||||
await connection.run_sync(Base.metadata.create_all)
|
||||
session_factory = sessionmaker(
|
||||
engine,
|
||||
class_=AsyncSession,
|
||||
expire_on_commit=False,
|
||||
)
|
||||
original_workers = main.manager.workers
|
||||
main.manager.workers = {
|
||||
1001: SimpleNamespace(is_running=True),
|
||||
1002: SimpleNamespace(is_running=False),
|
||||
}
|
||||
try:
|
||||
async with session_factory() as db:
|
||||
db.add_all(
|
||||
[
|
||||
Account(id=1001, status="offline"),
|
||||
Account(id=1002, status="online"),
|
||||
]
|
||||
)
|
||||
await db.commit()
|
||||
|
||||
with patch.object(
|
||||
main,
|
||||
"_build_account_response",
|
||||
side_effect=lambda account: {
|
||||
"id": account.id,
|
||||
"status": account.status,
|
||||
},
|
||||
):
|
||||
online = await main.get_accounts(
|
||||
page=1,
|
||||
page_size=20,
|
||||
q=None,
|
||||
status="online",
|
||||
db=db,
|
||||
user=SimpleNamespace(id=1, role="admin"),
|
||||
)
|
||||
await db.rollback()
|
||||
db.expire_all()
|
||||
offline = await main.get_accounts(
|
||||
page=1,
|
||||
page_size=20,
|
||||
q=None,
|
||||
status="offline",
|
||||
db=db,
|
||||
user=SimpleNamespace(id=1, role="admin"),
|
||||
)
|
||||
|
||||
self.assertEqual(online["total"], 1)
|
||||
self.assertEqual(online["items"], [{"id": 1001, "status": "online"}])
|
||||
self.assertEqual(offline["total"], 1)
|
||||
self.assertEqual(offline["items"], [{"id": 1002, "status": "offline"}])
|
||||
finally:
|
||||
main.manager.workers = original_workers
|
||||
await engine.dispose()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user