88from aiohttp .test_utils import TestClient
99from models_library .users import UserID
1010from servicelib .aiohttp import status
11+ from simcore_postgres_database .models .users import users as users_table
1112from simcore_service_webserver .db .models import UserRole , UserStatus
13+ from simcore_service_webserver .db .plugin import get_asyncpg_engine
1214from simcore_service_webserver .groups import api as groups_service
1315from simcore_service_webserver .login ._constants import MSG_LOGGED_IN
1416from simcore_service_webserver .login ._invitations_service import create_invitation_token
15- from simcore_service_webserver .login ._login_repository_legacy import (
16- AsyncpgStorage ,
17- get_plugin_storage ,
18- )
1917from simcore_service_webserver .products .products_service import list_products
2018from simcore_service_webserver .security import security_service
19+ from sqlalchemy .ext .asyncio import AsyncEngine
2120from yarl import URL
2221
2322from .assert_checks import assert_status
2423from .faker_factories import DEFAULT_FAKER , DEFAULT_TEST_PASSWORD , random_user
24+ from .postgres_tools import insert_and_get_row_lifespan
2525
2626
2727# WARNING: DO NOT use UserDict is already in https://docs.python.org/3/library/collections.html#collections.UserDictclass UserRowDict(TypedDict):
@@ -65,42 +65,61 @@ def parse_link(text):
6565 return URL (link ).path
6666
6767
68- async def _create_user (app : web .Application , data = None ) -> UserInfoDict :
69- db : AsyncpgStorage = get_plugin_storage (app )
68+ async def _create_user_in_db (
69+ sqlalchemy_async_engine : AsyncEngine ,
70+ exit_stack : contextlib .AsyncExitStack ,
71+ data : dict | None = None ,
72+ ) -> UserInfoDict :
7073
71- # create
74+ # create fake
7275 data = data or {}
7376 data .setdefault ("status" , UserStatus .ACTIVE .name )
7477 data .setdefault ("role" , UserRole .USER .name )
75- data .setdefault ("password" , DEFAULT_TEST_PASSWORD )
76- user = await db .create_user (random_user (** data ))
7778
78- # get
79- user = await db .get_user ({"id" : user ["id" ]})
79+ raw_password = DEFAULT_TEST_PASSWORD
80+
81+ # inject in db
82+ user = await exit_stack .enter_async_context (
83+ insert_and_get_row_lifespan ( # pylint:disable=contextmanager-generator-missing-cleanup
84+ sqlalchemy_async_engine ,
85+ table = users_table ,
86+ values = random_user (password = raw_password , ** data ),
87+ pk_col = users_table .c .id ,
88+ )
89+ )
8090 assert "first_name" in user
8191 assert "last_name" in user
8292
83- # adds extras
84- extras = {"raw_password" : data ["password" ]}
85-
8693 return UserInfoDict (
87- ** {
88- key : user [key ]
89- for key in [
90- "id" ,
91- "name" ,
92- "email" ,
93- "primary_gid" ,
94- "status" ,
95- "role" ,
96- "created_at" ,
97- "password_hash" ,
98- "first_name" ,
99- "last_name" ,
100- "phone" ,
101- ]
102- },
103- ** extras ,
94+ # required
95+ # - in db
96+ id = user ["id" ],
97+ name = user ["name" ],
98+ email = user ["email" ],
99+ primary_gid = user ["primary_gid" ],
100+ status = (
101+ UserStatus (user ["status" ])
102+ if not isinstance (user ["status" ], UserStatus )
103+ else user ["status" ]
104+ ),
105+ role = (
106+ UserRole (user ["role" ])
107+ if not isinstance (user ["role" ], UserRole )
108+ else user ["role" ]
109+ ),
110+ # optional
111+ # - in db
112+ created_at = (
113+ user ["created_at" ]
114+ if isinstance (user ["created_at" ], datetime )
115+ else datetime .fromisoformat (user ["created_at" ])
116+ ),
117+ password_hash = user ["password_hash" ],
118+ first_name = user ["first_name" ],
119+ last_name = user ["last_name" ],
120+ phone = user ["phone" ],
121+ # extras
122+ raw_password = raw_password ,
104123 )
105124
106125
@@ -114,12 +133,16 @@ async def _register_user_in_default_product(app: web.Application, user_id: UserI
114133 )
115134
116135
117- async def _create_account (
136+ async def _create_account_in_db (
118137 app : web .Application ,
138+ exit_stack : contextlib .AsyncExitStack ,
119139 user_data : dict [str , Any ] | None = None ,
120140) -> UserInfoDict :
121141 # users, groups in db
122- user = await _create_user (app , user_data )
142+ user = await _create_user_in_db (
143+ get_asyncpg_engine (app ), exit_stack = exit_stack , data = user_data
144+ )
145+
123146 # user has default product
124147 await _register_user_in_default_product (app , user_id = user ["id" ])
125148 return user
@@ -129,14 +152,17 @@ async def log_client_in(
129152 client : TestClient ,
130153 user_data : dict [str , Any ] | None = None ,
131154 * ,
132- enable_check = True ,
155+ exit_stack : contextlib .AsyncExitStack ,
156+ enable_check : bool = True ,
133157) -> UserInfoDict :
134158 assert client .app
135159
136160 # create account
137- user = await _create_account (client .app , user_data = user_data )
161+ user = await _create_account_in_db (
162+ client .app , exit_stack = exit_stack , user_data = user_data
163+ )
138164
139- # login
165+ # login (requires)
140166 url = client .app .router ["auth_login" ].url_for ()
141167 reponse = await client .post (
142168 str (url ),
@@ -160,16 +186,20 @@ def __init__(
160186 ):
161187 self .user_data = user_data
162188 self .user = None
189+
163190 assert app
164- self .db = get_plugin_storage (app )
165191 self .app = app
166192
193+ self .exit_stack = contextlib .AsyncExitStack ()
194+
167195 async def __aenter__ (self ) -> UserInfoDict :
168- self .user = await _create_account (self .app , self .user_data )
196+ self .user = await _create_account_in_db (
197+ self .app , self .exit_stack , self .user_data
198+ )
169199 return self .user
170200
171201 async def __aexit__ (self , * args ):
172- await self .db . delete_user ( self . user )
202+ await self .exit_stack . aclose ( )
173203
174204
175205class LoggedUser (NewUser ):
@@ -181,7 +211,10 @@ def __init__(self, client: TestClient, user_data=None, *, check_if_succeeds=True
181211
182212 async def __aenter__ (self ) -> UserInfoDict :
183213 self .user = await log_client_in (
184- self .client , self .user_data , enable_check = self .enable_check
214+ self .client ,
215+ self .user_data ,
216+ exit_stack = self .exit_stack ,
217+ enable_check = self .enable_check ,
185218 )
186219 return self .user
187220
@@ -237,7 +270,7 @@ def __init__(
237270 async def __aenter__ (self ) -> "NewInvitation" :
238271 # creates host user
239272 assert self .client .app
240- self .user = await _create_user (self .client .app , self .user_data )
273+ self .user = await _create_user_in_db (self .client .app , self .user_data )
241274
242275 self .confirmation = await create_invitation_token (
243276 self .db ,
0 commit comments