fix(api): return real total for user pagination

This commit is contained in:
2026-09-15 10:55:29 +08:00
parent 682c26fddd
commit 45e1b4b106
3 changed files with 35 additions and 3 deletions
+4 -1
View File
@@ -7,6 +7,7 @@ from sqlalchemy.engine.url import make_url
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
from sqlalchemy.ext.asyncio import create_async_engine
from app.api.pagination import PaginatedList
from app.auth.metadata_dependencies import (
get_current_metadata_admin,
get_metadata_repository,
@@ -236,7 +237,9 @@ async def list_metadata_users(
metadata_repo: MetadataRepository = Depends(get_metadata_repository),
) -> List[MetadataUserResponse]:
users = await metadata_repo.list_users(skip=skip, limit=limit)
return [MetadataUserResponse.model_validate(user) for user in users]
total = await metadata_repo.count_users()
items = [MetadataUserResponse.model_validate(user) for user in users]
return PaginatedList(items, total=total)
@router.get("/admin/projects", response_model=List[AdminProjectResponse])
@@ -4,7 +4,7 @@ from typing import Optional, List
from uuid import UUID, uuid4
from cryptography.fernet import InvalidToken
from sqlalchemy import delete, select
from sqlalchemy import delete, func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.encryption import (
@@ -122,6 +122,12 @@ class MetadataRepository:
)
return list(result.scalars().all())
async def count_users(self) -> int:
result = await self.session.execute(
select(func.count()).select_from(models.User)
)
return int(result.scalar() or 0)
async def upsert_user_from_keycloak(
self,
*,
+24 -1
View File
@@ -7,8 +7,9 @@ import pytest
from fastapi import HTTPException
from fastapi import Response
from app.auth.metadata_dependencies import get_current_metadata_admin
from app.api.v1.endpoints import admin_metadata
from app.api.pagination import PaginatedList
from app.auth.metadata_dependencies import get_current_metadata_admin
from app.domain.schemas.admin_metadata import (
AdminProjectCreateRequest,
MetadataUsersBatchSyncRequest,
@@ -83,6 +84,28 @@ def test_to_async_sqlalchemy_url_preserves_password():
assert "***" not in url
@pytest.mark.anyio
async def test_list_metadata_users_returns_page_with_real_total():
users = [_user(username="alice"), _user(username="bob")]
repo = SimpleNamespace(
list_users=AsyncMock(return_value=users),
count_users=AsyncMock(return_value=7),
)
response = await admin_metadata.list_metadata_users(
skip=2,
limit=2,
current_user=_user(role="admin", is_superuser=True),
metadata_repo=repo,
)
assert isinstance(response, PaginatedList)
assert response.total == 7
assert [item.username for item in response] == ["alice", "bob"]
repo.list_users.assert_awaited_once_with(skip=2, limit=2)
repo.count_users.assert_awaited_once_with()
@pytest.mark.anyio
async def test_sync_metadata_user_upserts_without_password(monkeypatch):
keycloak_id = uuid4()