Skip to content

Commit f67af69

Browse files
authored
♻️ Refactor user update (#689)
1 parent 22a7d7a commit f67af69

6 files changed

Lines changed: 62 additions & 10 deletions

File tree

backend/app/api/routes/users.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ def update_user_me(
8080
Update own user.
8181
"""
8282

83+
if user_in.email:
84+
existing_user = crud.get_user_by_email(session=session, email=user_in.email)
85+
if existing_user:
86+
raise HTTPException(
87+
status_code=409, detail="User with this email already exists"
88+
)
8389
user_data = user_in.model_dump(exclude_unset=True)
8490
current_user.sqlmodel_update(user_data)
8591
session.add(current_user)
@@ -170,12 +176,20 @@ def update_user(
170176
Update a user.
171177
"""
172178

173-
db_user = crud.update_user(session=session, user_id=user_id, user_in=user_in)
174-
if db_user is None:
179+
db_user = session.get(User, user_id)
180+
if not db_user:
175181
raise HTTPException(
176182
status_code=404,
177183
detail="The user with this id does not exist in the system",
178184
)
185+
if user_in.email:
186+
existing_user = crud.get_user_by_email(session=session, email=user_in.email)
187+
if existing_user:
188+
raise HTTPException(
189+
status_code=409, detail="User with this email already exists"
190+
)
191+
192+
db_user = crud.update_user(session=session, db_user=db_user, user_in=user_in)
179193
return db_user
180194

181195

backend/app/crud.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ def create_user(*, session: Session, user_create: UserCreate) -> User:
1616
return db_obj
1717

1818

19-
def update_user(*, session: Session, user_id: int, user_in: UserUpdate) -> Any:
20-
db_user = session.get(User, user_id)
21-
if not db_user:
22-
return None
19+
def update_user(*, session: Session, db_user: User, user_in: UserUpdate) -> Any:
2320
user_data = user_in.model_dump(exclude_unset=True)
2421
extra_data = {}
2522
if "password" in user_data:

backend/app/tests/api/routes/test_users.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def test_update_user_me(
170170
client: TestClient, normal_user_token_headers: dict[str, str], db: Session
171171
) -> None:
172172
full_name = "Updated Name"
173-
email = "updated email"
173+
email = random_email()
174174
data = {"full_name": full_name, "email": email}
175175
r = client.patch(
176176
f"{settings.API_V1_STR}/users/me",
@@ -228,6 +228,24 @@ def test_update_password_me_incorrect_password(
228228
assert updated_user["detail"] == "Incorrect password"
229229

230230

231+
def test_update_user_me_email_exists(
232+
client: TestClient, normal_user_token_headers: dict[str, str], db: Session
233+
) -> None:
234+
username = random_email()
235+
password = random_lower_string()
236+
user_in = UserCreate(email=username, password=password)
237+
user = crud.create_user(session=db, user_create=user_in)
238+
239+
data = {"email": user.email}
240+
r = client.patch(
241+
f"{settings.API_V1_STR}/users/me",
242+
headers=normal_user_token_headers,
243+
json=data,
244+
)
245+
assert r.status_code == 409
246+
assert r.json()["detail"] == "User with this email already exists"
247+
248+
231249
def test_update_password_me_same_password_error(
232250
client: TestClient, superuser_token_headers: dict[str, str], db: Session
233251
) -> None:
@@ -330,6 +348,29 @@ def test_update_user_not_exists(
330348
assert r.json()["detail"] == "The user with this id does not exist in the system"
331349

332350

351+
def test_update_user_email_exists(
352+
client: TestClient, superuser_token_headers: dict[str, str], db: Session
353+
) -> None:
354+
username = random_email()
355+
password = random_lower_string()
356+
user_in = UserCreate(email=username, password=password)
357+
user = crud.create_user(session=db, user_create=user_in)
358+
359+
username2 = random_email()
360+
password2 = random_lower_string()
361+
user_in2 = UserCreate(email=username2, password=password2)
362+
user2 = crud.create_user(session=db, user_create=user_in2)
363+
364+
data = {"email": user2.email}
365+
r = client.patch(
366+
f"{settings.API_V1_STR}/users/{user.id}",
367+
headers=superuser_token_headers,
368+
json=data,
369+
)
370+
assert r.status_code == 409
371+
assert r.json()["detail"] == "User with this email already exists"
372+
373+
333374
def test_delete_user_super_user(
334375
client: TestClient, superuser_token_headers: dict[str, str], db: Session
335376
) -> None:

backend/app/tests/crud/test_user.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def test_update_user(db: Session) -> None:
8484
new_password = random_lower_string()
8585
user_in_update = UserUpdate(password=new_password, is_superuser=True)
8686
if user.id is not None:
87-
crud.update_user(session=db, user_id=user.id, user_in=user_in_update)
87+
crud.update_user(session=db, db_user=user, user_in=user_in_update)
8888
user_2 = db.get(User, user.id)
8989
assert user_2
9090
assert user.email == user_2.email

backend/app/tests/utils/user.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ def authentication_token_from_email(
4444
user_in_update = UserUpdate(password=password)
4545
if not user.id:
4646
raise Exception("User id not set")
47-
user = crud.update_user(session=db, user_id=user.id, user_in=user_in_update)
47+
user = crud.update_user(session=db, db_user=user, user_in=user_in_update)
4848

4949
return user_authentication_headers(client=client, email=email, password=password)

backend/scripts/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ set -x
55

66
coverage run --source=app -m pytest
77
coverage report --show-missing
8-
coverage html --title "${@}"
8+
coverage html --title "${@-coverage}"

0 commit comments

Comments
 (0)