From b9036d8f8702bf01b18610813c8cfb36de2e5183 Mon Sep 17 00:00:00 2001 From: matusdrobuliak66 Date: Fri, 20 Dec 2024 13:37:36 +0100 Subject: [PATCH] list/get checkouts --- .../web-server/_licensed_items_checkouts.py | 57 ++++++++ .../licensed_items_checkouts.py | 29 +++- .../webserver/licenses/licensed_items.py | 10 +- ...pi.py => _licensed_items_checkouts_api.py} | 100 ++++++++++++- .../_licensed_items_checkouts_handlers.py | 131 ++++++++++++++++++ .../_licensed_items_checkouts_models.py | 56 ++++++++ .../licenses/_licensed_items_purchases_api.py | 1 + .../licenses/_rpc.py | 58 +++++--- .../test_licensed_items_checkouts_handlers.py | 84 +++++++++++ .../test_licensed_items_purchases_handlers.py | 2 +- .../with_dbs/04/licenses/test_licenses_rpc.py | 8 +- 11 files changed, 498 insertions(+), 38 deletions(-) create mode 100644 api/specs/web-server/_licensed_items_checkouts.py rename services/web/server/src/simcore_service_webserver/licenses/{_licensed_checkouts_api.py => _licensed_items_checkouts_api.py} (55%) create mode 100644 services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_handlers.py create mode 100644 services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_models.py create mode 100644 services/web/server/tests/unit/with_dbs/04/licenses/test_licensed_items_checkouts_handlers.py diff --git a/api/specs/web-server/_licensed_items_checkouts.py b/api/specs/web-server/_licensed_items_checkouts.py new file mode 100644 index 00000000000..cfc51a7c424 --- /dev/null +++ b/api/specs/web-server/_licensed_items_checkouts.py @@ -0,0 +1,57 @@ +""" Helper script to generate OAS automatically +""" + +# pylint: disable=redefined-outer-name +# pylint: disable=unused-argument +# pylint: disable=unused-variable +# pylint: disable=too-many-arguments + +from typing import Annotated + +from _common import as_query +from fastapi import APIRouter, Depends +from models_library.api_schemas_webserver.licensed_items_purchases import ( + LicensedItemPurchaseGet, +) +from models_library.generics import Envelope +from models_library.rest_error import EnvelopedError +from models_library.rest_pagination import Page +from simcore_service_webserver._meta import API_VTAG +from simcore_service_webserver.licenses._exceptions_handlers import _TO_HTTP_ERROR_MAP +from simcore_service_webserver.licenses._licensed_items_checkouts_models import ( + LicensedItemCheckoutPathParams, + LicensedItemsCheckoutsListQueryParams, +) +from simcore_service_webserver.wallets._handlers import WalletsPathParams + +router = APIRouter( + prefix=f"/{API_VTAG}", + tags=[ + "licenses", + ], + responses={ + i.status_code: {"model": EnvelopedError} for i in _TO_HTTP_ERROR_MAP.values() + }, +) + + +@router.get( + "/wallets/{wallet_id}/licensed-items-checkouts", + response_model=Page[LicensedItemPurchaseGet], + tags=["wallets"], +) +async def list_licensed_item_checkouts_for_wallet( + _path: Annotated[WalletsPathParams, Depends()], + _query: Annotated[as_query(LicensedItemsCheckoutsListQueryParams), Depends()], +): + ... + + +@router.get( + "/licensed-items-checkouts/{licensed_item_checkout_id}", + response_model=Envelope[LicensedItemPurchaseGet], +) +async def get_licensed_item_checkout( + _path: Annotated[LicensedItemCheckoutPathParams, Depends()], +): + ... diff --git a/packages/models-library/src/models_library/api_schemas_webserver/licensed_items_checkouts.py b/packages/models-library/src/models_library/api_schemas_webserver/licensed_items_checkouts.py index a3ee122ddee..c8fd22ce581 100644 --- a/packages/models-library/src/models_library/api_schemas_webserver/licensed_items_checkouts.py +++ b/packages/models-library/src/models_library/api_schemas_webserver/licensed_items_checkouts.py @@ -1,7 +1,7 @@ from datetime import datetime from typing import NamedTuple -from pydantic import PositiveInt +from pydantic import BaseModel, PositiveInt from ..licensed_items import LicensedItemID from ..products import ProductName @@ -10,8 +10,29 @@ from ..wallets import WalletID from ._base import OutputSchema +# RPC -class LicensedItemCheckoutGet(OutputSchema): + +class LicensedItemCheckoutRpcGet(BaseModel): + licensed_item_checkout_id: LicensedItemCheckoutID + licensed_item_id: LicensedItemID + wallet_id: WalletID + user_id: UserID + product_name: ProductName + started_at: datetime + stopped_at: datetime | None + num_of_seats: int + + +class LicensedItemCheckoutRpcGetPage(NamedTuple): + items: list[LicensedItemCheckoutRpcGet] + total: PositiveInt + + +# Rest + + +class LicensedItemCheckoutRestGet(OutputSchema): licensed_item_checkout_id: LicensedItemCheckoutID licensed_item_id: LicensedItemID wallet_id: WalletID @@ -22,6 +43,6 @@ class LicensedItemCheckoutGet(OutputSchema): num_of_seats: int -class LicensedItemUsageGetPage(NamedTuple): - items: list[LicensedItemCheckoutGet] +class LicensedItemCheckoutRestGetPage(NamedTuple): + items: list[LicensedItemCheckoutRestGet] total: PositiveInt diff --git a/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/licenses/licensed_items.py b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/licenses/licensed_items.py index f767882d247..0f86ab63d79 100644 --- a/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/licenses/licensed_items.py +++ b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/licenses/licensed_items.py @@ -6,7 +6,7 @@ LicensedItemGetPage, ) from models_library.api_schemas_webserver.licensed_items_checkouts import ( - LicensedItemCheckoutGet, + LicensedItemCheckoutRpcGet, ) from models_library.licensed_items import LicensedItemID from models_library.products import ProductName @@ -78,7 +78,7 @@ async def checkout_licensed_item_for_wallet( licensed_item_id: LicensedItemID, num_of_seats: int, service_run_id: ServiceRunID, -) -> LicensedItemCheckoutGet: +) -> LicensedItemCheckoutRpcGet: result = await rabbitmq_rpc_client.request( WEBSERVER_RPC_NAMESPACE, TypeAdapter(RPCMethodName).validate_python("checkout_licensed_item_for_wallet"), @@ -89,7 +89,7 @@ async def checkout_licensed_item_for_wallet( num_of_seats=num_of_seats, service_run_id=service_run_id, ) - assert isinstance(result, LicensedItemCheckoutGet) # nosec + assert isinstance(result, LicensedItemCheckoutRpcGet) # nosec return result @@ -100,7 +100,7 @@ async def release_licensed_item_for_wallet( product_name: ProductName, user_id: UserID, licensed_item_checkout_id: LicensedItemCheckoutID, -) -> LicensedItemCheckoutGet: +) -> LicensedItemCheckoutRpcGet: result = await rabbitmq_rpc_client.request( WEBSERVER_RPC_NAMESPACE, TypeAdapter(RPCMethodName).validate_python("release_licensed_item_for_wallet"), @@ -108,5 +108,5 @@ async def release_licensed_item_for_wallet( user_id=user_id, licensed_item_checkout_id=licensed_item_checkout_id, ) - assert isinstance(result, LicensedItemCheckoutGet) # nosec + assert isinstance(result, LicensedItemCheckoutRpcGet) # nosec return result diff --git a/services/web/server/src/simcore_service_webserver/licenses/_licensed_checkouts_api.py b/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_api.py similarity index 55% rename from services/web/server/src/simcore_service_webserver/licenses/_licensed_checkouts_api.py rename to services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_api.py index ba140d565d5..87a8aaf14c5 100644 --- a/services/web/server/src/simcore_service_webserver/licenses/_licensed_checkouts_api.py +++ b/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_api.py @@ -2,14 +2,12 @@ from models_library.api_schemas_resource_usage_tracker import ( licensed_items_checkouts as rut_licensed_items_checkouts, ) -from models_library.api_schemas_webserver import ( - licensed_items_checkouts as webserver_licensed_items_checkouts, -) from models_library.licensed_items import LicensedItemID from models_library.products import ProductName from models_library.resource_tracker_licensed_items_checkouts import ( LicensedItemCheckoutID, ) +from models_library.rest_ordering import OrderBy from models_library.services_types import ServiceRunID from models_library.users import UserID from models_library.wallets import WalletID @@ -20,6 +18,94 @@ from ..rabbitmq import get_rabbitmq_rpc_client from ..users.api import get_user from ..wallets.api import get_wallet_by_user +from ._licensed_items_checkouts_models import ( + LicensedItemCheckoutGet, + LicensedItemCheckoutGetPage, +) + + +async def list_licensed_items_checkouts_for_wallet( + app: web.Application, + *, + # access context + product_name: ProductName, + user_id: UserID, + wallet_id: WalletID, + offset: int, + limit: int, + order_by: OrderBy, +) -> LicensedItemCheckoutGetPage: + # Check whether user has access to the wallet + await get_wallet_by_user( + app, + user_id=user_id, + wallet_id=wallet_id, + product_name=product_name, + ) + + rpc_client = get_rabbitmq_rpc_client(app) + + result = await licensed_items_checkouts.get_licensed_items_checkouts_page( + rpc_client, + product_name=product_name, + filter_wallet_id=wallet_id, + offset=offset, + limit=limit, + order_by=order_by, + ) + + return LicensedItemCheckoutGetPage( + total=result.total, + items=[ + LicensedItemCheckoutGet.model_construct( + licensed_item_checkout_id=checkout_item.licensed_item_checkout_id, + licensed_item_id=checkout_item.licensed_item_id, + wallet_id=checkout_item.wallet_id, + user_id=checkout_item.user_id, + product_name=checkout_item.product_name, + started_at=checkout_item.started_at, + stopped_at=checkout_item.stopped_at, + num_of_seats=checkout_item.num_of_seats, + ) + for checkout_item in result.items + ], + ) + + +async def get_licensed_item_checkout( + app: web.Application, + *, + # access context + product_name: ProductName, + user_id: UserID, + licensed_item_checkout_id: LicensedItemCheckoutID, +) -> LicensedItemCheckoutGet: + rpc_client = get_rabbitmq_rpc_client(app) + + checkout_item = await licensed_items_checkouts.get_licensed_item_checkout( + rpc_client, + product_name=product_name, + licensed_item_checkout_id=licensed_item_checkout_id, + ) + + # Check whether user has access to the wallet + await get_wallet_by_user( + app, + user_id=user_id, + wallet_id=checkout_item.wallet_id, + product_name=product_name, + ) + + return LicensedItemCheckoutGet.model_construct( + licensed_item_checkout_id=checkout_item.licensed_item_checkout_id, + licensed_item_id=checkout_item.licensed_item_id, + wallet_id=checkout_item.wallet_id, + user_id=checkout_item.user_id, + product_name=checkout_item.product_name, + started_at=checkout_item.started_at, + stopped_at=checkout_item.stopped_at, + num_of_seats=checkout_item.num_of_seats, + ) async def checkout_licensed_item_for_wallet( @@ -33,7 +119,7 @@ async def checkout_licensed_item_for_wallet( licensed_item_id: LicensedItemID, num_of_seats: int, service_run_id: ServiceRunID, -) -> webserver_licensed_items_checkouts.LicensedItemCheckoutGet: +) -> LicensedItemCheckoutGet: # Check whether user has access to the wallet await get_wallet_by_user( app, @@ -58,7 +144,7 @@ async def checkout_licensed_item_for_wallet( ) ) - return webserver_licensed_items_checkouts.LicensedItemCheckoutGet( + return LicensedItemCheckoutGet.model_construct( licensed_item_checkout_id=licensed_item_get.licensed_item_checkout_id, licensed_item_id=licensed_item_get.licensed_item_id, wallet_id=licensed_item_get.wallet_id, @@ -78,7 +164,7 @@ async def release_licensed_item_for_wallet( user_id: UserID, # release args licensed_item_checkout_id: LicensedItemCheckoutID, -) -> webserver_licensed_items_checkouts.LicensedItemCheckoutGet: +) -> LicensedItemCheckoutGet: rpc_client = get_rabbitmq_rpc_client(app) checkout_item = await licensed_items_checkouts.get_licensed_item_checkout( @@ -103,7 +189,7 @@ async def release_licensed_item_for_wallet( ) ) - return webserver_licensed_items_checkouts.LicensedItemCheckoutGet( + return LicensedItemCheckoutGet.model_construct( licensed_item_checkout_id=licensed_item_get.licensed_item_checkout_id, licensed_item_id=licensed_item_get.licensed_item_id, wallet_id=licensed_item_get.wallet_id, diff --git a/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_handlers.py b/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_handlers.py new file mode 100644 index 00000000000..3a1a18bbef3 --- /dev/null +++ b/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_handlers.py @@ -0,0 +1,131 @@ +import logging + +from aiohttp import web +from models_library.api_schemas_webserver.licensed_items_checkouts import ( + LicensedItemCheckoutRestGet, + LicensedItemCheckoutRestGetPage, +) +from models_library.rest_ordering import OrderBy +from models_library.rest_pagination import Page +from models_library.rest_pagination_utils import paginate_data +from servicelib.aiohttp.requests_validation import ( + parse_request_path_parameters_as, + parse_request_query_parameters_as, +) +from servicelib.mimetype_constants import MIMETYPE_APPLICATION_JSON +from servicelib.rest_constants import RESPONSE_MODEL_POLICY + +from .._meta import API_VTAG as VTAG +from ..login.decorators import login_required +from ..security.decorators import permission_required +from ..utils_aiohttp import envelope_json_response +from ..wallets._handlers import WalletsPathParams +from . import _licensed_items_checkouts_api +from ._exceptions_handlers import handle_plugin_requests_exceptions +from ._licensed_items_checkouts_models import ( + LicensedItemCheckoutGet, + LicensedItemCheckoutGetPage, + LicensedItemCheckoutPathParams, +) +from ._models import LicensedItemsPurchasesListQueryParams, LicensedItemsRequestContext + +_logger = logging.getLogger(__name__) + + +routes = web.RouteTableDef() + + +@routes.get( + f"/{VTAG}/licensed-items-checkouts/{{licensed_item_checkout_id}}", + name="get_licensed_item_checkout", +) +@login_required +@permission_required("catalog/licensed-items.*") +@handle_plugin_requests_exceptions +async def get_licensed_item_checkout(request: web.Request): + req_ctx = LicensedItemsRequestContext.model_validate(request) + path_params = parse_request_path_parameters_as( + LicensedItemCheckoutPathParams, request + ) + + checkout_item: LicensedItemCheckoutGet = ( + await _licensed_items_checkouts_api.get_licensed_item_checkout( + app=request.app, + product_name=req_ctx.product_name, + user_id=req_ctx.user_id, + licensed_item_checkout_id=path_params.licensed_item_checkout_id, + ) + ) + + output = LicensedItemCheckoutRestGet.model_construct( + licensed_item_checkout_id=checkout_item.licensed_item_checkout_id, + licensed_item_id=checkout_item.licensed_item_id, + wallet_id=checkout_item.wallet_id, + user_id=checkout_item.user_id, + product_name=checkout_item.product_name, + started_at=checkout_item.started_at, + stopped_at=checkout_item.stopped_at, + num_of_seats=checkout_item.num_of_seats, + ) + + return envelope_json_response(output) + + +@routes.get( + f"/{VTAG}/wallets/{{wallet_id}}/licensed-items-checkouts", + name="list_licensed_item_checkouts_for_wallet", +) +@login_required +@permission_required("catalog/licensed-items.*") +@handle_plugin_requests_exceptions +async def list_licensed_item_checkouts_for_wallet(request: web.Request): + req_ctx = LicensedItemsRequestContext.model_validate(request) + path_params = parse_request_path_parameters_as(WalletsPathParams, request) + query_params: LicensedItemsPurchasesListQueryParams = ( + parse_request_query_parameters_as( + LicensedItemsPurchasesListQueryParams, request + ) + ) + + result: LicensedItemCheckoutGetPage = ( + await _licensed_items_checkouts_api.list_licensed_items_checkouts_for_wallet( + app=request.app, + product_name=req_ctx.product_name, + user_id=req_ctx.user_id, + wallet_id=path_params.wallet_id, + offset=query_params.offset, + limit=query_params.limit, + order_by=OrderBy.model_construct(**query_params.order_by.model_dump()), + ) + ) + + get_page = LicensedItemCheckoutRestGetPage( + total=result.total, + items=[ + LicensedItemCheckoutRestGet.model_construct( + licensed_item_checkout_id=checkout_item.licensed_item_checkout_id, + licensed_item_id=checkout_item.licensed_item_id, + wallet_id=checkout_item.wallet_id, + user_id=checkout_item.user_id, + product_name=checkout_item.product_name, + started_at=checkout_item.started_at, + stopped_at=checkout_item.stopped_at, + num_of_seats=checkout_item.num_of_seats, + ) + for checkout_item in result.items + ], + ) + + page = Page[LicensedItemCheckoutRestGetPage].model_validate( + paginate_data( + chunk=get_page.items, + request_url=request.url, + total=get_page.total, + limit=query_params.limit, + offset=query_params.offset, + ) + ) + return web.Response( + text=page.model_dump_json(**RESPONSE_MODEL_POLICY), + content_type=MIMETYPE_APPLICATION_JSON, + ) diff --git a/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_models.py b/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_models.py new file mode 100644 index 00000000000..43d6a290d6f --- /dev/null +++ b/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_checkouts_models.py @@ -0,0 +1,56 @@ +from datetime import datetime +from typing import NamedTuple + +from models_library.basic_types import IDStr +from models_library.licensed_items import LicensedItemID +from models_library.products import ProductName +from models_library.resource_tracker_licensed_items_checkouts import ( + LicensedItemCheckoutID, +) +from models_library.rest_base import RequestParameters, StrictRequestParameters +from models_library.rest_ordering import ( + OrderBy, + OrderDirection, + create_ordering_query_model_class, +) +from models_library.rest_pagination import PageQueryParameters +from models_library.users import UserID +from models_library.wallets import WalletID +from pydantic import BaseModel, PositiveInt + + +class LicensedItemCheckoutGet(BaseModel): + licensed_item_checkout_id: LicensedItemCheckoutID + licensed_item_id: LicensedItemID + wallet_id: WalletID + user_id: UserID + product_name: ProductName + started_at: datetime + stopped_at: datetime | None + num_of_seats: int + + +class LicensedItemCheckoutGetPage(NamedTuple): + items: list[LicensedItemCheckoutGet] + total: PositiveInt + + +class LicensedItemCheckoutPathParams(StrictRequestParameters): + licensed_item_checkout_id: LicensedItemCheckoutID + + +_LicensedItemsCheckoutsListOrderQueryParams: type[ + RequestParameters +] = create_ordering_query_model_class( + ordering_fields={ + "started_at", + }, + default=OrderBy(field=IDStr("started_at"), direction=OrderDirection.DESC), +) + + +class LicensedItemsCheckoutsListQueryParams( + PageQueryParameters, + _LicensedItemsCheckoutsListOrderQueryParams, # type: ignore[misc, valid-type] +): + ... diff --git a/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_purchases_api.py b/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_purchases_api.py index b42d593bed1..2cfa6355f83 100644 --- a/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_purchases_api.py +++ b/services/web/server/src/simcore_service_webserver/licenses/_licensed_items_purchases_api.py @@ -75,6 +75,7 @@ async def list_licensed_items_purchases( async def get_licensed_item_purchase( app: web.Application, + *, product_name: ProductName, user_id: UserID, licensed_item_purchase_id: LicensedItemPurchaseID, diff --git a/services/web/server/src/simcore_service_webserver/licenses/_rpc.py b/services/web/server/src/simcore_service_webserver/licenses/_rpc.py index 8be794e4016..3ecd72e65d6 100644 --- a/services/web/server/src/simcore_service_webserver/licenses/_rpc.py +++ b/services/web/server/src/simcore_service_webserver/licenses/_rpc.py @@ -2,7 +2,7 @@ from models_library.api_schemas_webserver import WEBSERVER_RPC_NAMESPACE from models_library.api_schemas_webserver.licensed_items import LicensedItemGetPage from models_library.api_schemas_webserver.licensed_items_checkouts import ( - LicensedItemCheckoutGet, + LicensedItemCheckoutRpcGet, ) from models_library.basic_types import IDStr from models_library.licensed_items import LicensedItemID @@ -20,7 +20,7 @@ ) from ..rabbitmq import get_rabbitmq_rpc_server -from . import _licensed_checkouts_api, _licensed_items_api +from . import _licensed_items_api, _licensed_items_checkouts_api router = RPCRouter() @@ -68,15 +68,27 @@ async def checkout_licensed_item_for_wallet( licensed_item_id: LicensedItemID, num_of_seats: int, service_run_id: ServiceRunID, -) -> LicensedItemCheckoutGet: - return await _licensed_checkouts_api.checkout_licensed_item_for_wallet( - app, - licensed_item_id=licensed_item_id, - wallet_id=wallet_id, - product_name=product_name, - num_of_seats=num_of_seats, - service_run_id=service_run_id, - user_id=user_id, +) -> LicensedItemCheckoutRpcGet: + licensed_item_get = ( + await _licensed_items_checkouts_api.checkout_licensed_item_for_wallet( + app, + licensed_item_id=licensed_item_id, + wallet_id=wallet_id, + product_name=product_name, + num_of_seats=num_of_seats, + service_run_id=service_run_id, + user_id=user_id, + ) + ) + return LicensedItemCheckoutRpcGet.model_construct( + licensed_item_checkout_id=licensed_item_get.licensed_item_checkout_id, + licensed_item_id=licensed_item_get.licensed_item_id, + wallet_id=licensed_item_get.wallet_id, + user_id=licensed_item_get.user_id, + product_name=licensed_item_get.product_name, + started_at=licensed_item_get.started_at, + stopped_at=licensed_item_get.stopped_at, + num_of_seats=licensed_item_get.num_of_seats, ) @@ -87,12 +99,24 @@ async def release_licensed_item_for_wallet( product_name: ProductName, user_id: UserID, licensed_item_checkout_id: LicensedItemCheckoutID, -) -> LicensedItemCheckoutGet: - return await _licensed_checkouts_api.release_licensed_item_for_wallet( - app, - product_name=product_name, - user_id=user_id, - licensed_item_checkout_id=licensed_item_checkout_id, +) -> LicensedItemCheckoutRpcGet: + licensed_item_get = ( + await _licensed_items_checkouts_api.release_licensed_item_for_wallet( + app, + product_name=product_name, + user_id=user_id, + licensed_item_checkout_id=licensed_item_checkout_id, + ) + ) + return LicensedItemCheckoutRpcGet.model_construct( + licensed_item_checkout_id=licensed_item_get.licensed_item_checkout_id, + licensed_item_id=licensed_item_get.licensed_item_id, + wallet_id=licensed_item_get.wallet_id, + user_id=licensed_item_get.user_id, + product_name=licensed_item_get.product_name, + started_at=licensed_item_get.started_at, + stopped_at=licensed_item_get.stopped_at, + num_of_seats=licensed_item_get.num_of_seats, ) diff --git a/services/web/server/tests/unit/with_dbs/04/licenses/test_licensed_items_checkouts_handlers.py b/services/web/server/tests/unit/with_dbs/04/licenses/test_licensed_items_checkouts_handlers.py new file mode 100644 index 00000000000..b6e60997e20 --- /dev/null +++ b/services/web/server/tests/unit/with_dbs/04/licenses/test_licensed_items_checkouts_handlers.py @@ -0,0 +1,84 @@ +# pylint: disable=redefined-outer-name +# pylint: disable=unused-argument +# pylint: disable=unused-variable +# pylint: disable=too-many-arguments +# pylint: disable=too-many-statements +from http import HTTPStatus + +import pytest +from aiohttp.test_utils import TestClient +from models_library.api_schemas_resource_usage_tracker import ( + licensed_items_checkouts as rut_licensed_items_checkouts, +) +from models_library.api_schemas_webserver.licensed_items_purchases import ( + LicensedItemPurchaseGet, +) +from pytest_mock.plugin import MockerFixture +from pytest_simcore.helpers.assert_checks import assert_status +from pytest_simcore.helpers.webserver_login import UserInfoDict +from servicelib.aiohttp import status +from simcore_service_webserver.db.models import UserRole + +_LICENSED_ITEM_CHECKOUT_GET = ( + rut_licensed_items_checkouts.LicensedItemCheckoutGet.model_validate({}) +) + +_LICENSED_ITEM_CHECKOUT_PAGE = rut_licensed_items_checkouts.LicensedItemsCheckoutsPage( + items=[_LICENSED_ITEM_CHECKOUT_GET], + total=1, +) + + +@pytest.fixture +def mock_get_licensed_items_purchases_page(mocker: MockerFixture) -> tuple: + return mocker.patch( + "simcore_service_webserver.licenses._licensed_items_checkouts_api.licensed_items_checkouts_api.get_licensed_items_purchases_page", + spec=True, + return_value=_LICENSED_ITEM_CHECKOUT_PAGE, + ) + + +@pytest.fixture +def mock_get_licensed_item_purchase(mocker: MockerFixture) -> tuple: + return mocker.patch( + "simcore_service_webserver.licenses._licensed_items_checkouts_api.licensed_items_purchases.get_licensed_item_purchase", + spec=True, + return_value=_LICENSED_ITEM_CHECKOUT_GET, + ) + + +@pytest.fixture +def mock_get_wallet_by_user(mocker: MockerFixture) -> tuple: + return mocker.patch( + "simcore_service_webserver.licenses._licensed_items_checkouts_api.get_wallet_by_user", + spec=True, + ) + + +@pytest.mark.parametrize("user_role,expected", [(UserRole.USER, status.HTTP_200_OK)]) +async def test_licensed_items_checkouts_handlers( + client: TestClient, + logged_user: UserInfoDict, + expected: HTTPStatus, + mock_get_licensed_items_purchases_page: MockerFixture, + mock_get_licensed_item_purchase: MockerFixture, + mock_get_wallet_by_user: MockerFixture, +): + assert client.app + + # list + url = client.app.router["list_wallet_licensed_items_purchases"].url_for( + wallet_id="1" + ) + resp = await client.get(f"{url}") + data, _ = await assert_status(resp, status.HTTP_200_OK) + assert len(data) == 1 + assert LicensedItemPurchaseGet(**data[0]) + + # get + url = client.app.router["get_licensed_item_purchase"].url_for( + licensed_item_purchase_id=f"{_LICENSED_ITEM_PURCHASE_PAGE.items[0].licensed_item_purchase_id}" + ) + resp = await client.get(f"{url}") + data, _ = await assert_status(resp, status.HTTP_200_OK) + assert LicensedItemPurchaseGet(**data) diff --git a/services/web/server/tests/unit/with_dbs/04/licenses/test_licensed_items_purchases_handlers.py b/services/web/server/tests/unit/with_dbs/04/licenses/test_licensed_items_purchases_handlers.py index ce0fddeca19..23e10209f27 100644 --- a/services/web/server/tests/unit/with_dbs/04/licenses/test_licensed_items_purchases_handlers.py +++ b/services/web/server/tests/unit/with_dbs/04/licenses/test_licensed_items_purchases_handlers.py @@ -73,7 +73,7 @@ def mock_get_wallet_by_user(mocker: MockerFixture) -> tuple: @pytest.mark.parametrize("user_role,expected", [(UserRole.USER, status.HTTP_200_OK)]) -async def test_licensed_items_db_crud( +async def test_licensed_items_purchaches_handlers( client: TestClient, logged_user: UserInfoDict, expected: HTTPStatus, diff --git a/services/web/server/tests/unit/with_dbs/04/licenses/test_licenses_rpc.py b/services/web/server/tests/unit/with_dbs/04/licenses/test_licenses_rpc.py index 6888711b2da..7bbfae01c90 100644 --- a/services/web/server/tests/unit/with_dbs/04/licenses/test_licenses_rpc.py +++ b/services/web/server/tests/unit/with_dbs/04/licenses/test_licenses_rpc.py @@ -73,7 +73,7 @@ async def rpc_client( @pytest.fixture def mock_get_wallet_by_user(mocker: MockerFixture) -> tuple: return mocker.patch( - "simcore_service_webserver.licenses._licensed_checkouts_api.get_wallet_by_user", + "simcore_service_webserver.licenses._licensed_items_checkouts_api.get_wallet_by_user", spec=True, ) @@ -86,7 +86,7 @@ def mock_get_wallet_by_user(mocker: MockerFixture) -> tuple: @pytest.fixture def mock_checkout_licensed_item(mocker: MockerFixture) -> tuple: return mocker.patch( - "simcore_service_webserver.licenses._licensed_checkouts_api.licensed_items_checkouts.checkout_licensed_item", + "simcore_service_webserver.licenses._licensed_items_checkouts_api.licensed_items_checkouts.checkout_licensed_item", spec=True, return_value=_LICENSED_ITEM_CHECKOUT_GET, ) @@ -95,7 +95,7 @@ def mock_checkout_licensed_item(mocker: MockerFixture) -> tuple: @pytest.fixture def mock_get_licensed_item_checkout(mocker: MockerFixture) -> tuple: return mocker.patch( - "simcore_service_webserver.licenses._licensed_checkouts_api.licensed_items_checkouts.get_licensed_item_checkout", + "simcore_service_webserver.licenses._licensed_items_checkouts_api.licensed_items_checkouts.get_licensed_item_checkout", spec=True, return_value=_LICENSED_ITEM_CHECKOUT_GET, ) @@ -104,7 +104,7 @@ def mock_get_licensed_item_checkout(mocker: MockerFixture) -> tuple: @pytest.fixture def mock_release_licensed_item(mocker: MockerFixture) -> tuple: return mocker.patch( - "simcore_service_webserver.licenses._licensed_checkouts_api.licensed_items_checkouts.release_licensed_item", + "simcore_service_webserver.licenses._licensed_items_checkouts_api.licensed_items_checkouts.release_licensed_item", spec=True, return_value=_LICENSED_ITEM_CHECKOUT_GET, )