Files
app/backend/tests/crud/test_user.py
T
Melvin StroblandClaude Opus 5 1916f7f778 Vendor backend and frontend into the monorepo
The submodule collapse was only half applied: .gitmodules was deleted but
backend/ and frontend/ were still recorded as gitlinks, so none of their
files were tracked. Replace the gitlinks with the real trees.

Also untrack .env (it carried placeholder secrets) in favour of a tracked
.env.example, drop the committed __pycache__, and narrow the blanket *.png
ignore that would have swallowed design assets.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 15:14:54 +02:00

131 lines
4.7 KiB
Python

from fastapi.encoders import jsonable_encoder
from pwdlib.hashers.bcrypt import BcryptHasher
from sqlmodel import Session
from app import crud
from app.core.security import verify_password
from app.models import User, UserCreate, UserUpdate
from tests.utils.utils import random_email, random_lower_string
def test_create_user(db: Session) -> None:
email = random_email()
password = random_lower_string()
user_in = UserCreate(email=email, password=password)
user = crud.create_user(session=db, user_create=user_in)
assert user.email == email
assert hasattr(user, "hashed_password")
def test_authenticate_user(db: Session) -> None:
email = random_email()
password = random_lower_string()
user_in = UserCreate(email=email, password=password)
user = crud.create_user(session=db, user_create=user_in)
authenticated_user = crud.authenticate(session=db, email=email, password=password)
assert authenticated_user
assert user.email == authenticated_user.email
def test_not_authenticate_user(db: Session) -> None:
email = random_email()
password = random_lower_string()
user = crud.authenticate(session=db, email=email, password=password)
assert user is None
def test_check_if_user_is_active(db: Session) -> None:
email = random_email()
password = random_lower_string()
user_in = UserCreate(email=email, password=password)
user = crud.create_user(session=db, user_create=user_in)
assert user.is_active is True
def test_check_if_user_is_active_inactive(db: Session) -> None:
email = random_email()
password = random_lower_string()
user_in = UserCreate(email=email, password=password, is_active=False)
user = crud.create_user(session=db, user_create=user_in)
assert user.is_active is False
def test_check_if_user_is_superuser(db: Session) -> None:
email = random_email()
password = random_lower_string()
user_in = UserCreate(email=email, password=password, is_superuser=True)
user = crud.create_user(session=db, user_create=user_in)
assert user.is_superuser is True
def test_check_if_user_is_superuser_normal_user(db: Session) -> None:
username = random_email()
password = random_lower_string()
user_in = UserCreate(email=username, password=password)
user = crud.create_user(session=db, user_create=user_in)
assert user.is_superuser is False
def test_get_user(db: Session) -> None:
password = random_lower_string()
username = random_email()
user_in = UserCreate(email=username, password=password, is_superuser=True)
user = crud.create_user(session=db, user_create=user_in)
user_2 = db.get(User, user.id)
assert user_2
assert user.email == user_2.email
assert jsonable_encoder(user) == jsonable_encoder(user_2)
def test_update_user(db: Session) -> None:
password = random_lower_string()
email = random_email()
user_in = UserCreate(email=email, password=password, is_superuser=True)
user = crud.create_user(session=db, user_create=user_in)
new_password = random_lower_string()
user_in_update = UserUpdate(password=new_password, is_superuser=True)
if user.id is not None:
crud.update_user(session=db, db_user=user, user_in=user_in_update)
user_2 = db.get(User, user.id)
assert user_2
assert user.email == user_2.email
verified, _ = verify_password(new_password, user_2.hashed_password)
assert verified
def test_authenticate_user_with_bcrypt_upgrades_to_argon2(db: Session) -> None:
"""Test that a user with bcrypt password hash gets upgraded to argon2 on login."""
email = random_email()
password = random_lower_string()
# Create a bcrypt hash directly (simulating legacy password)
bcrypt_hasher = BcryptHasher()
bcrypt_hash = bcrypt_hasher.hash(password)
assert bcrypt_hash.startswith("$2") # bcrypt hashes start with $2
# Create user with bcrypt hash directly in the database
user = User(email=email, hashed_password=bcrypt_hash)
db.add(user)
db.commit()
db.refresh(user)
# Verify the hash is bcrypt before authentication
assert user.hashed_password.startswith("$2")
# Authenticate - this should upgrade the hash to argon2
authenticated_user = crud.authenticate(session=db, email=email, password=password)
assert authenticated_user
assert authenticated_user.email == email
db.refresh(authenticated_user)
# Verify the hash was upgraded to argon2
assert authenticated_user.hashed_password.startswith("$argon2")
verified, updated_hash = verify_password(
password, authenticated_user.hashed_password
)
assert verified
# Should not need another update since it's already argon2
assert updated_hash is None