Skip to content

Commit 3b2d9fb

Browse files
committed
fixing test
1 parent 93c196a commit 3b2d9fb

File tree

3 files changed

+63
-42
lines changed

3 files changed

+63
-42
lines changed

services/web/server/src/simcore_service_webserver/folders/_folders_repository.py

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,6 @@ def _create_private_workspace_query(
9393
return (
9494
sql.select(
9595
*_FOLDER_DB_MODEL_COLS,
96-
# NOTE: design INVARIANT:
97-
# a user in his private workspace owns his folders
9896
sql.func.json_build_object(
9997
"read",
10098
sa.text("true"),
@@ -132,8 +130,6 @@ def _create_shared_workspace_query(
132130
shared_workspace_query = (
133131
sql.select(
134132
*_FOLDER_DB_MODEL_COLS,
135-
# NOTE: design INVARIANT:
136-
# a user access rights to a folder in a SHARED workspace is inherited from the workspace
137133
workspace_access_rights_subquery.c.my_access_rights,
138134
)
139135
.select_from(
@@ -160,12 +156,12 @@ def _create_shared_workspace_query(
160156
return shared_workspace_query
161157

162158

163-
def _to_sql_expression(table: sa.Table, order_by: OrderBy):
159+
def _to_expression(order_by: OrderBy):
164160
direction_func: Callable = {
165161
OrderDirection.ASC: sql.asc,
166162
OrderDirection.DESC: sql.desc,
167163
}[order_by.direction]
168-
return direction_func(table.columns[order_by.field])
164+
return direction_func(folders_v2.columns[order_by.field])
169165

170166

171167
async def list_( # pylint: disable=too-many-arguments,too-many-branches
@@ -249,9 +245,7 @@ async def list_( # pylint: disable=too-many-arguments,too-many-branches
249245

250246
# Ordering and pagination
251247
list_query = (
252-
combined_query.order_by(_to_sql_expression(folders_v2, order_by))
253-
.offset(offset)
254-
.limit(limit)
248+
combined_query.order_by(_to_expression(order_by)).offset(offset).limit(limit)
255249
)
256250

257251
async with pass_or_acquire_connection(get_asyncpg_engine(app), connection) as conn:
@@ -279,8 +273,9 @@ async def list_trashed_folders(
279273
) -> tuple[int, list[FolderDB]]:
280274
"""
281275
NOTE: this is app-wide i.e. no product, user or workspace filtered
276+
TODO: check with MD about workspaces
282277
"""
283-
base_query = sql.select(*_FOLDER_DB_MODEL_COLS).where(
278+
base_query = sql.select(_FOLDER_DB_MODEL_COLS).where(
284279
folders_v2.c.trashed.is_not(None)
285280
)
286281

@@ -299,9 +294,7 @@ async def list_trashed_folders(
299294

300295
# Ordering and pagination
301296
list_query = (
302-
base_query.order_by(_to_sql_expression(folders_v2, order_by))
303-
.offset(offset)
304-
.limit(limit)
297+
base_query.order_by(_to_expression(order_by)).offset(offset).limit(limit)
305298
)
306299

307300
async with pass_or_acquire_connection(get_asyncpg_engine(app), connection) as conn:
@@ -467,24 +460,6 @@ async def delete_recursively(
467460
)
468461

469462

470-
def _create_folder_hierarchy_cte(base_query: Select):
471-
folder_hierarchy_cte = base_query.cte(name="folder_hierarchy", recursive=True)
472-
473-
# Step 2: Define the recursive case
474-
folder_alias = aliased(folders_v2)
475-
recursive_query = sql.select(
476-
folder_alias.c.folder_id, folder_alias.c.parent_folder_id
477-
).select_from(
478-
folder_alias.join(
479-
folder_hierarchy_cte,
480-
folder_alias.c.parent_folder_id == folder_hierarchy_cte.c.folder_id,
481-
)
482-
)
483-
484-
# Step 3: Combine base and recursive cases into a CTE
485-
return folder_hierarchy_cte.union_all(recursive_query)
486-
487-
488463
async def get_projects_recursively_only_if_user_is_owner(
489464
app: web.Application,
490465
connection: AsyncConnection | None = None,
@@ -511,9 +486,21 @@ async def get_projects_recursively_only_if_user_is_owner(
511486
(folders_v2.c.folder_id == folder_id) # <-- specified folder id
512487
& (folders_v2.c.product_name == product_name)
513488
)
489+
folder_hierarchy_cte = base_query.cte(name="folder_hierarchy", recursive=True)
514490

515-
# Step 2,3
516-
folder_hierarchy_cte = _create_folder_hierarchy_cte(base_query)
491+
# Step 2: Define the recursive case
492+
folder_alias = aliased(folders_v2)
493+
recursive_query = sql.select(
494+
folder_alias.c.folder_id, folder_alias.c.parent_folder_id
495+
).select_from(
496+
folder_alias.join(
497+
folder_hierarchy_cte,
498+
folder_alias.c.parent_folder_id == folder_hierarchy_cte.c.folder_id,
499+
)
500+
)
501+
502+
# Step 3: Combine base and recursive cases into a CTE
503+
folder_hierarchy_cte = folder_hierarchy_cte.union_all(recursive_query)
517504

518505
# Step 4: Execute the query to get all descendants
519506
final_query = sql.select(folder_hierarchy_cte)
@@ -557,9 +544,21 @@ async def get_all_folders_and_projects_ids_recursively(
557544
(folders_v2.c.folder_id == folder_id) # <-- specified folder id
558545
& (folders_v2.c.product_name == product_name)
559546
)
547+
folder_hierarchy_cte = base_query.cte(name="folder_hierarchy", recursive=True)
560548

561-
# Step 2, 3
562-
folder_hierarchy_cte = _create_folder_hierarchy_cte(base_query)
549+
# Step 2: Define the recursive case
550+
folder_alias = aliased(folders_v2)
551+
recursive_query = sql.select(
552+
folder_alias.c.folder_id, folder_alias.c.parent_folder_id
553+
).select_from(
554+
folder_alias.join(
555+
folder_hierarchy_cte,
556+
folder_alias.c.parent_folder_id == folder_hierarchy_cte.c.folder_id,
557+
)
558+
)
559+
560+
# Step 3: Combine base and recursive cases into a CTE
561+
folder_hierarchy_cte = folder_hierarchy_cte.union_all(recursive_query)
563562

564563
# Step 4: Execute the query to get all descendants
565564
final_query = sql.select(folder_hierarchy_cte)
@@ -594,9 +593,21 @@ async def get_folders_recursively(
594593
(folders_v2.c.folder_id == folder_id) # <-- specified folder id
595594
& (folders_v2.c.product_name == product_name)
596595
)
596+
folder_hierarchy_cte = base_query.cte(name="folder_hierarchy", recursive=True)
597+
598+
# Step 2: Define the recursive case
599+
folder_alias = aliased(folders_v2)
600+
recursive_query = sql.select(
601+
folder_alias.c.folder_id, folder_alias.c.parent_folder_id
602+
).select_from(
603+
folder_alias.join(
604+
folder_hierarchy_cte,
605+
folder_alias.c.parent_folder_id == folder_hierarchy_cte.c.folder_id,
606+
)
607+
)
597608

598-
# Step 2, 3
599-
folder_hierarchy_cte = _create_folder_hierarchy_cte(base_query)
609+
# Step 3: Combine base and recursive cases into a CTE
610+
folder_hierarchy_cte = folder_hierarchy_cte.union_all(recursive_query)
600611

601612
# Step 4: Execute the query to get all descendants
602613
final_query = sql.select(folder_hierarchy_cte)

services/web/server/tests/unit/isolated/conftest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ def mock_env_devel_environment(
102102
monkeypatch,
103103
envs={
104104
"WEBSERVER_DEV_FEATURES_ENABLED": "1",
105+
"TRACING_OPENTELEMETRY_COLLECTOR_ENDPOINT": "null",
106+
"TRACING_OPENTELEMETRY_COLLECTOR_PORT": "null",
105107
},
106108
)
107109

services/web/server/tests/unit/isolated/products/test_products_model.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
import pytest
1111
import simcore_service_webserver.products
1212
import sqlalchemy as sa
13+
from faker import Faker
1314
from models_library.basic_regex import TWILIO_ALPHANUMERIC_SENDER_ID_RE
1415
from models_library.products import ProductName
1516
from pydantic import BaseModel, ValidationError
17+
from pytest_simcore.helpers.faker_factories import random_product
1618
from pytest_simcore.pydantic_models import (
1719
assert_validation_model,
1820
walk_model_examples_in_package,
@@ -124,13 +126,19 @@ def test_safe_load_empty_blanks_on_string_cols_from_db(
124126
}
125127

126128

127-
@pytest.mark.parametrize("product_name", list(FRONTEND_APPS_AVAILABLE))
129+
@pytest.mark.parametrize("expected_product_name", list(FRONTEND_APPS_AVAILABLE))
128130
def test_product_name_needs_front_end(
129-
product_name: ProductName, fake_product_from_db: dict[str, Any]
131+
faker: Faker,
132+
expected_product_name: ProductName,
133+
product_db_server_defaults: dict[str, Any],
130134
):
131-
fake_product_from_db.update(name=product_name)
132-
product = Product.model_validate(fake_product_from_db)
133-
assert product.name == product_name
135+
product_from_db = random_product(
136+
name=expected_product_name,
137+
fake=faker,
138+
**product_db_server_defaults,
139+
)
140+
product = Product.model_validate(product_from_db)
141+
assert product.name == expected_product_name
134142

135143

136144
def test_product_name_invalid(fake_product_from_db: dict[str, Any]):

0 commit comments

Comments
 (0)