До 10 подсказок по подстроке ника среди активных игроков (role=player). Регистронезависимо и для кириллицы: SQLite LIKE/lower сворачивают регистр только у ASCII, поэтому фильтрация/ранжирование в Python (casefold): префиксные совпадения раньше подстрочных, внутри — по алфавиту. Пустой q — пустой список. Тесты + регенерированный schema.d.ts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
66 lines
2.5 KiB
Python
66 lines
2.5 KiB
Python
"""Поиск игроков для автокомплита по нику: 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
|
|
)
|