from typing import Any, List from unittest.mock import MagicMock import pytest from pyramid.config import Configurator from pyramid.testing import DummyRequest, setUp, tearDown from workspaces.capability.enums import CapabilityRequestState from workspaces.capability.helpers import Parameter from workspaces.capability.schema import ( Capability, CapabilityRequest, CapabilityVersion, ) from workspaces.capability.schema_interfaces import CapabilityRequestIF from workspaces.products.schema import FutureProduct @pytest.fixture(scope="module") def test_config() -> Configurator: """ Returns a dummy Configurator object for testing purposes with set up and teardown :return: Dummy Configurator """ request = DummyRequest() config = setUp(request=request) config.add_request_method( lambda lookup: MagicMock(), "capability_info", reify=True, ) yield config tearDown() class MockCapabilityInfo(MagicMock): capabilities = [ Capability( name="null", steps="test", max_jobs=2, ), Capability( name="error", steps="error", max_jobs=-1, ), ] capability_requests = [ CapabilityRequest( id=0, state="Created", capability_name="null", parameters="-g", versions=[], ) ] def edit_capability( self, name: str, steps: str = None, max_jobs: int = None, enabled: bool = None ) -> bool: if name == "error": # This is here to mimic the case where an update fails to happen return False for capability in self.capabilities: if name == capability.name: if steps: capability.steps = steps if max_jobs: capability.max_jobs = max_jobs if enabled: capability.enabled = enabled return True return False def lookup_capability(self, capability_name: str) -> Capability: for capability in self.capabilities: if capability_name == capability.name: return capability return None def lookup_capability_request(self, request_id: int) -> CapabilityRequest: for capability_request in self.capability_requests: if request_id == capability_request.id: return capability_request return None def save_entity(self, entity: Any): if type(entity) is Capability: self.capabilities.append(entity) elif type(entity) is CapabilityRequest: entity.id = len(self.capability_requests) self.capability_requests.append(entity) class MockCapabilityService(MagicMock): def __init__(self, capability_info: MockCapabilityInfo): super().__init__() self.capability_info = capability_info def create_request( self, capability_name: str, parameters: List[Parameter] = None, products: List[FutureProduct] = None, ) -> CapabilityRequestIF: """ Mocked version of the corresponding `CapabilityService.create_request` method :param capability_name: Name of capability :param parameters: Parameters for request :param products: Product that the request will give back :return: Newly created request """ capability = self.capability_info.lookup_capability(capability_name) request = CapabilityRequest( state=CapabilityRequestState.Ready.name, capability=capability, capability_name=capability_name, parameters=str(parameters), # a trick here is to ensure that we always have a first version, with the original parameters versions=[CapabilityVersion(version_number=1, parameters=str(parameters))], ) self.capability_info.save_entity(request) return request @pytest.fixture(scope="module") def request_null_capability() -> DummyRequest: """ Returns a dummy request object with a mocked capability_info :return: DummyRequest with configured mock CapabilityInfo """ mock_capability_info = MockCapabilityInfo() request = DummyRequest( capability_info=mock_capability_info, capabilities=MockCapabilityService(mock_capability_info), ) return request