From f3c6273d01e0a38e857e80527cabb3c17829663e Mon Sep 17 00:00:00 2001 From: Matus Drobuliak <60785969+matusdrobuliak66@users.noreply.github.com> Date: Tue, 29 Oct 2024 19:08:26 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20rearranging=20`webserver`?= =?UTF-8?q?=20tests=20(#6633)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/integration/02/test_computation.py | 33 +---- .../with_dbs/{03 => 01}/folders/conftest.py | 0 .../{03 => 01}/folders/test_folders.py | 0 .../test_resource_manager.py | 0 .../with_dbs/{03 => 01}/products/conftest.py | 0 .../{03 => 01}/products/test_products_db.py | 0 .../products/test_products_handlers.py | 0 .../{03 => 01}/products/test_products_rpc.py | 0 .../with_dbs/{03 => 01}/wallets/conftest.py | 0 .../{03 => 01}/wallets/payments/conftest.py | 0 .../wallets/payments/test_payments.py | 0 .../wallets/payments/test_payments_methods.py | 0 .../wallets/payments/test_payments_rpc.py | 0 .../{03 => 01}/wallets/test_wallets.py | 0 .../{03 => 01}/wallets/test_wallets_groups.py | 0 .../{03 => 01}/workspaces/conftest.py | 0 .../{03 => 01}/workspaces/test_workspaces.py | 0 ...t_workspaces__folders_and_projects_crud.py | 0 ...t_workspaces__list_projects_full_search.py | 0 ...ces__moving_projects_between_workspaces.py | 0 .../workspaces/test_workspaces_groups.py | 0 .../server/tests/unit/with_dbs/03/conftest.py | 134 +---------------- .../server/tests/unit/with_dbs/conftest.py | 140 +++++++++++++++++- 23 files changed, 140 insertions(+), 167 deletions(-) rename services/web/server/tests/unit/with_dbs/{03 => 01}/folders/conftest.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/folders/test_folders.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/garbage_collector/test_resource_manager.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/products/conftest.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/products/test_products_db.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/products/test_products_handlers.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/products/test_products_rpc.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/wallets/conftest.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/wallets/payments/conftest.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/wallets/payments/test_payments.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/wallets/payments/test_payments_methods.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/wallets/payments/test_payments_rpc.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/wallets/test_wallets.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/wallets/test_wallets_groups.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/workspaces/conftest.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/workspaces/test_workspaces.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/workspaces/test_workspaces__folders_and_projects_crud.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/workspaces/test_workspaces__list_projects_full_search.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/workspaces/test_workspaces__moving_projects_between_workspaces.py (100%) rename services/web/server/tests/unit/with_dbs/{03 => 01}/workspaces/test_workspaces_groups.py (100%) diff --git a/services/web/server/tests/integration/02/test_computation.py b/services/web/server/tests/integration/02/test_computation.py index 0a73402e68d..98cd65e511d 100644 --- a/services/web/server/tests/integration/02/test_computation.py +++ b/services/web/server/tests/integration/02/test_computation.py @@ -95,28 +95,10 @@ def __str__(self) -> str: return f"{self.__class__.__name__}({items})" -def standard_role_response(): +def user_role_response(): return ( "user_role,expected", [ - pytest.param( - UserRole.ANONYMOUS, - _ExpectedResponseTuple( - ok=status.HTTP_401_UNAUTHORIZED, - created=status.HTTP_401_UNAUTHORIZED, - no_content=status.HTTP_401_UNAUTHORIZED, - confict=status.HTTP_401_UNAUTHORIZED, - ), - ), - pytest.param( - UserRole.GUEST, - _ExpectedResponseTuple( - ok=status.HTTP_200_OK, - created=status.HTTP_201_CREATED, - no_content=status.HTTP_204_NO_CONTENT, - confict=status.HTTP_409_CONFLICT, - ), - ), pytest.param( UserRole.USER, _ExpectedResponseTuple( @@ -126,15 +108,6 @@ def standard_role_response(): confict=status.HTTP_409_CONFLICT, ), ), - pytest.param( - UserRole.TESTER, - _ExpectedResponseTuple( - ok=status.HTTP_200_OK, - created=status.HTTP_201_CREATED, - no_content=status.HTTP_204_NO_CONTENT, - confict=status.HTTP_409_CONFLICT, - ), - ), ], ) @@ -365,7 +338,7 @@ async def _assert_and_wait_for_comp_task_states_to_be_transmitted_in_projects( ) -@pytest.mark.parametrize(*standard_role_response(), ids=str) +@pytest.mark.parametrize(*user_role_response(), ids=str) async def test_start_stop_computation( client: TestClient, sleeper_service: dict[str, str], @@ -438,7 +411,7 @@ async def test_start_stop_computation( ) -@pytest.mark.parametrize(*standard_role_response(), ids=str) +@pytest.mark.parametrize(*user_role_response(), ids=str) async def test_run_pipeline_and_check_state( client: TestClient, sleeper_service: dict[str, str], diff --git a/services/web/server/tests/unit/with_dbs/03/folders/conftest.py b/services/web/server/tests/unit/with_dbs/01/folders/conftest.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/folders/conftest.py rename to services/web/server/tests/unit/with_dbs/01/folders/conftest.py diff --git a/services/web/server/tests/unit/with_dbs/03/folders/test_folders.py b/services/web/server/tests/unit/with_dbs/01/folders/test_folders.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/folders/test_folders.py rename to services/web/server/tests/unit/with_dbs/01/folders/test_folders.py diff --git a/services/web/server/tests/unit/with_dbs/03/garbage_collector/test_resource_manager.py b/services/web/server/tests/unit/with_dbs/01/garbage_collector/test_resource_manager.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/garbage_collector/test_resource_manager.py rename to services/web/server/tests/unit/with_dbs/01/garbage_collector/test_resource_manager.py diff --git a/services/web/server/tests/unit/with_dbs/03/products/conftest.py b/services/web/server/tests/unit/with_dbs/01/products/conftest.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/products/conftest.py rename to services/web/server/tests/unit/with_dbs/01/products/conftest.py diff --git a/services/web/server/tests/unit/with_dbs/03/products/test_products_db.py b/services/web/server/tests/unit/with_dbs/01/products/test_products_db.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/products/test_products_db.py rename to services/web/server/tests/unit/with_dbs/01/products/test_products_db.py diff --git a/services/web/server/tests/unit/with_dbs/03/products/test_products_handlers.py b/services/web/server/tests/unit/with_dbs/01/products/test_products_handlers.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/products/test_products_handlers.py rename to services/web/server/tests/unit/with_dbs/01/products/test_products_handlers.py diff --git a/services/web/server/tests/unit/with_dbs/03/products/test_products_rpc.py b/services/web/server/tests/unit/with_dbs/01/products/test_products_rpc.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/products/test_products_rpc.py rename to services/web/server/tests/unit/with_dbs/01/products/test_products_rpc.py diff --git a/services/web/server/tests/unit/with_dbs/03/wallets/conftest.py b/services/web/server/tests/unit/with_dbs/01/wallets/conftest.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/wallets/conftest.py rename to services/web/server/tests/unit/with_dbs/01/wallets/conftest.py diff --git a/services/web/server/tests/unit/with_dbs/03/wallets/payments/conftest.py b/services/web/server/tests/unit/with_dbs/01/wallets/payments/conftest.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/wallets/payments/conftest.py rename to services/web/server/tests/unit/with_dbs/01/wallets/payments/conftest.py diff --git a/services/web/server/tests/unit/with_dbs/03/wallets/payments/test_payments.py b/services/web/server/tests/unit/with_dbs/01/wallets/payments/test_payments.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/wallets/payments/test_payments.py rename to services/web/server/tests/unit/with_dbs/01/wallets/payments/test_payments.py diff --git a/services/web/server/tests/unit/with_dbs/03/wallets/payments/test_payments_methods.py b/services/web/server/tests/unit/with_dbs/01/wallets/payments/test_payments_methods.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/wallets/payments/test_payments_methods.py rename to services/web/server/tests/unit/with_dbs/01/wallets/payments/test_payments_methods.py diff --git a/services/web/server/tests/unit/with_dbs/03/wallets/payments/test_payments_rpc.py b/services/web/server/tests/unit/with_dbs/01/wallets/payments/test_payments_rpc.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/wallets/payments/test_payments_rpc.py rename to services/web/server/tests/unit/with_dbs/01/wallets/payments/test_payments_rpc.py diff --git a/services/web/server/tests/unit/with_dbs/03/wallets/test_wallets.py b/services/web/server/tests/unit/with_dbs/01/wallets/test_wallets.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/wallets/test_wallets.py rename to services/web/server/tests/unit/with_dbs/01/wallets/test_wallets.py diff --git a/services/web/server/tests/unit/with_dbs/03/wallets/test_wallets_groups.py b/services/web/server/tests/unit/with_dbs/01/wallets/test_wallets_groups.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/wallets/test_wallets_groups.py rename to services/web/server/tests/unit/with_dbs/01/wallets/test_wallets_groups.py diff --git a/services/web/server/tests/unit/with_dbs/03/workspaces/conftest.py b/services/web/server/tests/unit/with_dbs/01/workspaces/conftest.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/workspaces/conftest.py rename to services/web/server/tests/unit/with_dbs/01/workspaces/conftest.py diff --git a/services/web/server/tests/unit/with_dbs/03/workspaces/test_workspaces.py b/services/web/server/tests/unit/with_dbs/01/workspaces/test_workspaces.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/workspaces/test_workspaces.py rename to services/web/server/tests/unit/with_dbs/01/workspaces/test_workspaces.py diff --git a/services/web/server/tests/unit/with_dbs/03/workspaces/test_workspaces__folders_and_projects_crud.py b/services/web/server/tests/unit/with_dbs/01/workspaces/test_workspaces__folders_and_projects_crud.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/workspaces/test_workspaces__folders_and_projects_crud.py rename to services/web/server/tests/unit/with_dbs/01/workspaces/test_workspaces__folders_and_projects_crud.py diff --git a/services/web/server/tests/unit/with_dbs/03/workspaces/test_workspaces__list_projects_full_search.py b/services/web/server/tests/unit/with_dbs/01/workspaces/test_workspaces__list_projects_full_search.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/workspaces/test_workspaces__list_projects_full_search.py rename to services/web/server/tests/unit/with_dbs/01/workspaces/test_workspaces__list_projects_full_search.py diff --git a/services/web/server/tests/unit/with_dbs/03/workspaces/test_workspaces__moving_projects_between_workspaces.py b/services/web/server/tests/unit/with_dbs/01/workspaces/test_workspaces__moving_projects_between_workspaces.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/workspaces/test_workspaces__moving_projects_between_workspaces.py rename to services/web/server/tests/unit/with_dbs/01/workspaces/test_workspaces__moving_projects_between_workspaces.py diff --git a/services/web/server/tests/unit/with_dbs/03/workspaces/test_workspaces_groups.py b/services/web/server/tests/unit/with_dbs/01/workspaces/test_workspaces_groups.py similarity index 100% rename from services/web/server/tests/unit/with_dbs/03/workspaces/test_workspaces_groups.py rename to services/web/server/tests/unit/with_dbs/01/workspaces/test_workspaces_groups.py diff --git a/services/web/server/tests/unit/with_dbs/03/conftest.py b/services/web/server/tests/unit/with_dbs/03/conftest.py index 8e4e8af6188..3d75d45f3dc 100644 --- a/services/web/server/tests/unit/with_dbs/03/conftest.py +++ b/services/web/server/tests/unit/with_dbs/03/conftest.py @@ -4,25 +4,11 @@ # pylint: disable=too-many-arguments -from collections.abc import AsyncIterable, AsyncIterator -from decimal import Decimal +from collections.abc import AsyncIterator import aiopg.sa import pytest -import sqlalchemy as sa -from aiopg.sa import create_engine -from aiopg.sa.connection import SAConnection -from faker import Faker -from models_library.products import ProductName -from pytest_simcore.helpers.faker_factories import random_product -from simcore_postgres_database.models.products import products -from simcore_postgres_database.models.products_prices import products_prices from simcore_postgres_database.models.user_preferences import user_preferences_frontend -from simcore_postgres_database.utils_products import get_or_create_product_group -from simcore_service_webserver.statics._constants import ( - FRONTEND_APP_DEFAULT, - FRONTEND_APPS_AVAILABLE, -) @pytest.fixture @@ -32,121 +18,3 @@ async def drop_all_preferences( yield async with aiopg_engine.acquire() as conn: await conn.execute(user_preferences_frontend.delete()) - - -@pytest.fixture -async def _pre_connection(postgres_db: sa.engine.Engine) -> AsyncIterable[SAConnection]: - # NOTE: call to postgres BEFORE app starts - async with await create_engine( - f"{postgres_db.url}" - ) as engine, engine.acquire() as conn: - yield conn - - -@pytest.fixture -async def all_products_names( - _pre_connection: SAConnection, -) -> AsyncIterable[list[ProductName]]: - # default product - result = await _pre_connection.execute( - products.select().order_by(products.c.priority) - ) - rows = await result.fetchall() - assert rows - assert len(rows) == 1 - osparc_product_row = rows[0] - assert osparc_product_row.name == FRONTEND_APP_DEFAULT - assert osparc_product_row.priority == 0 - - # creates remaing products for front-end - priority = 1 - for name in FRONTEND_APPS_AVAILABLE: - if name != FRONTEND_APP_DEFAULT: - result = await _pre_connection.execute( - products.insert().values( - random_product( - name=name, - priority=priority, - login_settings=osparc_product_row.login_settings, - group_id=None, - ) - ) - ) - await get_or_create_product_group(_pre_connection, product_name=name) - priority += 1 - - # get all products - result = await _pre_connection.execute( - sa.select(products.c.name).order_by(products.c.priority) - ) - rows = await result.fetchall() - - yield [r.name for r in rows] - - await _pre_connection.execute(products_prices.delete()) - await _pre_connection.execute( - products.delete().where(products.c.name != FRONTEND_APP_DEFAULT) - ) - - -@pytest.fixture -async def all_product_prices( - _pre_connection: SAConnection, - all_products_names: list[ProductName], - faker: Faker, -) -> dict[ProductName, Decimal | None]: - """Initial list of prices for all products""" - - # initial list of prices - product_price = { - "osparc": Decimal(0), # free of charge - "tis": Decimal(5), - "tiplite": Decimal(5), - "s4l": Decimal(9), - "s4llite": Decimal(0), # free of charge - "s4lacad": Decimal(1.1), - } - - result = {} - for product_name in all_products_names: - usd_or_none = product_price.get(product_name, None) - if usd_or_none is not None: - await _pre_connection.execute( - products_prices.insert().values( - product_name=product_name, - usd_per_credit=usd_or_none, - comment=faker.sentence(), - min_payment_amount_usd=10, - stripe_price_id=faker.pystr(), - stripe_tax_rate_id=faker.pystr(), - ) - ) - - result[product_name] = usd_or_none - - return result - - -@pytest.fixture -async def latest_osparc_price( - all_product_prices: dict[ProductName, Decimal], - _pre_connection: SAConnection, -) -> Decimal: - """This inserts a new price for osparc in the history - (i.e. the old price of osparc is still in the database) - """ - - usd = await _pre_connection.scalar( - products_prices.insert() - .values( - product_name="osparc", - usd_per_credit=all_product_prices["osparc"] + 5, - comment="New price for osparc", - stripe_price_id="stripe-price-id", - stripe_tax_rate_id="stripe-tax-rate-id", - ) - .returning(products_prices.c.usd_per_credit) - ) - assert usd is not None - assert usd != all_product_prices["osparc"] - return Decimal(usd) diff --git a/services/web/server/tests/unit/with_dbs/conftest.py b/services/web/server/tests/unit/with_dbs/conftest.py index f4f527179b1..84ffd71830f 100644 --- a/services/web/server/tests/unit/with_dbs/conftest.py +++ b/services/web/server/tests/unit/with_dbs/conftest.py @@ -17,8 +17,9 @@ import textwrap from collections.abc import AsyncIterator, Awaitable, Callable, Iterator from copy import deepcopy +from decimal import Decimal from pathlib import Path -from typing import Any, Final +from typing import Any, AsyncIterable, Final from unittest import mock from unittest.mock import AsyncMock, MagicMock @@ -34,6 +35,8 @@ import sqlalchemy as sa from aiohttp import web from aiohttp.test_utils import TestClient, TestServer +from aiopg.sa import create_engine +from aiopg.sa.connection import SAConnection from faker import Faker from models_library.api_schemas_directorv2.dynamic_services import DynamicServiceGet from models_library.products import ProductName @@ -41,6 +44,7 @@ from pydantic import ByteSize, parse_obj_as from pytest_mock import MockerFixture from pytest_simcore.helpers.dict_tools import ConfigDict +from pytest_simcore.helpers.faker_factories import random_product from pytest_simcore.helpers.monkeypatch_envs import setenvs_from_dict from pytest_simcore.helpers.typing_env import EnvVarsDict from pytest_simcore.helpers.webserver_login import NewUser, UserInfoDict @@ -56,7 +60,12 @@ from simcore_postgres_database.models.groups_extra_properties import ( groups_extra_properties, ) -from simcore_postgres_database.utils_products import get_default_product_name +from simcore_postgres_database.models.products import products +from simcore_postgres_database.models.products_prices import products_prices +from simcore_postgres_database.utils_products import ( + get_default_product_name, + get_or_create_product_group, +) from simcore_service_webserver._constants import INDEX_RESOURCE_NAME from simcore_service_webserver.application import create_application from simcore_service_webserver.db.plugin import get_database_engine @@ -67,6 +76,10 @@ list_user_groups_with_read_access, ) from simcore_service_webserver.projects.models import ProjectDict +from simcore_service_webserver.statics._constants import ( + FRONTEND_APP_DEFAULT, + FRONTEND_APPS_AVAILABLE, +) from sqlalchemy import exc as sql_exceptions CURRENT_DIR = Path(sys.argv[0] if __name__ == "__main__" else __file__).resolve().parent @@ -529,8 +542,6 @@ def postgres_db( @pytest.fixture async def aiopg_engine(postgres_db: sa.engine.Engine) -> AsyncIterator[aiopg.sa.Engine]: - from aiopg.sa import create_engine - engine = await create_engine(f"{postgres_db.url}") assert engine @@ -762,3 +773,124 @@ async def with_permitted_override_services_specifications( .where(groups_extra_properties.c.group_id == 1) .values(override_services_specifications=old_value) ) + + +# PRODUCT PRICES FIXTURES ------------------------------------------------------- + + +@pytest.fixture +async def _pre_connection(postgres_db: sa.engine.Engine) -> AsyncIterable[SAConnection]: + # NOTE: call to postgres BEFORE app starts + async with await create_engine( + f"{postgres_db.url}" + ) as engine, engine.acquire() as conn: + yield conn + + +@pytest.fixture +async def all_products_names( + _pre_connection: SAConnection, +) -> AsyncIterable[list[ProductName]]: + # default product + result = await _pre_connection.execute( + products.select().order_by(products.c.priority) + ) + rows = await result.fetchall() + assert rows + assert len(rows) == 1 + osparc_product_row = rows[0] + assert osparc_product_row.name == FRONTEND_APP_DEFAULT + assert osparc_product_row.priority == 0 + + # creates remaing products for front-end + priority = 1 + for name in FRONTEND_APPS_AVAILABLE: + if name != FRONTEND_APP_DEFAULT: + result = await _pre_connection.execute( + products.insert().values( + random_product( + name=name, + priority=priority, + login_settings=osparc_product_row.login_settings, + group_id=None, + ) + ) + ) + await get_or_create_product_group(_pre_connection, product_name=name) + priority += 1 + + # get all products + result = await _pre_connection.execute( + sa.select(products.c.name).order_by(products.c.priority) + ) + rows = await result.fetchall() + + yield [r.name for r in rows] + + await _pre_connection.execute(products_prices.delete()) + await _pre_connection.execute( + products.delete().where(products.c.name != FRONTEND_APP_DEFAULT) + ) + + +@pytest.fixture +async def all_product_prices( + _pre_connection: SAConnection, + all_products_names: list[ProductName], + faker: Faker, +) -> dict[ProductName, Decimal | None]: + """Initial list of prices for all products""" + + # initial list of prices + product_price = { + "osparc": Decimal(0), # free of charge + "tis": Decimal(5), + "tiplite": Decimal(5), + "s4l": Decimal(9), + "s4llite": Decimal(0), # free of charge + "s4lacad": Decimal(1.1), + } + + result = {} + for product_name in all_products_names: + usd_or_none = product_price.get(product_name, None) + if usd_or_none is not None: + await _pre_connection.execute( + products_prices.insert().values( + product_name=product_name, + usd_per_credit=usd_or_none, + comment=faker.sentence(), + min_payment_amount_usd=10, + stripe_price_id=faker.pystr(), + stripe_tax_rate_id=faker.pystr(), + ) + ) + + result[product_name] = usd_or_none + + return result + + +@pytest.fixture +async def latest_osparc_price( + all_product_prices: dict[ProductName, Decimal], + _pre_connection: SAConnection, +) -> Decimal: + """This inserts a new price for osparc in the history + (i.e. the old price of osparc is still in the database) + """ + + usd = await _pre_connection.scalar( + products_prices.insert() + .values( + product_name="osparc", + usd_per_credit=all_product_prices["osparc"] + 5, + comment="New price for osparc", + stripe_price_id="stripe-price-id", + stripe_tax_rate_id="stripe-tax-rate-id", + ) + .returning(products_prices.c.usd_per_credit) + ) + assert usd is not None + assert usd != all_product_prices["osparc"] + return Decimal(usd)