From 0ae7f69821a764caf6ff5ee646c4ff3da15c1c0e Mon Sep 17 00:00:00 2001 From: "Janet L. Goldstein" <jgoldste@nrao.edu> Date: Tue, 11 Jan 2022 13:38:01 -0700 Subject: [PATCH] WS-858: unit test for create_followon_request_version --- .../capability/views/capability_request.py | 33 ++++++---- .../capability/test/test_capability_routes.py | 60 ++++++++++++++++++- .../test/test_capability_request.py | 2 + 3 files changed, 84 insertions(+), 11 deletions(-) diff --git a/services/capability/capability/views/capability_request.py b/services/capability/capability/views/capability_request.py index 3a7cf0454..e14d93e77 100644 --- a/services/capability/capability/views/capability_request.py +++ b/services/capability/capability/views/capability_request.py @@ -21,6 +21,8 @@ File containing definitions for the other half of the capability side of the Workspaces REST API, concerning capability requests """ +# pylint: disable=E0401 + import json from capability.views.capability_version import submit_capability_version @@ -29,6 +31,8 @@ from pyramid.request import Request from pyramid.response import Response from pyramid.view import view_config +from workspaces.capability.schema import CapabilityVersion + @view_config(route_name="view_capability_request", renderer="json") def view_capability_request(request: Request) -> Response: @@ -121,12 +125,13 @@ def create_capability_request(request: Request) -> Response: @view_config(route_name="create_follow_on_capability_request", renderer="json") -def create_follow_on_capability_request(request: Request) -> Response: +def create_follow_on_capability_request(request: Request, version: CapabilityVersion) -> Response: """ Pyramid view that accepts a request to create a follow-on capability request from a previous request URL: capability/request/{request_id}/followon/{followon_type} :param request: POST request + :param version: version of the request for which we want to create a follow-on request :return: 200 OK response with JSON-formatted info of newly created capability request or 400 response (HTTPBadRequest) if expected parameters not given or 412 response (HTTPPreconditionFailed) if capability with given name does not exist and thus cannot be @@ -136,22 +141,24 @@ def create_follow_on_capability_request(request: Request) -> Response: request_id = request.matchdict["request_id"] followon_type = request.matchdict["followon_type"] - capability_request = request.capability_info.lookup_capability_request(request_id) - parameters = capability_request.current_version.parameters - user_email = parameters["user_email"] - - previous_workflow_id = capability_request.current_execution.current_workflow_request_id + previous_workflow_id = request_id - metadata_content = request.workflow_service.retrieve_file_content( - followon_type, previous_workflow_id, "metadata.json" - ) + metadata_content = request.workflow_service.retrieve_file_content(previous_workflow_id, "metadata.json") metadata = json.loads(metadata_content) cms_path = metadata["destinationDirectory"] + "/working" sdm_id = metadata["fileSetIds"][0] if isinstance(metadata["fileSetIds"], list) else metadata["fileSetIds"] new_capability_request = request.capability_info.create_capability_request( - followon_type, parameters={"cms_path": cms_path, "sdmId": sdm_id, "user_email": user_email} + followon_type, + parameters={ + "cms_path": cms_path, + "sdmId": sdm_id, + "user_email": "jgoldste@nrao.edu", + "version": version.version_number, + "previous_workflow_request_id": previous_workflow_id, + "capability_name": version.capability_name, + }, ) return Response(json_body=new_capability_request.__json__()) @@ -172,6 +179,12 @@ def edit_capability_request(request: Request) -> Response: @view_config(route_name="create_and_submit_capability_request", renderer="json") def create_and_submit_capability_request(request: Request) -> Response: + """ + Pyramid view to reate and submit a capability request + + :param request: dummy POST request + :return: + """ response = create_capability_request(request) capability_request = request.capability_info.lookup_capability_request(response.json_body["id"]) request.matchdict = { diff --git a/services/capability/test/test_capability_routes.py b/services/capability/test/test_capability_routes.py index c129488a4..c6938dfa1 100644 --- a/services/capability/test/test_capability_routes.py +++ b/services/capability/test/test_capability_routes.py @@ -19,18 +19,34 @@ """ Make sure we've got all the capability routes""" # pylint: disable=E0401, W0621 - +import copy +import http from typing import List +from unittest.mock import patch import pytest +from capability.views.capability_request import create_follow_on_capability_request from pyramid.config import Configurator from pyramid.interfaces import IRoutesMapper +from pyramid.testing import DummyRequest + +from workspaces.capability.schema import CapabilityRequest +from workspaces.capability.services.capability_service import CapabilityService +from workspaces.workflow.schema import WorkflowRequest +from workspaces.workflow.services.workflow_service import WorkflowService + +pytest_plugins = ["testing.utils.conftest"] RouteList = List[str] @pytest.fixture() def capability_routes() -> RouteList: + """ + All the capability routes (or should be) + + :return: list of all available capability routes + """ return [ "home", "view_capability", @@ -83,3 +99,45 @@ def test_routes_exist(test_config: Configurator, capability_routes: RouteList): assert route in route_names assert len(capability_routes) == len(route_names) + + +def test_create_follow_on_capability_request( + request_null_capability: DummyRequest, + mock_capability_service: CapabilityService, + mock_workflow_service: WorkflowService, + mock_workflow_requests: List[WorkflowRequest], + mock_capability_requests: List[CapabilityRequest], +): + """ + Test for CapabilityRequest.create_follow_on_capability_request + + :param request_null_capability: Dummy Pyramid request object set up with mocked DB access + supporting the null capability + :param mock_capability_service: stand-in for CapabilityService + :param mock_workflow_service: stand-in for WorkflowService + :param mock_workflow_requests: WorkflowRequest impostors + :param mock_capability_requests: CapabilityRequest impostors + + :return: + """ + capability_request = copy.deepcopy(mock_capability_requests[0]) + capability_request.capability_name = "std_cms_imaging" + + request_null_capability.matchdict["request_id"] = capability_request.id + + request_null_capability.workflow_service = mock_workflow_service + request_null_capability.matchdict["workflow_request_id"] = mock_workflow_requests[0].workflow_request_id + version = mock_capability_service.create_new_version(capability_request_id=capability_request.id) + version.parameters = {"user_email": "jgoldste@nrao.edu", "previous_workflow_request_id": 42} + request_null_capability.matchdict["version_number"] = version.version_number + + request_null_capability.matchdict["followon_type"] = capability_request.capability_name + + fake_file_content = '{"destinationDirectory": "/var/tmp", "fileSetIds": "[]"}' + with patch( + "workspaces.workflow.services.workflow_service.WorkflowService.retrieve_file_content", + return_value=fake_file_content, + ) as mock_retrieve: + response = create_follow_on_capability_request(request=request_null_capability, version=version) + assert response.status_code == http.HTTPStatus.OK + mock_retrieve.assert_called_once() diff --git a/shared/workspaces/test/test_capability_request.py b/shared/workspaces/test/test_capability_request.py index b6f4043b0..a51714ea1 100644 --- a/shared/workspaces/test/test_capability_request.py +++ b/shared/workspaces/test/test_capability_request.py @@ -35,6 +35,8 @@ from .conftest import ( clear_test_database, ) +pytest_plugins = ["testing.utils.conftest"] + # Register CapabilityRequest JSON blueprint as a hypothesis type strategy # To use: # >>> @given(st.from_type(CapabilityRequest)) -- GitLab