diff --git a/backend/app/routes/profile.py b/backend/app/routes/profile.py index c05fa90..365ec11 100644 --- a/backend/app/routes/profile.py +++ b/backend/app/routes/profile.py @@ -1,5 +1,6 @@ from fastapi import APIRouter, Depends, UploadFile, File from sqlalchemy.orm import Session +from sqlalchemy.exc import IntegrityError from pathlib import Path import shutil import uuid @@ -28,12 +29,27 @@ def update_profile( current_user: User = Depends(get_current_user), ): if payload.username: + existing_user = ( + db.query(User) + .filter( + User.username == payload.username, + User.id != current_user.id, + ) + .first() + ) + if existing_user: + raise ValidationException("Username already exists") current_user.username = payload.username if payload.display_name: current_user.display_name = payload.display_name - db.commit() + try: + db.commit() + except IntegrityError: + db.rollback() + raise ValidationException("Username already exists") + db.refresh(current_user) return current_user diff --git a/backend/tests/test_profile.py b/backend/tests/test_profile.py new file mode 100644 index 0000000..f288451 --- /dev/null +++ b/backend/tests/test_profile.py @@ -0,0 +1,28 @@ +def test_profile_update_duplicate_username(client, auth_headers, other_user): + response = client.put( + "/profile/", + json={"username": "other"}, + headers=auth_headers, + ) + assert response.status_code == 400 + assert response.json()["error"]["message"] == "Username already exists" + + +def test_profile_update_keep_username(client, auth_headers, user): + response = client.put( + "/profile/", + json={"username": "tester"}, + headers=auth_headers, + ) + assert response.status_code == 200 + assert response.json()["username"] == "tester" + + +def test_profile_update_unique_username(client, auth_headers, user): + response = client.put( + "/profile/", + json={"username": "tester_new"}, + headers=auth_headers, + ) + assert response.status_code == 200 + assert response.json()["username"] == "tester_new"