Skip to content
Snippets Groups Projects
conftest.py 4.39 KiB
Newer Older
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),
    )