Files

134 lines
4.7 KiB
Python
Raw Permalink Normal View History

"""Tests for UserRepository."""
from uuid import uuid4
import asyncpg
import pytest
from app.repositories.user import UserRepository
class TestUserRepository:
"""Tests for UserRepository conforming to SPECS.md."""
async def test_create_user_returns_user_data(self, db_conn: asyncpg.Connection) -> None:
"""Creating a user returns the user data with id, email, created_at."""
repo = UserRepository(db_conn)
user_id = uuid4()
email = "test@example.com"
password_hash = "hashed_password_123"
result = await repo.create(user_id, email, password_hash)
assert result["id"] == user_id
assert result["email"] == email
assert result["created_at"] is not None
async def test_create_user_stores_password_hash(self, db_conn: asyncpg.Connection) -> None:
"""Password hash is stored correctly in the database."""
repo = UserRepository(db_conn)
user_id = uuid4()
email = "hash_test@example.com"
password_hash = "bcrypt_hashed_value"
await repo.create(user_id, email, password_hash)
user = await repo.get_by_id(user_id)
assert user["password_hash"] == password_hash
async def test_create_user_email_must_be_unique(self, db_conn: asyncpg.Connection) -> None:
"""Email uniqueness constraint per SPECS.md users table."""
repo = UserRepository(db_conn)
email = "duplicate@example.com"
await repo.create(uuid4(), email, "hash1")
with pytest.raises(asyncpg.UniqueViolationError):
await repo.create(uuid4(), email, "hash2")
async def test_get_by_id_returns_user(self, db_conn: asyncpg.Connection) -> None:
"""get_by_id returns the correct user."""
repo = UserRepository(db_conn)
user_id = uuid4()
email = "getbyid@example.com"
await repo.create(user_id, email, "hash")
result = await repo.get_by_id(user_id)
assert result is not None
assert result["id"] == user_id
assert result["email"] == email
async def test_get_by_id_returns_none_for_nonexistent(self, db_conn: asyncpg.Connection) -> None:
"""get_by_id returns None for non-existent user."""
repo = UserRepository(db_conn)
result = await repo.get_by_id(uuid4())
assert result is None
async def test_get_by_email_returns_user(self, db_conn: asyncpg.Connection) -> None:
"""get_by_email returns the correct user."""
repo = UserRepository(db_conn)
user_id = uuid4()
email = "getbyemail@example.com"
await repo.create(user_id, email, "hash")
result = await repo.get_by_email(email)
assert result is not None
assert result["id"] == user_id
assert result["email"] == email
async def test_get_by_email_returns_none_for_nonexistent(self, db_conn: asyncpg.Connection) -> None:
"""get_by_email returns None for non-existent email."""
repo = UserRepository(db_conn)
result = await repo.get_by_email("nonexistent@example.com")
assert result is None
async def test_get_by_email_is_case_sensitive(self, db_conn: asyncpg.Connection) -> None:
"""Email lookup is case-sensitive (stored as provided)."""
repo = UserRepository(db_conn)
email = "CaseSensitive@Example.com"
await repo.create(uuid4(), email, "hash")
# Exact match works
result = await repo.get_by_email(email)
assert result is not None
# Different case returns None
result = await repo.get_by_email(email.lower())
assert result is None
async def test_exists_by_email_returns_true_when_exists(self, db_conn: asyncpg.Connection) -> None:
"""exists_by_email returns True when email exists."""
repo = UserRepository(db_conn)
email = "exists@example.com"
await repo.create(uuid4(), email, "hash")
result = await repo.exists_by_email(email)
assert result is True
async def test_exists_by_email_returns_false_when_not_exists(self, db_conn: asyncpg.Connection) -> None:
"""exists_by_email returns False when email doesn't exist."""
repo = UserRepository(db_conn)
result = await repo.exists_by_email("notexists@example.com")
assert result is False
async def test_user_id_is_uuid_primary_key(self, db_conn: asyncpg.Connection) -> None:
"""User ID must be a valid UUID (primary key)."""
repo = UserRepository(db_conn)
user_id = uuid4()
await repo.create(user_id, "pk_test@example.com", "hash")
# Duplicate ID should fail
with pytest.raises(asyncpg.UniqueViolationError):
await repo.create(user_id, "other@example.com", "hash")