feat: add search_users and count_users to user repository
This commit is contained in:
parent
b22dabbbb0
commit
7e9eeb1339
3 changed files with 73 additions and 0 deletions
|
|
@ -20,6 +20,10 @@ class UserRepository(Protocol):
|
|||
|
||||
async def list_users(self, offset: int = 0, limit: int = 100) -> list[User]: ...
|
||||
|
||||
async def search_users(self, query: str, offset: int = 0, limit: int = 100) -> list[User]: ...
|
||||
|
||||
async def count_users(self, query: str | None = None) -> int: ...
|
||||
|
||||
async def delete(self, userid: str) -> bool: ...
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,32 @@ class SQLiteUserRepository:
|
|||
users.append(self._row_to_user(row, groups))
|
||||
return users
|
||||
|
||||
async def search_users(self, query: str, offset: int = 0, limit: int = 100) -> list[User]:
|
||||
pattern = f"%{query}%"
|
||||
async with self._db.execute(
|
||||
"SELECT * FROM users WHERE username LIKE ? OR email LIKE ? ORDER BY username LIMIT ? OFFSET ?",
|
||||
(pattern, pattern, limit, offset),
|
||||
) as cursor:
|
||||
rows = await cursor.fetchall()
|
||||
users = []
|
||||
for row in rows:
|
||||
groups = await self._get_groups(row["userid"])
|
||||
users.append(self._row_to_user(row, groups))
|
||||
return users
|
||||
|
||||
async def count_users(self, query: str | None = None) -> int:
|
||||
if query:
|
||||
pattern = f"%{query}%"
|
||||
async with self._db.execute(
|
||||
"SELECT COUNT(*) FROM users WHERE username LIKE ? OR email LIKE ?",
|
||||
(pattern, pattern),
|
||||
) as cursor:
|
||||
row = await cursor.fetchone()
|
||||
else:
|
||||
async with self._db.execute("SELECT COUNT(*) FROM users") as cursor:
|
||||
row = await cursor.fetchone()
|
||||
return row[0] if row else 0
|
||||
|
||||
async def delete(self, userid: str) -> bool:
|
||||
cursor = await self._db.execute("DELETE FROM users WHERE userid = ?", (userid,))
|
||||
await self._db.commit()
|
||||
|
|
|
|||
|
|
@ -159,6 +159,49 @@ async def test_create_duplicate_username(user_repo: SQLiteUserRepository) -> Non
|
|||
await user_repo.create(_make_user(userid="different-id", username="alice"))
|
||||
|
||||
|
||||
async def test_search_users_by_username(user_repo: SQLiteUserRepository) -> None:
|
||||
await user_repo.create(_make_user(userid="id-1", username="sample_user"))
|
||||
results = await user_repo.search_users("sample", offset=0, limit=100)
|
||||
assert len(results) == 1
|
||||
assert results[0].userid == "id-1"
|
||||
|
||||
|
||||
async def test_search_users_by_email(user_repo: SQLiteUserRepository) -> None:
|
||||
await user_repo.create(_make_user(email="alice@example.com"))
|
||||
results = await user_repo.search_users("alice", offset=0, limit=100)
|
||||
assert len(results) == 1
|
||||
|
||||
|
||||
async def test_search_users_no_match(user_repo: SQLiteUserRepository) -> None:
|
||||
await user_repo.create(_make_user())
|
||||
results = await user_repo.search_users("nonexistent", offset=0, limit=100)
|
||||
assert len(results) == 0
|
||||
|
||||
|
||||
async def test_search_users_pagination(user_repo: SQLiteUserRepository) -> None:
|
||||
for i in range(5):
|
||||
await user_repo.create(_make_user(userid=f"id-{i}", username=f"user{i}", groups=["users"]))
|
||||
page1 = await user_repo.search_users("user", offset=0, limit=2)
|
||||
page2 = await user_repo.search_users("user", offset=2, limit=2)
|
||||
assert len(page1) == 2
|
||||
assert len(page2) == 2
|
||||
assert page1[0].username != page2[0].username
|
||||
|
||||
|
||||
async def test_count_users_no_query(user_repo: SQLiteUserRepository) -> None:
|
||||
await user_repo.create(_make_user())
|
||||
count = await user_repo.count_users()
|
||||
assert count == 1
|
||||
|
||||
|
||||
async def test_count_users_with_query(user_repo: SQLiteUserRepository) -> None:
|
||||
await user_repo.create(_make_user())
|
||||
count = await user_repo.count_users(query="alice")
|
||||
assert count == 1
|
||||
count = await user_repo.count_users(query="nonexistent")
|
||||
assert count == 0
|
||||
|
||||
|
||||
async def test_roundtrip_preserves_all_fields(user_repo: SQLiteUserRepository) -> None:
|
||||
user = _make_user(
|
||||
preferred_username="ally",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue