Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix flush with reverse m2m changed signal #386

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion waffle/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,12 @@
@receiver(m2m_changed, sender=get_waffle_flag_model().groups.through)
def flag_membership_changed(sender, instance, action, **kwargs):
if action in ('post_add', 'post_remove'):
instance.flush()
flag_model = get_waffle_flag_model()

# instance could be a flag or an instance of the related model
# https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed
if isinstance(instance, flag_model):
instance.flush()
else:
for flag in flag_model.objects.filter(pk__in=kwargs['pk_set']):
flag.flush()
50 changes: 50 additions & 0 deletions waffle/tests/test_waffle.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,29 @@ def test_user(self):
response = process_request(request, views.flag_in_view)
self.assertEqual(b'off', response.content)

def test_remove_from_user(self):
"""Same operation of `test_user` but performed with reverse relation"""
user = get_user_model().objects.create(username='foo')
flag = waffle.get_waffle_flag_model().objects.create(name='myflag')
flag.users.add(user)

request = get()
request.user = user
response = process_request(request, views.flag_in_view)
self.assertEqual(b'on', response.content)
assert 'dwf_myflag' not in response.cookies

request.user = get_user_model().objects.create(username='someone_else')
response = process_request(request, views.flag_in_view)
self.assertEqual(b'off', response.content)
assert 'dwf_myflag' not in response.cookies

# Unsetting the flag on a user should have an effect.
user.flag_set.remove(flag)
request.user = user
response = process_request(request, views.flag_in_view)
self.assertEqual(b'off', response.content)

def test_group(self):
"""Test the per-group switch."""
group = Group.objects.create(name='foo')
Expand Down Expand Up @@ -191,6 +214,33 @@ def test_group(self):
response = process_request(request, views.flag_in_view)
self.assertEqual(b'off', response.content)

def test_remove_from_group(self):
"""Same operation of `test_group` but performed with reverse relation"""
group = Group.objects.create(name='foo')
user = get_user_model().objects.create(username='bar')
user.groups.add(group)

flag = waffle.get_waffle_flag_model().objects.create(name='myflag')
flag.groups.add(group)

request = get()
request.user = user
response = process_request(request, views.flag_in_view)
self.assertEqual(b'on', response.content)
assert 'dwf_myflag' not in response.cookies

request.user = get_user_model()(username='someone_else')
request.user.save()
response = process_request(request, views.flag_in_view)
self.assertEqual(b'off', response.content)
assert 'dwf_myflag' not in response.cookies

# Unsetting the flag on a group should have an effect.
group.flag_set.remove(flag)
request.user = user
response = process_request(request, views.flag_in_view)
self.assertEqual(b'off', response.content)

def test_authenticated(self):
"""Test the authenticated/anonymous switch."""
waffle.get_waffle_flag_model().objects.create(name='myflag', authenticated=True)
Expand Down