Skip to content

Commit ee3e70f

Browse files
committed
drafting tests
1 parent 9b245c4 commit ee3e70f

File tree

3 files changed

+137
-128
lines changed

3 files changed

+137
-128
lines changed

services/web/server/src/simcore_service_webserver/users/_users_repository.py

Lines changed: 127 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from simcore_postgres_database.models.users_details import (
2121
users_pre_registration_details,
2222
)
23+
from simcore_postgres_database.utils import as_postgres_sql_query_str
2324
from simcore_postgres_database.utils_groups_extra_properties import (
2425
GroupExtraPropertiesNotFoundError,
2526
GroupExtraPropertiesRepo,
@@ -376,6 +377,132 @@ async def search_users_and_get_profile(
376377
return [row async for row in result]
377378

378379

380+
async def list_users_for_admin(
381+
engine: AsyncEngine,
382+
connection: AsyncConnection | None = None,
383+
*,
384+
filter_approved: bool | None = None,
385+
limit: int = 50,
386+
offset: int = 0,
387+
include_deleted: bool = False,
388+
) -> tuple[list[dict[str, Any]], int]:
389+
"""
390+
Gets users data for admin with pagination support using SQLAlchemy expressions
391+
392+
Args:
393+
engine: The database engine
394+
connection: Optional existing connection to reuse
395+
filter_approved: If set, filters users by their approval status
396+
limit: Maximum number of users to return
397+
offset: Number of users to skip for pagination
398+
include_deleted: Whether to include users marked as deleted
399+
400+
Returns:
401+
Tuple of (list of user data, total count)
402+
"""
403+
joined_user_tables = users.outerjoin(
404+
users_pre_registration_details,
405+
users.c.id == users_pre_registration_details.c.user_id,
406+
)
407+
408+
where_conditions = []
409+
if not include_deleted:
410+
where_conditions.append(users.c.status != UserStatus.DELETED)
411+
412+
if filter_approved is not None:
413+
if filter_approved:
414+
where_conditions.append(
415+
users_pre_registration_details.c.account_request_status
416+
== AccountRequestStatus.APPROVED
417+
)
418+
else:
419+
where_conditions.append(
420+
users_pre_registration_details.c.account_request_status
421+
!= AccountRequestStatus.APPROVED
422+
)
423+
424+
where_clause = sa.and_(*where_conditions) if where_conditions else sa.true()
425+
426+
# Count query
427+
count_query = (
428+
sa.select(sa.func.count().label("total"))
429+
.select_from(joined_user_tables)
430+
.where(where_clause)
431+
)
432+
433+
# Create an alias for the users table to use in the subquery
434+
users_alias = sa.alias(users, name="creators")
435+
invited_by = (
436+
sa.select(
437+
users_alias.c.name,
438+
)
439+
.where(
440+
users_pre_registration_details.c.created_by.isnot(None)
441+
& (users_pre_registration_details.c.created_by == users_alias.c.id)
442+
)
443+
.correlate(None)
444+
.scalar_subquery()
445+
.label("invited_by")
446+
)
447+
448+
# Main query to get user data
449+
main_query = (
450+
sa.select(
451+
users_pre_registration_details.c.pre_email, # unique
452+
users_pre_registration_details.c.pre_first_name,
453+
users_pre_registration_details.c.pre_last_name,
454+
users_pre_registration_details.c.institution,
455+
users_pre_registration_details.c.pre_phone,
456+
users_pre_registration_details.c.address,
457+
users_pre_registration_details.c.city,
458+
users_pre_registration_details.c.state,
459+
users_pre_registration_details.c.postal_code,
460+
users_pre_registration_details.c.country,
461+
users_pre_registration_details.c.user_id,
462+
users_pre_registration_details.c.extras,
463+
users_pre_registration_details.c.created,
464+
users_pre_registration_details.c.account_request_status,
465+
users.c.id.label("user_id"),
466+
users.c.name.label("user_name"),
467+
users.c.first_name,
468+
users.c.last_name,
469+
users.c.email,
470+
users.c.phone,
471+
users.c.created_at,
472+
users.c.status,
473+
invited_by,
474+
)
475+
.select_from(joined_user_tables)
476+
.where(where_clause)
477+
.order_by(
478+
users_pre_registration_details.c.created.desc(), # newest pre-registered first
479+
users_pre_registration_details.c.pre_email,
480+
)
481+
.limit(limit)
482+
.offset(offset)
483+
)
484+
485+
print(
486+
"-" * 100,
487+
"\n",
488+
as_postgres_sql_query_str(main_query),
489+
"-" * 100,
490+
"\n",
491+
as_postgres_sql_query_str(count_query),
492+
) # DEBUG
493+
494+
async with pass_or_acquire_connection(engine, connection) as conn:
495+
# Get total count
496+
count_result = await conn.execute(count_query)
497+
total_count = count_result.scalar()
498+
499+
# Get user records
500+
result = await conn.execute(main_query)
501+
records = result.mappings().all()
502+
503+
return list(records), total_count
504+
505+
379506
async def get_user_products(
380507
engine: AsyncEngine,
381508
connection: AsyncConnection | None = None,
@@ -487,133 +614,6 @@ async def is_user_in_product_name(
487614
return value is not None
488615

489616

490-
async def list_users_for_admin(
491-
engine: AsyncEngine,
492-
connection: AsyncConnection | None = None,
493-
*,
494-
filter_approved: bool | None = None,
495-
limit: int = 50,
496-
offset: int = 0,
497-
include_deleted: bool = False,
498-
) -> tuple[list[dict[str, Any]], int]:
499-
"""
500-
Gets users data for admin with pagination support using SQLAlchemy expressions
501-
502-
Args:
503-
engine: The database engine
504-
connection: Optional existing connection to reuse
505-
filter_approved: If set, filters users by their approval status
506-
limit: Maximum number of users to return
507-
offset: Number of users to skip for pagination
508-
include_deleted: Whether to include users marked as deleted
509-
510-
Returns:
511-
Tuple of (list of user data, total count)
512-
"""
513-
514-
# Define the join between users and users_pre_registration_details
515-
joined_tables = users.outerjoin(
516-
users_pre_registration_details,
517-
users.c.id == users_pre_registration_details.c.user_id,
518-
)
519-
520-
# Basic where clause - exclude deleted by default
521-
where_conditions = []
522-
if not include_deleted:
523-
where_conditions.append(users.c.status != UserStatus.DELETED)
524-
525-
# Add filtering by approval status if requested
526-
if filter_approved is not None:
527-
if filter_approved:
528-
where_conditions.append(
529-
users_pre_registration_details.c.account_request_status
530-
== AccountRequestStatus.APPROVED
531-
)
532-
else:
533-
where_conditions.append(
534-
users_pre_registration_details.c.account_request_status
535-
!= AccountRequestStatus.APPROVED
536-
)
537-
538-
# Combine all conditions with AND
539-
where_clause = sa.and_(*where_conditions) if where_conditions else sa.true()
540-
541-
# Count query to get total number of users
542-
count_query = (
543-
sa.select(sa.func.count().label("total"))
544-
.select_from(joined_tables)
545-
.where(where_clause)
546-
)
547-
548-
# Main query to get user data
549-
invited_by = (
550-
sa.select(
551-
users.c.name,
552-
)
553-
.where(users_pre_registration_details.c.created_by == users.c.id)
554-
.label("invited_by")
555-
)
556-
557-
main_query = (
558-
sa.select(
559-
users.c.id.label("user_id"),
560-
users.c.name,
561-
sa.case(
562-
(users.c.email.is_(None), users_pre_registration_details.c.pre_email),
563-
else_=users.c.email,
564-
).label("email"),
565-
sa.case(
566-
(
567-
users.c.first_name.is_(None),
568-
users_pre_registration_details.c.pre_first_name,
569-
),
570-
else_=users.c.first_name,
571-
).label("first_name"),
572-
sa.case(
573-
(
574-
users.c.last_name.is_(None),
575-
users_pre_registration_details.c.pre_last_name,
576-
),
577-
else_=users.c.last_name,
578-
).label("last_name"),
579-
users.c.status,
580-
users.c.created,
581-
users_pre_registration_details.c.institution,
582-
sa.case(
583-
(
584-
users.c.phone.is_(None),
585-
users_pre_registration_details.c.pre_phone,
586-
),
587-
else_=users.c.phone,
588-
).label("phone"),
589-
users_pre_registration_details.c.address,
590-
users_pre_registration_details.c.city,
591-
users_pre_registration_details.c.state,
592-
users_pre_registration_details.c.postal_code,
593-
users_pre_registration_details.c.country,
594-
users_pre_registration_details.c.extras,
595-
users_pre_registration_details.c.account_request_status,
596-
invited_by,
597-
)
598-
.select_from(joined_tables)
599-
.where(where_clause)
600-
.order_by(users.c.created.desc()) # newest first
601-
.limit(limit)
602-
.offset(offset)
603-
)
604-
605-
async with pass_or_acquire_connection(engine, connection) as conn:
606-
# Get total count
607-
count_result = await conn.execute(count_query)
608-
total_count = count_result.scalar()
609-
610-
# Get user records
611-
result = await conn.execute(main_query)
612-
records = result.mappings().all()
613-
614-
return list(records), total_count
615-
616-
617617
#
618618
# USER PROFILE
619619
#

services/web/server/src/simcore_service_webserver/users/_users_rest.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,10 @@ async def pre_register_user_for_admin(request: web.Request) -> web.Response:
231231
pre_user_profile = await parse_request_body_as(PreRegisteredUserGet, request)
232232

233233
user_profile = await _users_service.pre_register_user(
234-
request.app, profile=pre_user_profile, creator_user_id=req_ctx.user_id
234+
request.app,
235+
profile=pre_user_profile,
236+
creator_user_id=req_ctx.user_id,
237+
product_name=req_ctx.product_name,
235238
)
236239
return envelope_json_response(
237240
user_profile.model_dump(**_RESPONSE_MODEL_MINIMAL_POLICY)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# create a PO user (w/o pre-registration)
2+
#
3+
# An user requests an account -> gets pre
4+
#
5+
#
6+
#

0 commit comments

Comments
 (0)