diff --git a/allianceauth/services/modules/teamspeak3/signals.py b/allianceauth/services/modules/teamspeak3/signals.py index f7befb1e..6ae97778 100644 --- a/allianceauth/services/modules/teamspeak3/signals.py +++ b/allianceauth/services/modules/teamspeak3/signals.py @@ -5,7 +5,7 @@ from django.db.models.signals import m2m_changed from django.db.models.signals import post_delete from django.db.models.signals import post_save from django.dispatch import receiver - +from allianceauth.authentication.signals import state_changed from .tasks import Teamspeak3Tasks from .models import AuthTS, StateGroup @@ -39,3 +39,11 @@ def post_delete_authts(sender, instance, *args, **kwargs): # it's literally the same logic so just recycle the receiver post_save.connect(post_save_authts, sender=StateGroup) post_delete.connect(post_delete_authts, sender=StateGroup) + + +@receiver(state_changed) +def check_groups_on_state_change(sender, user, state, **kwargs): + def trigger_update(): + Teamspeak3Tasks.update_groups.delay(user.pk) + logger.debug("Received state_changed signal from {}".format(user)) + transaction.on_commit(trigger_update) diff --git a/allianceauth/services/modules/teamspeak3/tests.py b/allianceauth/services/modules/teamspeak3/tests.py index 114efb86..bb22eb33 100644 --- a/allianceauth/services/modules/teamspeak3/tests.py +++ b/allianceauth/services/modules/teamspeak3/tests.py @@ -278,3 +278,15 @@ class Teamspeak3SignalsTestCase(TestCase): self.m2m_member.delete() # Trigger delete signal self.assertTrue(trigger_all_ts_update.called) + + @mock.patch(MODULE_PATH + '.signals.transaction') + @mock.patch(MODULE_PATH + '.signals.Teamspeak3Tasks.update_groups.delay') + def test_state_changed(self, update_groups, transaction): + # Overload transaction.on_commit so everything happens synchronously + transaction.on_commit = lambda fn: fn() + + state = AuthUtils.create_state('test', 1000, disconnect_signals=True) + self.member.profile.state = state + self.member.profile.save() + + self.assertTrue(update_groups.called)