import pytest
from testdoubleutil import SpyCall

from httpmessageprocessorutil.automapped import AutoMappedMessageProcessor
from httpmessageprocessorutil.automapped.exception import (
    InteractorWithoutExecuteMethod,
    InteractorWithMoreThanOneParameterOnExecute
)


class NoExecuteInteractor(object):
    pass


class NoParameterInteractor(object):
    def __init__(self):
        self.execute_call = SpyCall()

    def execute(self):
        self.execute_call.register()


class ParameterInteractor(object):
    def __init__(self):
        self.execute_call = SpyCall()

    def execute(self, obj):
        self.execute_call.register(obj)


class TwoParametersInteractor(object):
    def execute(self, obj1, obj2):
        pass


class TestCallBusiness(object):
    def test_whenInteractorHasNoExecuteMethod_ExceptionIsRaised(self):
        with pytest.raises(InteractorWithoutExecuteMethod):
            AutoMappedMessageProcessor(str, NoExecuteInteractor())

    def test_whenInteractorHasMoreThanOneParameterOnExecute_ExceptionIsRaised(self):
        with pytest.raises(InteractorWithMoreThanOneParameterOnExecute):
            AutoMappedMessageProcessor(str, TwoParametersInteractor())

    def test_NoneParameterAndNoParameterInteractor_ExecuteIsCalled(self):
        interactor = NoParameterInteractor()
        AutoMappedMessageProcessor(str, interactor).call_business(None)
        assert interactor.execute_call.called

    def test_NoneParameterAndParameterInteractor_ExecuteWithNoneIsCalled(self):
        interactor = ParameterInteractor()
        AutoMappedMessageProcessor(str, interactor).call_business(None)
        assert interactor.execute_call.called
        assert interactor.execute_call.args[0] is None

    def test_ReceivedValueIsPassedToInteractor(self):
        value = "asdf"
        interactor = ParameterInteractor()
        AutoMappedMessageProcessor(str, interactor).call_business(value)
        assert interactor.execute_call.called
        assert interactor.execute_call.args[0] == value
