1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
from unittest import mock
import django
import pytest
from django.apps import apps
from django.core.management import call_command
from django.db import DEFAULT_DB_ALIAS
from django.db.models.signals import post_migrate, pre_migrate
from django_test_migrations.contrib.unittest_case import MigratorTestCase
class TestSignalMuting(MigratorTestCase):
"""Test that the `post_migrate` signal has been muted."""
migrate_from = ('main_app', '0002_someitem_is_clean')
migrate_to = ('main_app', '0001_initial')
def test_pre_migrate_muted(self):
"""Ensure ``pre_migrate`` signal has been muted."""
assert not pre_migrate.receivers
def test_post_migrate_muted(self):
"""Ensure ``post_migrate`` signal has been muted."""
assert not post_migrate.receivers
class TestSignalConnectInTest(MigratorTestCase):
"""Ensure test ``pre_migrate`` or ``post_migrate`` receiver are called.
Ensure that ``pre_migrate`` or ``post_migrate`` signals receivers
connected directly in tests are called.
"""
migrate_from = ('main_app', '0001_initial')
migrate_to = ('main_app', '0002_someitem_is_clean')
def tearDown(self):
"""Disconnect ``pre_migrate`` and ``post_migrate`` testing receivers."""
pre_migrate.disconnect(
self.pre_migrate_receiver_mock,
sender=self.main_app_config,
)
post_migrate.disconnect(
self.post_migrate_receiver_mock,
sender=self.main_app_config,
)
def prepare(self):
"""Connect testing ``pre_migrate`` and ``post_migrate`` receivers."""
self.pre_migrate_receiver_mock = mock.MagicMock()
self.post_migrate_receiver_mock = mock.MagicMock()
# ``old_apps`` is not real ``ProjectState`` instance, so we cannot use
# it to get "original" main_app ``AppConfig`` instance needed to
# connect signal receiver, that's the reason we are using
# ``apps`` imported directly from ``django.apps``
self.main_app_config = apps.get_app_config('main_app')
pre_migrate.connect(
self.pre_migrate_receiver_mock,
sender=self.main_app_config,
)
post_migrate.connect(
self.post_migrate_receiver_mock,
sender=self.main_app_config,
)
@pytest.mark.skipif(
django.VERSION >= (4, 0),
reason='requires `Django<4.0`',
)
def test_signal_receivers_added_in_tests(self):
"""Ensure migration signals receivers connected in tests are called."""
verbosity = 0
interactive = False
# call `migrate` management command to trigger ``pre_migrate`` and
# ``post_migrate`` signals
call_command('migrate', verbosity=verbosity, interactive=interactive)
common_kwargs = {
'sender': self.main_app_config,
'app_config': self.main_app_config,
'apps': mock.ANY, # we don't have any reference to this object
'using': DEFAULT_DB_ALIAS,
'verbosity': verbosity,
'interactive': interactive,
'plan': mock.ANY, # not important for this test
}
self.pre_migrate_receiver_mock.assert_called_once_with(
**common_kwargs,
signal=pre_migrate,
)
self.post_migrate_receiver_mock.assert_called_once_with(
**common_kwargs,
signal=post_migrate,
)
@pytest.mark.skipif(
django.VERSION < (4, 0),
reason='requires `Django>=4.0`',
)
def test_signal_receivers_added_in_tests_django40(self):
"""Ensure migration signals receivers connected in tests are called."""
verbosity = 0
interactive = False
# call `migrate` management command to trigger ``pre_migrate`` and
# ``post_migrate`` signals
call_command('migrate', verbosity=verbosity, interactive=interactive)
common_kwargs = {
'sender': self.main_app_config,
'app_config': self.main_app_config,
'apps': mock.ANY, # we don't have any reference to this object
'using': DEFAULT_DB_ALIAS,
'verbosity': verbosity,
'interactive': interactive,
# following kwargs are not important for this test
'stdout': mock.ANY,
'plan': mock.ANY,
}
self.pre_migrate_receiver_mock.assert_called_once_with(
**common_kwargs,
signal=pre_migrate,
)
self.post_migrate_receiver_mock.assert_called_once_with(
**common_kwargs,
signal=post_migrate,
)
|