1- """Tests for DELETE /users/{user_id} (Phase 1: no resources, self or admin) ."""
1+ """Tests for DELETE /users/{user_id}."""
22
33import uuid
4- from collections .abc import AsyncGenerator
54from http import HTTPStatus
65from typing import NamedTuple
76
1514from core .errors import AccountHasResourcesError , ForbiddenError , UserNotFoundError
1615from database .users import UserGroup
1716from routers .openml .users import delete_user_account
18- from tests .users import ADMIN_USER , SOME_USER , ApiKey
17+ from tests .users import ADMIN_USER , OWNER_USER , SOME_USER , ApiKey
1918
2019
2120async def test_delete_user_missing_auth (py_api : httpx .AsyncClient ) -> None :
@@ -32,7 +31,7 @@ class DisposableUser(NamedTuple):
3231
3332
3433@pytest .fixture
35- async def disposable_user (user_test : AsyncConnection ) -> AsyncGenerator [ DisposableUser ] :
34+ async def disposable_user (user_test : AsyncConnection ) -> DisposableUser :
3635 api_key = uuid .uuid4 ().hex
3736 suffix = uuid .uuid4 ().hex [:10 ]
3837 username = f"tmp_user_{ suffix } "
@@ -58,23 +57,20 @@ async def disposable_user(user_test: AsyncConnection) -> AsyncGenerator[Disposab
5857 text ("INSERT INTO users_groups (user_id, group_id) VALUES (:uid, :gid)" ),
5958 parameters = {"uid" : new_id , "gid" : UserGroup .READ_WRITE .value },
6059 )
61- yield DisposableUser (user_id = new_id , api_key = api_key )
62- await user_test .execute (
63- text ("DELETE FROM users_groups WHERE user_id = :uid" ),
64- parameters = {"uid" : new_id },
65- )
66- await user_test .execute (
67- text ("DELETE FROM users WHERE id = :uid" ),
68- parameters = {"uid" : new_id },
69- )
60+ return DisposableUser (user_id = new_id , api_key = api_key )
61+ # No explicit teardown: the ``user_test`` fixture rolls back at the end
62+ # of the test, which removes the rows inserted above.
7063
7164
7265@pytest .mark .mut
7366async def test_delete_user_api_success_self_delete (
7467 py_api : httpx .AsyncClient ,
7568 user_test : AsyncConnection ,
7669 disposable_user : DisposableUser ,
70+ mocker : pytest_mock .MockerFixture ,
7771) -> None :
72+ log_info = mocker .patch ("routers.openml.users.logger.info" )
73+
7874 response = await py_api .delete (
7975 f"/users/{ disposable_user .user_id } " ,
8076 params = {"api_key" : disposable_user .api_key },
@@ -88,6 +84,11 @@ async def test_delete_user_api_success_self_delete(
8884 )
8985 assert exists .one_or_none () is None
9086
87+ log_info .assert_any_call (
88+ "User account {user_id} was removed." ,
89+ user_id = disposable_user .user_id ,
90+ )
91+
9192
9293@pytest .mark .mut
9394async def test_delete_user_api_success_admin_deletes_disposable_user (
@@ -143,43 +144,32 @@ async def test_delete_user_direct_forbidden(
143144 assert exc_info .value .status_code == HTTPStatus .FORBIDDEN
144145 assert exc_info .value .uri == ForbiddenError .uri
145146
147+ admin_row = await user_test .execute (
148+ text ("SELECT 1 FROM users WHERE id = :id LIMIT 1" ),
149+ parameters = {"id" : ADMIN_USER .user_id },
150+ )
151+ assert admin_row .one_or_none () is not None
152+
146153
147154async def test_delete_user_direct_conflict_has_resources (
148155 user_test : AsyncConnection ,
149156 expdb_test : AsyncConnection ,
150157) -> None :
151158 with pytest .raises (AccountHasResourcesError , match = "Cannot delete this account" ) as exc_info :
152159 await delete_user_account (
153- user_id = 16 ,
160+ user_id = OWNER_USER . user_id ,
154161 current_user = ADMIN_USER ,
155162 expdb = expdb_test ,
156163 userdb = user_test ,
157164 )
158165 assert exc_info .value .status_code == HTTPStatus .CONFLICT
159166 assert exc_info .value .uri == AccountHasResourcesError .uri
160167
161-
162- @pytest .mark .mut
163- async def test_delete_user_direct_success_logs_info (
164- user_test : AsyncConnection ,
165- expdb_test : AsyncConnection ,
166- disposable_user : DisposableUser ,
167- mocker : pytest_mock .MockerFixture ,
168- ) -> None :
169- log_info = mocker .patch ("routers.openml.users.logger.info" )
170-
171- response = await delete_user_account (
172- user_id = disposable_user .user_id ,
173- current_user = ADMIN_USER ,
174- expdb = expdb_test ,
175- userdb = user_test ,
176- )
177-
178- assert response .status_code == HTTPStatus .NO_CONTENT
179- log_info .assert_called_once_with (
180- "User account {user_id} was removed." ,
181- user_id = disposable_user .user_id ,
168+ owner_row = await user_test .execute (
169+ text ("SELECT 1 FROM users WHERE id = :id LIMIT 1" ),
170+ parameters = {"id" : OWNER_USER .user_id },
182171 )
172+ assert owner_row .one_or_none () is not None
183173
184174
185175@pytest .mark .mut
0 commit comments