From 1d5f2634f1041f5e8eea5f0472bc73f834125436 Mon Sep 17 00:00:00 2001 From: Aaron Kable Date: Tue, 29 Jun 2021 03:10:23 +0000 Subject: [PATCH] Update member when they are already in Discord server. --- .../services/modules/discord/managers.py | 23 ++++- .../modules/discord/tests/test_managers.py | 90 +++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/allianceauth/services/modules/discord/managers.py b/allianceauth/services/modules/discord/managers.py index d54599de..f430f164 100644 --- a/allianceauth/services/modules/discord/managers.py +++ b/allianceauth/services/modules/discord/managers.py @@ -83,10 +83,31 @@ class DiscordUserManager(models.Manager): if created is not False: if created is None: logger.debug( - "User %s with Discord ID %s is already a member.", + "User %s with Discord ID %s is already a member. Forcing a Refresh", user, user_id, ) + + # Force an update cause the discord API won't do it for us. + if role_ids: + role_ids = list(role_ids) + + updated = bot_client.modify_guild_member( + guild_id=DISCORD_GUILD_ID, + user_id=user_id, + role_ids=role_ids, + nick=nickname + ) + + if not updated: + # Could not update the new user so fail. + logger.warning( + "Failed to add user %s with Discord ID %s to Discord server", + user, + user_id, + ) + return False + self.update_or_create( user=user, defaults={ diff --git a/allianceauth/services/modules/discord/tests/test_managers.py b/allianceauth/services/modules/discord/tests/test_managers.py index 79eb2249..9ea50c4c 100644 --- a/allianceauth/services/modules/discord/tests/test_managers.py +++ b/allianceauth/services/modules/discord/tests/test_managers.py @@ -111,6 +111,40 @@ class TestAddUser(TestCase): self.assertSetEqual(set(kwargs['role_ids']), {1, 2, 3}) self.assertIsNone(kwargs['nick']) + def test_can_activate_existing_user_with_roles_no_nick( + self, + mock_user_formatted_nick, + mock_user_group_names, + mock_exchange_auth_code_for_token, + mock_DiscordClient + ): + roles = [ + create_matched_role(ROLE_ALPHA), + create_matched_role(ROLE_BRAVO), + create_matched_role(ROLE_CHARLIE) + ] + mock_user_formatted_nick.return_value = None + mock_user_group_names.return_value = ['a', 'b', 'c'] + mock_exchange_auth_code_for_token.return_value = self.access_token + mock_DiscordClient.return_value.current_user.return_value = self.user_info + mock_DiscordClient.return_value.match_or_create_roles_from_names\ + .return_value = roles + mock_DiscordClient.return_value.add_guild_member.return_value = None + mock_DiscordClient.return_value.modify_guild_member.return_value = True + + result = DiscordUser.objects.add_user(self.user, authorization_code='abcdef') + self.assertTrue(result) + self.assertTrue( + DiscordUser.objects.filter(user=self.user, uid=TEST_USER_ID).exists() + ) + self.assertTrue(mock_DiscordClient.return_value.add_guild_member.called) + self.assertTrue(mock_DiscordClient.return_value.modify_guild_member.called) + args, kwargs = mock_DiscordClient.return_value.modify_guild_member.call_args + self.assertEqual(kwargs['guild_id'], TEST_GUILD_ID) + self.assertEqual(kwargs['user_id'], TEST_USER_ID) + self.assertSetEqual(set(kwargs['role_ids']), {1, 2, 3}) + self.assertIsNone(kwargs['nick']) + @patch(MODULE_PATH + '.managers.DISCORD_SYNC_NAMES', True) def test_can_create_user_no_roles_with_nick( self, @@ -140,6 +174,36 @@ class TestAddUser(TestCase): self.assertIsNone(kwargs['role_ids']) self.assertEqual(kwargs['nick'], TEST_MAIN_NAME) + @patch(MODULE_PATH + '.managers.DISCORD_SYNC_NAMES', True) + def test_can_activate_existing_user_no_roles_with_nick( + self, + mock_user_formatted_nick, + mock_user_group_names, + mock_exchange_auth_code_for_token, + mock_DiscordClient + ): + mock_user_formatted_nick.return_value = TEST_MAIN_NAME + mock_user_group_names.return_value = [] + mock_exchange_auth_code_for_token.return_value = self.access_token + mock_DiscordClient.return_value.current_user.return_value = self.user_info + mock_DiscordClient.return_value.match_or_create_roles_from_names\ + .return_value = [] + mock_DiscordClient.return_value.add_guild_member.return_value = None + mock_DiscordClient.return_value.modify_guild_member.return_value = True + + result = DiscordUser.objects.add_user(self.user, authorization_code='abcdef') + self.assertTrue(result) + self.assertTrue( + DiscordUser.objects.filter(user=self.user, uid=TEST_USER_ID).exists() + ) + self.assertTrue(mock_DiscordClient.return_value.add_guild_member.called) + self.assertTrue(mock_DiscordClient.return_value.modify_guild_member.called) + args, kwargs = mock_DiscordClient.return_value.modify_guild_member.call_args + self.assertEqual(kwargs['guild_id'], TEST_GUILD_ID) + self.assertEqual(kwargs['user_id'], TEST_USER_ID) + self.assertIsNone(kwargs['role_ids']) + self.assertEqual(kwargs['nick'], TEST_MAIN_NAME) + @patch(MODULE_PATH + '.managers.DISCORD_SYNC_NAMES', False) def test_can_create_user_no_roles_and_without_nick_if_turned_off( self, @@ -183,6 +247,7 @@ class TestAddUser(TestCase): mock_DiscordClient.return_value.match_or_create_roles_from_names\ .return_value = [] mock_DiscordClient.return_value.add_guild_member.return_value = None + mock_DiscordClient.return_value.modify_guild_member.return_value = True result = DiscordUser.objects.add_user(self.user, authorization_code='abcdef') self.assertTrue(result) @@ -190,6 +255,31 @@ class TestAddUser(TestCase): DiscordUser.objects.filter(user=self.user, uid=TEST_USER_ID).exists() ) self.assertTrue(mock_DiscordClient.return_value.add_guild_member.called) + self.assertTrue(mock_DiscordClient.return_value.modify_guild_member.called) + + def test_can_activate_existing_guild_member_failure( + self, + mock_user_formatted_nick, + mock_user_group_names, + mock_exchange_auth_code_for_token, + mock_DiscordClient + ): + mock_user_formatted_nick.return_value = None + mock_user_group_names.return_value = [] + mock_exchange_auth_code_for_token.return_value = self.access_token + mock_DiscordClient.return_value.current_user.return_value = self.user_info + mock_DiscordClient.return_value.match_or_create_roles_from_names\ + .return_value = [] + mock_DiscordClient.return_value.add_guild_member.return_value = None + mock_DiscordClient.return_value.modify_guild_member.return_value = False + + result = DiscordUser.objects.add_user(self.user, authorization_code='abcdef') + self.assertFalse(result) + self.assertFalse( + DiscordUser.objects.filter(user=self.user, uid=TEST_USER_ID).exists() + ) + self.assertTrue(mock_DiscordClient.return_value.add_guild_member.called) + self.assertTrue(mock_DiscordClient.return_value.modify_guild_member.called) def test_return_false_when_user_creation_fails( self,