"""Поиск игроков для автокомплита по нику: GET /api/users/search.""" from __future__ import annotations from fastapi.testclient import TestClient from sqlmodel import Session from app.models import User from tests.conftest import login def _add_user(engine, nickname: str, *, active: bool = True, role: str = "player") -> None: """Готовим данные напрямую в БД: нужны выключенные аккаунты и админы.""" with Session(engine) as s: s.add( User( nickname=nickname, role=role, auth_provider="stub" if role == "player" else "local", is_active=active, # CHECK ck_users_admin_has_password: админ обязан иметь пароль. password_hash="x" if role == "admin" else None, ) ) s.commit() def test_search_prefix_first_cyrillic_case_insensitive(client: TestClient, engine): login(client, "Искатель") for nick in ("Барсик", "барс", "Морбарс", "Zed"): _add_user(engine, nick) r = client.get("/api/users/search", params={"q": "БАР"}) assert r.status_code == 200, r.text got = r.json() # Префиксные раньше подстрочных, внутри — по алфавиту; регистр кириллицы не важен. assert [u["nickname"] for u in got] == ["барс", "Барсик", "Морбарс"] assert {"user_id", "nickname", "avatar_url"} <= set(got[0].keys()) def test_search_empty_query_returns_empty_list(client: TestClient): login(client, "Искатель") r = client.get("/api/users/search", params={"q": " "}) assert r.status_code == 200, r.text assert r.json() == [] def test_search_skips_inactive_and_admins(client: TestClient, engine): login(client, "Искатель") _add_user(engine, "Спящий барсук", active=False) _add_user(engine, "адм барс", role="admin") r = client.get("/api/users/search", params={"q": "барс"}) assert r.status_code == 200, r.text assert r.json() == [] def test_search_respects_limit(client: TestClient, engine): login(client, "Искатель") for i in range(5): _add_user(engine, f"Игрок {i}") assert len(client.get("/api/users/search", params={"q": "игрок"}).json()) == 3 assert ( len(client.get("/api/users/search", params={"q": "игрок", "limit": 5}).json()) == 5 )