193 lines
6.2 KiB
Python
193 lines
6.2 KiB
Python
import pytest
|
|
from fastapi import HTTPException
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.user import User
|
|
from app.models.user_profile import UserProfile
|
|
from app.schemas.user import UserCreate, UserUpdate
|
|
from app.security import verify_password
|
|
from app.services.user_service import (
|
|
create_user,
|
|
delete_user,
|
|
get_user_by_id,
|
|
get_user_list,
|
|
update_user,
|
|
)
|
|
|
|
|
|
class TestGetUserList:
|
|
def test_empty(self, db_session: Session):
|
|
users = get_user_list(db_session)
|
|
assert users == []
|
|
|
|
def test_with_users(self, db_session: Session):
|
|
for i in range(3):
|
|
user = User(email=f"test{i}@ex.com", username=f"user{i}", password="x")
|
|
db_session.add(user)
|
|
db_session.commit()
|
|
|
|
users = get_user_list(db_session)
|
|
assert len(users) == 3
|
|
|
|
def test_soft_deleted_excluded(self, db_session: Session):
|
|
from datetime import datetime
|
|
|
|
u1 = User(email="active@ex.com", username="active", password="x")
|
|
u2 = User(email="deleted@ex.com", username="deleted", password="x", deleted_at=datetime.now())
|
|
db_session.add_all([u1, u2])
|
|
db_session.commit()
|
|
|
|
users = get_user_list(db_session)
|
|
assert len(users) == 1
|
|
assert users[0].email == "active@ex.com"
|
|
|
|
|
|
class TestGetUserById:
|
|
def test_found(self, db_session: Session):
|
|
user = User(email="find@ex.com", username="find", password="x")
|
|
db_session.add(user)
|
|
db_session.commit()
|
|
|
|
result = get_user_by_id(db_session, user.id)
|
|
assert result.id == user.id
|
|
assert result.email == "find@ex.com"
|
|
|
|
def test_not_found(self, db_session: Session):
|
|
with pytest.raises(HTTPException) as exc:
|
|
get_user_by_id(db_session, "nonexistent")
|
|
assert exc.value.status_code == 404
|
|
|
|
def test_soft_deleted(self, db_session: Session):
|
|
from datetime import datetime
|
|
|
|
user = User(email="gone@ex.com", username="gone", password="x", deleted_at=datetime.now())
|
|
db_session.add(user)
|
|
db_session.commit()
|
|
|
|
with pytest.raises(HTTPException) as exc:
|
|
get_user_by_id(db_session, user.id)
|
|
assert exc.value.status_code == 404
|
|
|
|
|
|
class TestCreateUser:
|
|
def test_create(self, db_session: Session):
|
|
data = UserCreate(
|
|
email="new@ex.com",
|
|
username="newuser",
|
|
password="secret",
|
|
full_name="New User",
|
|
)
|
|
user = create_user(db_session, data)
|
|
|
|
assert user.email == "new@ex.com"
|
|
assert user.username == "newuser"
|
|
assert verify_password("secret", user.password)
|
|
|
|
profile = db_session.query(UserProfile).filter(UserProfile.user_id == user.id).first()
|
|
assert profile is not None
|
|
assert profile.full_name == "New User"
|
|
|
|
def test_duplicate_email(self, db_session: Session):
|
|
db_session.add(User(email="dup@ex.com", username="first", password="x"))
|
|
db_session.commit()
|
|
data = UserCreate(
|
|
email="dup@ex.com",
|
|
username="second",
|
|
password="x",
|
|
full_name="Dup",
|
|
)
|
|
with pytest.raises(HTTPException) as exc:
|
|
create_user(db_session, data)
|
|
assert exc.value.status_code == 409
|
|
|
|
def test_duplicate_username(self, db_session: Session):
|
|
data = UserCreate(
|
|
email="a@ex.com",
|
|
username="taken",
|
|
password="x",
|
|
full_name="A",
|
|
)
|
|
create_user(db_session, data)
|
|
|
|
dup = UserCreate(
|
|
email="b@ex.com",
|
|
username="taken",
|
|
password="x",
|
|
full_name="B",
|
|
)
|
|
with pytest.raises(HTTPException) as exc:
|
|
create_user(db_session, dup)
|
|
assert exc.value.status_code == 409
|
|
|
|
|
|
class TestUpdateUser:
|
|
def test_update_email(self, db_session: Session):
|
|
user = User(email="old@ex.com", username="old", password="x")
|
|
db_session.add(user)
|
|
db_session.commit()
|
|
|
|
data = UserUpdate(email="new@ex.com")
|
|
updated = update_user(db_session, user.id, data)
|
|
|
|
assert updated.email == "new@ex.com"
|
|
|
|
def test_update_profile(self, db_session: Session):
|
|
user = User(email="prof@ex.com", username="prof", password="x")
|
|
db_session.add(user)
|
|
db_session.flush()
|
|
|
|
profile = UserProfile(user_id=user.id, full_name="Old Name")
|
|
db_session.add(profile)
|
|
db_session.commit()
|
|
|
|
data = UserUpdate(full_name="Updated Name")
|
|
updated = update_user(db_session, user.id, data)
|
|
|
|
assert updated.profile.full_name == "Updated Name"
|
|
|
|
def test_update_password(self, db_session: Session):
|
|
user = User(email="pw@ex.com", username="pw", password="x")
|
|
db_session.add(user)
|
|
db_session.commit()
|
|
|
|
data = UserUpdate(password="newsecret")
|
|
update_user(db_session, user.id, data)
|
|
|
|
db_session.refresh(user)
|
|
assert verify_password("newsecret", user.password)
|
|
|
|
def test_update_not_found(self, db_session: Session):
|
|
data = UserUpdate(email="nope@ex.com")
|
|
with pytest.raises(HTTPException) as exc:
|
|
update_user(db_session, "nonexistent", data)
|
|
assert exc.value.status_code == 404
|
|
|
|
def test_update_conflict_email(self, db_session: Session):
|
|
User(email="existing@ex.com", username="existing", password="x")
|
|
user = User(email="me@ex.com", username="me", password="x")
|
|
db_session.add_all([User(email="existing@ex.com", username="existing", password="x"), user])
|
|
db_session.commit()
|
|
|
|
data = UserUpdate(email="existing@ex.com")
|
|
with pytest.raises(HTTPException) as exc:
|
|
update_user(db_session, user.id, data)
|
|
assert exc.value.status_code == 409
|
|
|
|
|
|
class TestDeleteUser:
|
|
def test_soft_delete(self, db_session: Session):
|
|
user = User(email="del@ex.com", username="del", password="x")
|
|
db_session.add(user)
|
|
db_session.commit()
|
|
|
|
delete_user(db_session, user.id)
|
|
assert user.deleted_at is not None
|
|
|
|
def test_delete_not_found(self, db_session: Session):
|
|
with pytest.raises(HTTPException) as exc:
|
|
delete_user(db_session, "nonexistent")
|
|
assert exc.value.status_code == 404
|
|
|
|
|
|
|