|
24 | 24 | from fastapi import FastAPI, status |
25 | 25 | from fastapi.encoders import jsonable_encoder |
26 | 26 | from httpx import ASGITransport, Request, Response |
| 27 | +from models_library.api_schemas_catalog import CATALOG_RPC_NAMESPACE |
27 | 28 | from models_library.api_schemas_long_running_tasks.tasks import ( |
28 | 29 | TaskGet, |
29 | 30 | TaskProgress, |
|
42 | 43 | from models_library.products import ProductName |
43 | 44 | from models_library.projects import ProjectID |
44 | 45 | from models_library.projects_nodes_io import BaseFileLink, SimcoreS3FileID |
| 46 | +from models_library.rabbitmq_basic_types import RPCMethodName, RPCNamespace |
45 | 47 | from models_library.rpc.webserver.projects import ProjectJobRpcGet |
46 | 48 | from models_library.users import UserID |
47 | 49 | from moto.server import ThreadedMotoServer |
|
57 | 59 | from pytest_simcore.simcore_webserver_projects_rest_api import GET_PROJECT |
58 | 60 | from requests.auth import HTTPBasicAuth |
59 | 61 | from respx import MockRouter |
| 62 | +from servicelib.rabbitmq._client_rpc import RabbitMQRPCClient |
60 | 63 | from simcore_service_api_server.api.dependencies.authentication import Identity |
61 | 64 | from simcore_service_api_server.core.application import create_app |
62 | 65 | from simcore_service_api_server.core.settings import ApplicationSettings |
@@ -254,31 +257,71 @@ def mocked_s3_server_url() -> Iterator[HttpUrl]: |
254 | 257 |
|
255 | 258 |
|
256 | 259 | @pytest.fixture |
257 | | -def mocked_app_dependencies(app: FastAPI, mocker: MockerFixture) -> Iterator[None]: |
| 260 | +def mocked_rabbit_rpc_client(mocker: MockerFixture) -> MockType: |
| 261 | + """This fixture mocks the RabbitMQRPCClient.request method which is used |
| 262 | + in all RPC clients in the api-server, regardeless of the namespace. |
| 263 | + """ |
| 264 | + |
| 265 | + async def _request( |
| 266 | + namespace: RPCNamespace, |
| 267 | + method_name: RPCMethodName, |
| 268 | + **kwargs, |
| 269 | + ) -> Any: |
| 270 | + |
| 271 | + kwargs.pop("timeout_s", None) # remove timeout from kwargs |
| 272 | + |
| 273 | + # NOTE: we could switch to different namespaces |
| 274 | + if namespace == CATALOG_RPC_NAMESPACE: |
| 275 | + catalog_side_effect = CatalogRpcSideEffects() |
| 276 | + return await getattr(catalog_side_effect, method_name)( |
| 277 | + mocker.MagicMock(), **kwargs |
| 278 | + ) |
| 279 | + |
| 280 | + # if not namespace == WEBSERVER_RPC_NAMESPACE |
| 281 | + webserver_side_effect = WebserverRpcSideEffects() |
| 282 | + return await getattr(webserver_side_effect, method_name)( |
| 283 | + mocker.MagicMock(), **kwargs |
| 284 | + ) |
| 285 | + |
| 286 | + pytest.fail(f"Unexpected namespace {namespace} and method {method_name}") |
| 287 | + |
| 288 | + # NOTE: mocks RabbitMQRPCClient.request(...) |
| 289 | + mock = mocker.MagicMock(spec=RabbitMQRPCClient) |
| 290 | + mock.request.side_effect = _request |
| 291 | + |
| 292 | + return mock |
| 293 | + |
| 294 | + |
| 295 | +@pytest.fixture |
| 296 | +def mocked_app_dependencies( |
| 297 | + app: FastAPI, mocker: MockerFixture, mocked_rabbit_rpc_client: MockType |
| 298 | +) -> Iterator[None]: |
258 | 299 | """ |
259 | 300 | Mocks some dependency overrides for the FastAPI app. |
260 | 301 | """ |
261 | 302 | assert app.state.settings.API_SERVER_RABBITMQ is None |
262 | | - from servicelib.rabbitmq import RabbitMQRPCClient |
263 | 303 | from simcore_service_api_server.api.dependencies.rabbitmq import ( |
264 | 304 | get_rabbitmq_rpc_client, |
265 | 305 | ) |
266 | 306 | from simcore_service_api_server.api.dependencies.webserver_rpc import ( |
267 | 307 | get_wb_api_rpc_client, |
268 | 308 | ) |
269 | 309 |
|
| 310 | + # Overrides Depends[get_rabbitmq_rpc_client] |
270 | 311 | def _get_rabbitmq_rpc_client_override(): |
271 | | - return mocker.MagicMock() |
| 312 | + return mocked_rabbit_rpc_client |
272 | 313 |
|
| 314 | + app.dependency_overrides[get_rabbitmq_rpc_client] = ( |
| 315 | + _get_rabbitmq_rpc_client_override |
| 316 | + ) |
| 317 | + |
| 318 | + # Overrides Depends[get_wb_api_rpc_client] |
273 | 319 | async def _get_wb_api_rpc_client_override(): |
274 | 320 | from simcore_service_api_server.services_rpc import wb_api_server |
275 | 321 |
|
276 | | - wb_api_server.setup(app, mocker.MagicMock(spec=RabbitMQRPCClient)) |
| 322 | + wb_api_server.setup(app, rabbitmq_rpc_client=mocked_rabbit_rpc_client) |
277 | 323 | return WbApiRpcClient.get_from_app_state(app) |
278 | 324 |
|
279 | | - app.dependency_overrides[get_rabbitmq_rpc_client] = ( |
280 | | - _get_rabbitmq_rpc_client_override |
281 | | - ) |
282 | 325 | app.dependency_overrides[get_wb_api_rpc_client] = _get_wb_api_rpc_client_override |
283 | 326 |
|
284 | 327 | yield |
@@ -562,51 +605,30 @@ def mocked_catalog_rest_api_base( |
562 | 605 |
|
563 | 606 |
|
564 | 607 | @pytest.fixture |
565 | | -def project_job_rpc_get() -> ProjectJobRpcGet: |
| 608 | +def fake_project_job_rpc_get() -> ProjectJobRpcGet: |
566 | 609 | example = ProjectJobRpcGet.model_json_schema()["examples"][0] |
567 | 610 | return ProjectJobRpcGet.model_validate(example) |
568 | 611 |
|
569 | 612 |
|
570 | 613 | @pytest.fixture |
571 | | -def job_links() -> JobLinks: |
| 614 | +def fake_job_links() -> JobLinks: |
572 | 615 | example = JobLinks.model_json_schema()["examples"][0] |
573 | 616 | return JobLinks.model_validate(example) |
574 | 617 |
|
575 | 618 |
|
576 | 619 | @pytest.fixture |
577 | 620 | def mocked_webserver_rpc_api( |
578 | 621 | mocked_app_dependencies: None, |
579 | | - mocker: MockerFixture, |
580 | | - project_job_rpc_get: ProjectJobRpcGet, |
| 622 | + mocked_rabbit_rpc_client: MockType, |
581 | 623 | ) -> dict[str, MockType]: |
582 | 624 | """ |
583 | | - Mocks the webserver's simcore service RPC API for testing purposes. |
584 | | - """ |
585 | | - from servicelib.rabbitmq.rpc_interfaces.webserver import ( |
586 | | - projects as projects_rpc, # keep import here |
587 | | - ) |
588 | | - |
589 | | - side_effects = WebserverRpcSideEffects(project_job_rpc_get=project_job_rpc_get) |
| 625 | + In reality this fixture will mock the underlying RabbitMQRPCClient.request method |
| 626 | + used in the webserver's RPC client which fakes the webserver's RPC API response for testing purposes. |
590 | 627 |
|
| 628 | + NOTE: the responses are defined in the mocked_rabbit_rpc_client fixture |
| 629 | + """ |
591 | 630 | return { |
592 | | - "mark_project_as_job": mocker.patch.object( |
593 | | - projects_rpc, |
594 | | - "mark_project_as_job", |
595 | | - autospec=True, |
596 | | - side_effect=side_effects.mark_project_as_job, |
597 | | - ), |
598 | | - "get_project_marked_as_job": mocker.patch.object( |
599 | | - projects_rpc, |
600 | | - "get_project_marked_as_job", |
601 | | - autospec=True, |
602 | | - side_effect=side_effects.get_project_marked_as_job, |
603 | | - ), |
604 | | - "list_projects_marked_as_jobs": mocker.patch.object( |
605 | | - projects_rpc, |
606 | | - "list_projects_marked_as_jobs", |
607 | | - autospec=True, |
608 | | - side_effect=side_effects.list_projects_marked_as_jobs, |
609 | | - ), |
| 631 | + "mocked_rabbit_rpc_client": mocked_rabbit_rpc_client, |
610 | 632 | } |
611 | 633 |
|
612 | 634 |
|
|
0 commit comments