33# pylint: disable=unused-variable
44# pylint: disable=too-many-arguments
55
6+ from collections .abc import AsyncIterable
67from dataclasses import dataclass
8+ from typing import Any
79
810import pytest
911import sqlalchemy as sa
10- from aiopg .sa .connection import SAConnection
1112from aiopg .sa .result import RowProxy
1213from faker import Faker
1314from pytest_simcore .helpers .faker_factories import (
1415 random_pre_registration_details ,
16+ random_product ,
1517 random_user ,
1618)
19+ from pytest_simcore .helpers .postgres_tools import (
20+ insert_and_get_row_lifespan ,
21+ )
22+ from simcore_postgres_database .models .products import products
1723from simcore_postgres_database .models .users import UserRole , UserStatus , users
1824from simcore_postgres_database .models .users_details import (
1925 users_pre_registration_details ,
2026)
27+ from simcore_postgres_database .utils_repos import (
28+ pass_or_acquire_connection ,
29+ transaction_context ,
30+ )
2131from simcore_postgres_database .utils_users import UsersRepo
32+ from sqlalchemy .ext .asyncio import AsyncEngine
2233
2334
2435@pytest .fixture
25- async def po_user (
36+ async def product_name (
2637 faker : Faker ,
27- connection : SAConnection ,
28- ):
29- user_id = await connection .scalar (
30- users .insert ()
31- .values (** random_user (faker , role = UserRole .PRODUCT_OWNER ))
32- .returning (users .c .id )
33- )
34- assert user_id
38+ asyncpg_engine : AsyncEngine ,
39+ ) -> AsyncIterable [str ]:
40+ async with insert_and_get_row_lifespan ( # pylint:disable=contextmanager-generator-missing-cleanup
41+ asyncpg_engine ,
42+ table = products ,
43+ values = random_product (fake = faker , name = "s4l" ),
44+ pk_col = products .c .name ,
45+ ) as row :
46+ yield row ["name" ]
3547
36- result = await connection .execute (sa .select (users ).where (users .c .id == user_id ))
37- yield await result .first ()
3848
39- users .delete ().where (users .c .id == user_id )
49+ @pytest .fixture
50+ async def po_user (
51+ faker : Faker ,
52+ asyncpg_engine : AsyncEngine ,
53+ ) -> AsyncIterable [dict [str , Any ]]:
54+ async with insert_and_get_row_lifespan ( # pylint:disable=contextmanager-generator-missing-cleanup
55+ asyncpg_engine ,
56+ table = users ,
57+ values = random_user (faker , role = UserRole .PRODUCT_OWNER ),
58+ pk_col = users .c .id ,
59+ ) as row :
60+ yield row
4061
4162
4263@pytest .mark .acceptance_test (
4364 "pre-registration in https://github.com/ITISFoundation/osparc-simcore/issues/5138"
4465)
4566async def test_user_creation_workflow (
46- connection : SAConnection , faker : Faker , po_user : RowProxy
67+ asyncpg_engine : AsyncEngine ,
68+ faker : Faker ,
69+ po_user : dict [str , Any ],
70+ product_name : str ,
4771):
4872 # a PO creates an invitation
4973 fake_pre_registration_data = random_pre_registration_details (
50- faker , created_by = po_user . id
74+ faker , created_by = po_user [ "id" ], product_name = product_name
5175 )
5276
53- pre_email = await connection .scalar (
54- sa .insert (users_pre_registration_details )
55- .values (** fake_pre_registration_data )
56- .returning (users_pre_registration_details .c .pre_email )
57- )
77+ async with transaction_context (asyncpg_engine ) as connection :
78+ pre_email = await connection .scalar (
79+ sa .insert (users_pre_registration_details )
80+ .values (** fake_pre_registration_data )
81+ .returning (users_pre_registration_details .c .pre_email )
82+ )
5883 assert pre_email is not None
5984 assert pre_email == fake_pre_registration_data ["pre_email" ]
6085
61- # user gets created
62- new_user = await UsersRepo .new_user (
63- connection ,
64- email = pre_email ,
65- password_hash = "123456" , # noqa: S106
66- status = UserStatus .ACTIVE ,
67- expires_at = None ,
68- )
69- await UsersRepo .join_and_update_from_pre_registration_details (
70- connection , new_user .id , new_user .email
71- )
86+ async with transaction_context (asyncpg_engine ) as connection :
87+ # user gets created
88+ new_user = await UsersRepo .new_user (
89+ connection ,
90+ email = pre_email ,
91+ password_hash = "123456" , # noqa: S106
92+ status = UserStatus .ACTIVE ,
93+ expires_at = None ,
94+ )
95+ await UsersRepo .link_and_update_user_from_pre_registration (
96+ connection , new_user_id = new_user .id , new_user_email = new_user .email
97+ )
7298
73- invoice_data = await UsersRepo .get_billing_details (connection , user_id = new_user .id )
74- assert invoice_data is not None
99+ async with pass_or_acquire_connection (asyncpg_engine ) as connection :
100+ invoice_data = await UsersRepo .get_billing_details (
101+ connection , user_id = new_user .id
102+ )
103+ assert invoice_data is not None
75104
76105 # drafts converting data models from https://github.com/ITISFoundation/osparc-simcore/pull/5402
77106 @dataclass
@@ -84,7 +113,11 @@ class UserAddress:
84113
85114 @classmethod
86115 def create_from_db (cls , row : RowProxy ):
87- parts = (row [c ] for c in ("institution" , "address" ) if row [c ])
116+ parts = (
117+ getattr (row , col_name )
118+ for col_name in ("institution" , "address" )
119+ if getattr (row , col_name )
120+ )
88121 return cls (
89122 line1 = ". " .join (parts ),
90123 state = row .state ,
@@ -110,28 +143,30 @@ def create_from_db(cls, row: RowProxy):
110143 assert user_address .country == fake_pre_registration_data ["country" ]
111144
112145 # now let's update the user
113- result = await connection .execute (
114- users .update ()
115- .values (first_name = "My New Name" )
116- .where (users .c .id == new_user .id )
117- .returning ("*" )
118- )
119- updated_user = await result .fetchone ()
146+ async with transaction_context (asyncpg_engine ) as connection :
147+ result = await connection .execute (
148+ users .update ()
149+ .values (first_name = "My New Name" )
150+ .where (users .c .id == new_user .id )
151+ .returning ("*" )
152+ )
153+ updated_user = result .one ()
120154
121155 assert updated_user
122156 assert updated_user .first_name == "My New Name"
123157 assert updated_user .id == new_user .id
124158
125159 for _ in range (2 ):
126- await UsersRepo .join_and_update_from_pre_registration_details (
127- connection , new_user .id , new_user .email
128- )
160+ async with transaction_context (asyncpg_engine ) as connection :
161+ await UsersRepo .link_and_update_user_from_pre_registration (
162+ connection , new_user_id = new_user .id , new_user_email = new_user .email
163+ )
129164
130- result = await connection .execute (
131- users .select ().where (users .c .id == new_user .id )
132- )
133- current_user = await result .fetchone ()
134- assert current_user
165+ result = await connection .execute (
166+ users .select ().where (users .c .id == new_user .id )
167+ )
168+ current_user = result .one ()
169+ assert current_user
135170
136- # overriden!
137- assert current_user .first_name != updated_user .first_name
171+ # overriden!
172+ assert current_user .first_name != updated_user .first_name
0 commit comments