diff --git a/morango/constants/transfer_stages.py b/morango/constants/transfer_stages.py index a93c69e..7362062 100644 --- a/morango/constants/transfer_stages.py +++ b/morango/constants/transfer_stages.py @@ -3,6 +3,10 @@ """ from django.utils.translation import ugettext_lazy as _ +# A special null stage to use before the transfer session has been started +# this allows the initializing stage to be properly invoked. +# This is not included in ALL or CHOICES below because it is not a valid stage. +NO_STAGE = "no_stage" INITIALIZING = "initializing" SERIALIZING = "serializing" QUEUING = "queuing" @@ -24,6 +28,7 @@ ALL = {stage for stage, _ in CHOICES} PRECEDENCE = { + NO_STAGE: 0, INITIALIZING: 10, SERIALIZING: 20, QUEUING: 30, diff --git a/morango/sync/context.py b/morango/sync/context.py index d8013d7..da46902 100644 --- a/morango/sync/context.py +++ b/morango/sync/context.py @@ -231,7 +231,7 @@ def stage(self): """ :return: A transfer_stage.* constant """ - stage = transfer_stages.INITIALIZING + stage = transfer_stages.NO_STAGE if self._has_transfer_session: stage = self.transfer_session.transfer_stage or stage return stage @@ -308,7 +308,7 @@ def __init__(self, connection, **kwargs): super(NetworkSessionContext, self).__init__(**kwargs) # since this is network context, keep local reference to state vars - self._stage = transfer_stages.INITIALIZING + self._stage = transfer_stages.NO_STAGE self._stage_status = transfer_statuses.PENDING @property @@ -355,7 +355,7 @@ def __init__(self, contexts, *args, **kwargs): """ self.children = contexts self._counter = 0 - self._stage = transfer_stages.INITIALIZING + self._stage = transfer_stages.NO_STAGE self._stage_status = transfer_statuses.PENDING super(CompositeSessionContext, self).__init__(*args, **kwargs) self._update_attrs(**kwargs) diff --git a/morango/sync/utils.py b/morango/sync/utils.py index a025b55..8908b94 100644 --- a/morango/sync/utils.py +++ b/morango/sync/utils.py @@ -181,6 +181,14 @@ def connect(self, handler): """ self._handlers.append(handler) + def disconnect(self, handler): + """ + Removes a callable handler that would be called when the signal is fired. + + :type handler: function + """ + self._handlers.remove(handler) + def fire(self, **kwargs): """ Fires the handler functions connected via `connect`. diff --git a/tests/testapp/tests/test_api.py b/tests/testapp/tests/test_api.py index 01d7399..b8c2ef3 100644 --- a/tests/testapp/tests/test_api.py +++ b/tests/testapp/tests/test_api.py @@ -10,12 +10,14 @@ from django.utils import timezone from django.utils.functional import SimpleLazyObject from facility_profile.models import MyUser +from mock import Mock from rest_framework.test import APITestCase as BaseTestCase from .compat import EnvironmentVarGuard from morango.api.serializers import BufferSerializer from morango.api.serializers import CertificateSerializer from morango.api.serializers import InstanceIDSerializer +from morango.api.viewsets import session_controller from morango.constants import transfer_stages from morango.constants import transfer_statuses from morango.models.certificates import Certificate @@ -790,6 +792,19 @@ def test_transfersession_creation_fails_for_nonexistent_syncsession(self): syncsession=syncsession, ) + def test_transfersession_creation_calls_initializing_started_handler(self): + mock = Mock() + session_controller.signals.initializing.started.connect(mock) + try: + + self.make_transfersession_creation_request( + filter=str(self.sub_subset_cert1_with_key.get_scope().write_filter), + push=True, + ) + self.assertTrue(mock.called) + finally: + session_controller.signals.initializing.started.disconnect(mock) + def test_transfersession_can_be_deleted(self): self.test_transfersession_can_be_created()