arm-core/api/tests/test_api_users_brief.py
Andrey Epifancev 58f039a91d feat(users): GET /users/brief — имена пользователей для всех аутентифицированных (D-12)
Добавлен эндпоинт GET /api/v1/users/brief для получения краткого справочника
пользователей (id, ФИО, статус активности) по списку id. Доступен любому
аутентифицированному пользователю без отдельного права. Максимум 200 id,
иначе 422 TOO_MANY_IDS; некорректный UUID — 422 INVALID_IDS.

- Создан api/src/api/endpoints/users.py с маршрутом /brief
- Добавлен метод users_brief в repositories/users.py
- Добавлена схема UserBriefOut в schemas/admin.py
- Подключён маршрут users в build_api_router ДО admin.router
- Обновлены тесты OpenAPI: добавлены маршрут и префикс /users/brief
- Написаны интеграционные тесты в test_api_users_brief.py

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-07 13:08:29 +04:00

38 lines
1.7 KiB
Python

"""Краткий справочник пользователей (spec users-admin «Краткий справочник пользователей»; D-12)."""
import uuid
import pytest
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from src.api.endpoints.users import MAX_BRIEF_IDS
from src.models.access import AppUser
from tests.conftest import AuthClientFactory
pytestmark = pytest.mark.integration
HTTP_OK = 200
HTTP_UNPROCESSABLE = 422
KA_RF = "ka_rf@armka.local"
async def test_brief_for_non_admin(seeded: AsyncSession, auth_client: AuthClientFactory) -> None:
users = (await seeded.execute(select(AppUser).order_by(AppUser.email).limit(2))).scalars().all()
unknown = uuid.uuid4()
client = await auth_client(KA_RF) # без USERS_ADMIN
ids = ",".join([*(str(user.id) for user in users), str(unknown)])
response = await client.get("/users/brief", params={"ids": ids})
assert response.status_code == HTTP_OK
body = {item["id"]: item for item in response.json()}
assert set(body) == {str(user.id) for user in users}
assert all(set(item) == {"id", "full_name", "is_active"} for item in body.values())
async def test_brief_limits(seeded: AsyncSession, auth_client: AuthClientFactory) -> None: # noqa: ARG001
client = await auth_client(KA_RF)
too_many = ",".join(str(uuid.uuid4()) for _ in range(MAX_BRIEF_IDS + 1))
response = await client.get("/users/brief", params={"ids": too_many})
assert response.status_code == HTTP_UNPROCESSABLE and response.json()["detail"]["code"] == "TOO_MANY_IDS"
assert (await client.get("/users/brief", params={"ids": "not-a-uuid"})).status_code == HTTP_UNPROCESSABLE