How can I mute Django signals during creation of PyTest fixture?

Viewed 385

In my Django project I create Profile of the User via the post_save signal:

@receiver(post_save, sender=User)
def post_save_user(sender, instance, *args, **kwwargs):

    Profile.objects.create_profile(instance)
    return None

In Profile objects manager I iterate over permissions and assign them to Profile object:

    for perm in ASSIGNED_PERMISSIONS['profile']:
        assign_perm(perm[0], user, profile)

When I try to create user fixture in PyTest:

@pytest.fixture
def user(db, django_user_model):
    return django_user_model.objects.create(username='user', password='password')

I get error about missing Permissions in the DB.

django.contrib.auth.models.Permission.DoesNotExist: Permission matching query does not exist

As I understand PyTest tries to create user fixture. User model emits post_save signal which is handled in Profile. However, required permissions over which I iterate are not yet in the DB.

One of the solutions could be to disable signals with autoused fixture which will be then applied to each test:

@pytest.fixture(autouse=True)
def mute_signals(request):

    restore = {}
    if not 'enable_signals' in request.keywords:
        signals = [
            pre_save,
            post_save,
            pre_delete,
            post_delete,
            m2m_changed
        ]

        for signal in signals:
            restore[signal] = signal.receivers
            signal.receivers = []

    yield

    for signal, receivers in restore.items():
        signal.receivers = receivers

However, then I need to define user and related objects (user_profile, user_profile_settings) in every test:

@pytest.mark.django_db
def test_check_follows():
    user = User.objects.create(username='user', password='password')
    user1 = User.objects.create(username='user1', password='password1')
    profile = ..
    profile1 = ...
    get_or_create_fellowship(user, user1)

and I will prefer to keep all the fixtures in conftest.py for simplicity.

The question is how can I disable signals for every fixture in conftest.py? Or probably, can I make signals work, so that after creation of user fixture I get all the related objects (Profile, Settings) returned in one fixture?

Thanks.

0 Answers
Related