From a48c67de5ce7647b9c18f206d230a2b95ffca775 Mon Sep 17 00:00:00 2001 From: ErikKalkoken Date: Thu, 13 Feb 2020 23:20:22 +0100 Subject: [PATCH] Restructure Discord tests into folder and add admin testst --- .../modules/discord/tests/__init__.py | 10 + .../modules/discord/tests/test_admin.py | 268 ++++++++++++++++++ .../modules/discord/tests/test_hooks.py | 127 +++++++++ .../{tests.py => tests/test_managers.py} | 190 +------------ .../modules/discord/tests/test_views.py | 66 +++++ 5 files changed, 475 insertions(+), 186 deletions(-) create mode 100644 allianceauth/services/modules/discord/tests/__init__.py create mode 100644 allianceauth/services/modules/discord/tests/test_admin.py create mode 100644 allianceauth/services/modules/discord/tests/test_hooks.py rename allianceauth/services/modules/discord/{tests.py => tests/test_managers.py} (55%) create mode 100644 allianceauth/services/modules/discord/tests/test_views.py diff --git a/allianceauth/services/modules/discord/tests/__init__.py b/allianceauth/services/modules/discord/tests/__init__.py new file mode 100644 index 00000000..3d5481cb --- /dev/null +++ b/allianceauth/services/modules/discord/tests/__init__.py @@ -0,0 +1,10 @@ +from django.contrib.auth.models import User, Group, Permission +from allianceauth.tests.auth_utils import AuthUtils + +DEFAULT_AUTH_GROUP = 'Member' +MODULE_PATH = 'allianceauth.services.modules.discord' + +def add_permissions(): + permission = Permission.objects.get(codename='access_discord') + members = Group.objects.get_or_create(name=DEFAULT_AUTH_GROUP)[0] + AuthUtils.add_permissions_to_groups([permission], [members]) diff --git a/allianceauth/services/modules/discord/tests/test_admin.py b/allianceauth/services/modules/discord/tests/test_admin.py new file mode 100644 index 00000000..5d9c4dc1 --- /dev/null +++ b/allianceauth/services/modules/discord/tests/test_admin.py @@ -0,0 +1,268 @@ +from unittest.mock import patch + +from django.test import TestCase, RequestFactory +from django.contrib import admin +from django.contrib.admin.sites import AdminSite +from django.contrib.auth.models import User + +from allianceauth.authentication.models import CharacterOwnership +from allianceauth.eveonline.models import ( + EveCharacter, EveCorporationInfo, EveAllianceInfo +) + +from ....admin import ( + user_profile_pic, + user_username, + user_main_organization, + ServicesUserAdmin, + MainCorporationsFilter, + MainAllianceFilter +) +from ..admin import ( + DiscordUser, + DiscordUserAdmin +) + + +class TestDiscordUserAdmin(TestCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + + # user 1 - corp and alliance, normal user + cls.character_1 = EveCharacter.objects.create( + character_id='1001', + character_name='Bruce Wayne', + corporation_id='2001', + corporation_name='Wayne Technologies', + corporation_ticker='WT', + alliance_id='3001', + alliance_name='Wayne Enterprises', + alliance_ticker='WE', + ) + cls.character_1a = EveCharacter.objects.create( + character_id='1002', + character_name='Batman', + corporation_id='2001', + corporation_name='Wayne Technologies', + corporation_ticker='WT', + alliance_id='3001', + alliance_name='Wayne Enterprises', + alliance_ticker='WE', + ) + alliance = EveAllianceInfo.objects.create( + alliance_id='3001', + alliance_name='Wayne Enterprises', + alliance_ticker='WE', + executor_corp_id='2001' + ) + EveCorporationInfo.objects.create( + corporation_id='2001', + corporation_name='Wayne Technologies', + corporation_ticker='WT', + member_count=42, + alliance=alliance + ) + cls.user_1 = User.objects.create_user( + cls.character_1.character_name.replace(' ', '_'), + 'abc@example.com', + 'password' + ) + CharacterOwnership.objects.create( + character=cls.character_1, + owner_hash='x1' + cls.character_1.character_name, + user=cls.user_1 + ) + CharacterOwnership.objects.create( + character=cls.character_1a, + owner_hash='x1' + cls.character_1a.character_name, + user=cls.user_1 + ) + cls.user_1.profile.main_character = cls.character_1 + cls.user_1.profile.save() + DiscordUser.objects.create( + user=cls.user_1, + uid=1001 + ) + + # user 2 - corp only, staff + cls.character_2 = EveCharacter.objects.create( + character_id=1003, + character_name='Clark Kent', + corporation_id=2002, + corporation_name='Daily Planet', + corporation_ticker='DP', + alliance_id=None + ) + EveCorporationInfo.objects.create( + corporation_id=2002, + corporation_name='Daily Plane', + corporation_ticker='DP', + member_count=99, + alliance=None + ) + cls.user_2 = User.objects.create_user( + cls.character_2.character_name.replace(' ', '_'), + 'abc@example.com', + 'password' + ) + CharacterOwnership.objects.create( + character=cls.character_2, + owner_hash='x1' + cls.character_2.character_name, + user=cls.user_2 + ) + cls.user_2.profile.main_character = cls.character_2 + cls.user_2.profile.save() + DiscordUser.objects.create( + user=cls.user_2, + uid=1002 + ) + + # user 3 - no main, no group, superuser + cls.character_3 = EveCharacter.objects.create( + character_id=1101, + character_name='Lex Luthor', + corporation_id=2101, + corporation_name='Lex Corp', + corporation_ticker='LC', + alliance_id=None + ) + EveCorporationInfo.objects.create( + corporation_id=2101, + corporation_name='Lex Corp', + corporation_ticker='LC', + member_count=666, + alliance=None + ) + EveAllianceInfo.objects.create( + alliance_id='3101', + alliance_name='Lex World Domination', + alliance_ticker='LWD', + executor_corp_id='' + ) + cls.user_3 = User.objects.create_user( + cls.character_3.character_name.replace(' ', '_'), + 'abc@example.com', + 'password' + ) + CharacterOwnership.objects.create( + character=cls.character_3, + owner_hash='x1' + cls.character_3.character_name, + user=cls.user_3 + ) + DiscordUser.objects.create( + user=cls.user_3, + uid=1003 + ) + + + def setUp(self): + self.factory = RequestFactory() + self.modeladmin = DiscordUserAdmin( + model=DiscordUser, admin_site=AdminSite() + ) + + # column rendering + + def test_user_profile_pic_u1(self): + expected = ('') + self.assertEqual(user_profile_pic(self.user_1.discord), expected) + + def test_user_profile_pic_u3(self): + self.assertIsNone(user_profile_pic(self.user_3.discord)) + + def test_user_username_u1(self): + expected = ( + '' + 'Bruce_Wayne
Bruce Wayne'.format( + self.user_1.discord.pk + ) + ) + self.assertEqual(user_username(self.user_1.discord), expected) + + def test_user_username_u3(self): + expected = ( + '' + 'Lex_Luthor'.format(self.user_3.discord.pk) + ) + self.assertEqual(user_username(self.user_3.discord), expected) + + def test_user_main_organization_u1(self): + expected = 'Wayne Technologies
Wayne Enterprises' + result = user_main_organization(self.user_1.discord) + self.assertEqual(result, expected) + + def test_user_main_organization_u2(self): + expected = 'Daily Planet' + result = user_main_organization(self.user_2.discord) + self.assertEqual(result, expected) + + def test_user_main_organization_u3(self): + expected = None + result = user_main_organization(self.user_3.discord) + self.assertEqual(result, expected) + + # actions + + # filters + def test_filter_main_corporations(self): + + class DiscordUserAdminTest(ServicesUserAdmin): + list_filter = (MainCorporationsFilter,) + + my_modeladmin = DiscordUserAdminTest(DiscordUser, AdminSite()) + + # Make sure the lookups are correct + request = self.factory.get('/') + request.user = self.user_1 + changelist = my_modeladmin.get_changelist_instance(request) + filters = changelist.get_filters(request) + filterspec = filters[0][0] + expected = [ + ('2002', 'Daily Planet'), + ('2001', 'Wayne Technologies'), + ] + self.assertEqual(filterspec.lookup_choices, expected) + + # Make sure the correct queryset is returned + request = self.factory.get( + '/', + {'main_corporation_id__exact': self.character_1.corporation_id} + ) + request.user = self.user_1 + changelist = my_modeladmin.get_changelist_instance(request) + queryset = changelist.get_queryset(request) + expected = [self.user_1.discord] + self.assertSetEqual(set(queryset), set(expected)) + + def test_filter_main_alliances(self): + + class DiscordUserAdminTest(ServicesUserAdmin): + list_filter = (MainAllianceFilter,) + + my_modeladmin = DiscordUserAdminTest(DiscordUser, AdminSite()) + + # Make sure the lookups are correct + request = self.factory.get('/') + request.user = self.user_1 + changelist = my_modeladmin.get_changelist_instance(request) + filters = changelist.get_filters(request) + filterspec = filters[0][0] + expected = [ + ('3001', 'Wayne Enterprises'), + ] + self.assertEqual(filterspec.lookup_choices, expected) + + # Make sure the correct queryset is returned + request = self.factory.get( + '/', + {'main_alliance_id__exact': self.character_1.alliance_id} + ) + request.user = self.user_1 + changelist = my_modeladmin.get_changelist_instance(request) + queryset = changelist.get_queryset(request) + expected = [self.user_1.discord] + self.assertSetEqual(set(queryset), set(expected)) + \ No newline at end of file diff --git a/allianceauth/services/modules/discord/tests/test_hooks.py b/allianceauth/services/modules/discord/tests/test_hooks.py new file mode 100644 index 00000000..d7c82c8c --- /dev/null +++ b/allianceauth/services/modules/discord/tests/test_hooks.py @@ -0,0 +1,127 @@ +from unittest import mock + +from django.test import TestCase, RequestFactory +from django.contrib.auth.models import User +from django.core.exceptions import ObjectDoesNotExist +from allianceauth.tests.auth_utils import AuthUtils + +from ..auth_hooks import DiscordService +from ..models import DiscordUser +from ..tasks import DiscordTasks +from ..manager import DiscordOAuthManager + +from . import DEFAULT_AUTH_GROUP, add_permissions, MODULE_PATH + + +class DiscordHooksTestCase(TestCase): + def setUp(self): + self.member = 'member_user' + member = AuthUtils.create_member(self.member) + DiscordUser.objects.create(user=member, uid='12345') + self.none_user = 'none_user' + none_user = AuthUtils.create_user(self.none_user) + self.service = DiscordService + add_permissions() + + def test_has_account(self): + member = User.objects.get(username=self.member) + none_user = User.objects.get(username=self.none_user) + self.assertTrue(DiscordTasks.has_account(member)) + self.assertFalse(DiscordTasks.has_account(none_user)) + + def test_service_enabled(self): + service = self.service() + member = User.objects.get(username=self.member) + none_user = User.objects.get(username=self.none_user) + + self.assertTrue(service.service_active_for_user(member)) + self.assertFalse(service.service_active_for_user(none_user)) + + @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') + def test_update_all_groups(self, manager): + service = self.service() + service.update_all_groups() + # Check member and blue user have groups updated + self.assertTrue(manager.update_groups.called) + self.assertEqual(manager.update_groups.call_count, 1) + + def test_update_groups(self): + # Check member has Member group updated + with mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') as manager: + service = self.service() + member = User.objects.get(username=self.member) + AuthUtils.disconnect_signals() + service.update_groups(member) + self.assertTrue(manager.update_groups.called) + args, kwargs = manager.update_groups.call_args + user_id, groups = args + self.assertIn(DEFAULT_AUTH_GROUP, groups) + self.assertEqual(user_id, member.discord.uid) + + # Check none user does not have groups updated + with mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') as manager: + service = self.service() + none_user = User.objects.get(username=self.none_user) + service.update_groups(none_user) + self.assertFalse(manager.update_groups.called) + + @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') + def test_validate_user(self, manager): + service = self.service() + # Test member is not deleted + member = User.objects.get(username=self.member) + service.validate_user(member) + self.assertTrue(member.discord) + + # Test none user is deleted + none_user = User.objects.get(username=self.none_user) + DiscordUser.objects.create(user=none_user, uid='abc123') + service.validate_user(none_user) + self.assertTrue(manager.delete_user.called) + with self.assertRaises(ObjectDoesNotExist): + none_discord = User.objects.get(username=self.none_user).discord + + @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') + def test_sync_nickname(self, manager): + service = self.service() + member = User.objects.get(username=self.member) + AuthUtils.add_main_character(member, 'test user', '12345', corp_ticker='AAUTH') + + service.sync_nickname(member) + + self.assertTrue(manager.update_nickname.called) + args, kwargs = manager.update_nickname.call_args + self.assertEqual(args[0], member.discord.uid) + self.assertEqual(args[1], 'test user') + + @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') + def test_delete_user(self, manager): + member = User.objects.get(username=self.member) + + service = self.service() + result = service.delete_user(member) + + self.assertTrue(result) + self.assertTrue(manager.delete_user.called) + with self.assertRaises(ObjectDoesNotExist): + discord_user = User.objects.get(username=self.member).discord + + def test_render_services_ctrl(self): + service = self.service() + member = User.objects.get(username=self.member) + request = RequestFactory().get('/services/') + request.user = member + + response = service.render_services_ctrl(request) + self.assertTemplateUsed(service.service_ctrl_template) + self.assertIn('/discord/reset/', response) + self.assertIn('/discord/deactivate/', response) + + # Test register becomes available + member.discord.delete() + member = User.objects.get(username=self.member) + request.user = member + response = service.render_services_ctrl(request) + self.assertIn('/discord/activate/', response) + + # TODO: Test update nicknames diff --git a/allianceauth/services/modules/discord/tests.py b/allianceauth/services/modules/discord/tests/test_managers.py similarity index 55% rename from allianceauth/services/modules/discord/tests.py rename to allianceauth/services/modules/discord/tests/test_managers.py index 87916fd0..2ee838a7 100644 --- a/allianceauth/services/modules/discord/tests.py +++ b/allianceauth/services/modules/discord/tests/test_managers.py @@ -2,197 +2,15 @@ import json import urllib import datetime import requests_mock -from django_webtest import WebTest from unittest import mock -from django.test import TestCase, RequestFactory -from django.contrib.auth.models import User, Group, Permission -from django.core.exceptions import ObjectDoesNotExist +from django.test import TestCase from django.conf import settings -from allianceauth.tests.auth_utils import AuthUtils -from .auth_hooks import DiscordService -from .models import DiscordUser -from .tasks import DiscordTasks -from .manager import DiscordOAuthManager -from . import manager +from ..manager import DiscordOAuthManager +from .. import manager - -MODULE_PATH = 'allianceauth.services.modules.discord' -DEFAULT_AUTH_GROUP = 'Member' - - -def add_permissions(): - permission = Permission.objects.get(codename='access_discord') - members = Group.objects.get_or_create(name=DEFAULT_AUTH_GROUP)[0] - AuthUtils.add_permissions_to_groups([permission], [members]) - - -class DiscordHooksTestCase(TestCase): - def setUp(self): - self.member = 'member_user' - member = AuthUtils.create_member(self.member) - DiscordUser.objects.create(user=member, uid='12345') - self.none_user = 'none_user' - none_user = AuthUtils.create_user(self.none_user) - self.service = DiscordService - add_permissions() - - def test_has_account(self): - member = User.objects.get(username=self.member) - none_user = User.objects.get(username=self.none_user) - self.assertTrue(DiscordTasks.has_account(member)) - self.assertFalse(DiscordTasks.has_account(none_user)) - - def test_service_enabled(self): - service = self.service() - member = User.objects.get(username=self.member) - none_user = User.objects.get(username=self.none_user) - - self.assertTrue(service.service_active_for_user(member)) - self.assertFalse(service.service_active_for_user(none_user)) - - @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') - def test_update_all_groups(self, manager): - service = self.service() - service.update_all_groups() - # Check member and blue user have groups updated - self.assertTrue(manager.update_groups.called) - self.assertEqual(manager.update_groups.call_count, 1) - - def test_update_groups(self): - # Check member has Member group updated - with mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') as manager: - service = self.service() - member = User.objects.get(username=self.member) - AuthUtils.disconnect_signals() - service.update_groups(member) - self.assertTrue(manager.update_groups.called) - args, kwargs = manager.update_groups.call_args - user_id, groups = args - self.assertIn(DEFAULT_AUTH_GROUP, groups) - self.assertEqual(user_id, member.discord.uid) - - # Check none user does not have groups updated - with mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') as manager: - service = self.service() - none_user = User.objects.get(username=self.none_user) - service.update_groups(none_user) - self.assertFalse(manager.update_groups.called) - - @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') - def test_validate_user(self, manager): - service = self.service() - # Test member is not deleted - member = User.objects.get(username=self.member) - service.validate_user(member) - self.assertTrue(member.discord) - - # Test none user is deleted - none_user = User.objects.get(username=self.none_user) - DiscordUser.objects.create(user=none_user, uid='abc123') - service.validate_user(none_user) - self.assertTrue(manager.delete_user.called) - with self.assertRaises(ObjectDoesNotExist): - none_discord = User.objects.get(username=self.none_user).discord - - @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') - def test_sync_nickname(self, manager): - service = self.service() - member = User.objects.get(username=self.member) - AuthUtils.add_main_character(member, 'test user', '12345', corp_ticker='AAUTH') - - service.sync_nickname(member) - - self.assertTrue(manager.update_nickname.called) - args, kwargs = manager.update_nickname.call_args - self.assertEqual(args[0], member.discord.uid) - self.assertEqual(args[1], 'test user') - - @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') - def test_delete_user(self, manager): - member = User.objects.get(username=self.member) - - service = self.service() - result = service.delete_user(member) - - self.assertTrue(result) - self.assertTrue(manager.delete_user.called) - with self.assertRaises(ObjectDoesNotExist): - discord_user = User.objects.get(username=self.member).discord - - def test_render_services_ctrl(self): - service = self.service() - member = User.objects.get(username=self.member) - request = RequestFactory().get('/services/') - request.user = member - - response = service.render_services_ctrl(request) - self.assertTemplateUsed(service.service_ctrl_template) - self.assertIn('/discord/reset/', response) - self.assertIn('/discord/deactivate/', response) - - # Test register becomes available - member.discord.delete() - member = User.objects.get(username=self.member) - request.user = member - response = service.render_services_ctrl(request) - self.assertIn('/discord/activate/', response) - - # TODO: Test update nicknames - - -class DiscordViewsTestCase(WebTest): - def setUp(self): - self.member = AuthUtils.create_member('auth_member') - AuthUtils.add_main_character(self.member, 'test character', '1234', '2345', 'test corp', 'testc') - add_permissions() - - def login(self): - self.app.set_user(self.member) - - @mock.patch(MODULE_PATH + '.views.DiscordOAuthManager') - def test_activate(self, manager): - self.login() - manager.generate_oauth_redirect_url.return_value = '/example.com/oauth/' - response = self.app.get('/discord/activate/', auto_follow=False) - self.assertRedirects(response, expected_url='/example.com/oauth/', target_status_code=404) - - @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') - def test_callback(self, manager): - self.login() - manager.add_user.return_value = '1234' - response = self.app.get('/discord/callback/', params={'code': '1234'}) - - self.member = User.objects.get(pk=self.member.pk) - - self.assertTrue(manager.add_user.called) - self.assertEqual(manager.update_nickname.called, settings.DISCORD_SYNC_NAMES) - self.assertEqual(self.member.discord.uid, '1234') - self.assertRedirects(response, expected_url='/services/', target_status_code=200) - - @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') - def test_reset(self, manager): - self.login() - DiscordUser.objects.create(user=self.member, uid='12345') - manager.delete_user.return_value = True - - response = self.app.get('/discord/reset/') - - self.assertRedirects(response, expected_url='/discord/activate/', target_status_code=302) - - @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') - def test_deactivate(self, manager): - self.login() - DiscordUser.objects.create(user=self.member, uid='12345') - manager.delete_user.return_value = True - - response = self.app.get('/discord/deactivate/') - - self.assertTrue(manager.delete_user.called) - self.assertRedirects(response, expected_url='/services/', target_status_code=200) - with self.assertRaises(ObjectDoesNotExist): - discord_user = User.objects.get(pk=self.member.pk).discord +from . import DEFAULT_AUTH_GROUP, add_permissions, MODULE_PATH class DiscordManagerTestCase(TestCase): diff --git a/allianceauth/services/modules/discord/tests/test_views.py b/allianceauth/services/modules/discord/tests/test_views.py new file mode 100644 index 00000000..8de0e2eb --- /dev/null +++ b/allianceauth/services/modules/discord/tests/test_views.py @@ -0,0 +1,66 @@ +from django_webtest import WebTest +from unittest import mock + +from django.test import TestCase +from django.contrib.auth.models import User +from django.core.exceptions import ObjectDoesNotExist +from django.conf import settings +from allianceauth.tests.auth_utils import AuthUtils + +from ..models import DiscordUser +from ..manager import DiscordOAuthManager + +from . import DEFAULT_AUTH_GROUP, add_permissions, MODULE_PATH + + +class DiscordViewsTestCase(WebTest): + def setUp(self): + self.member = AuthUtils.create_member('auth_member') + AuthUtils.add_main_character(self.member, 'test character', '1234', '2345', 'test corp', 'testc') + add_permissions() + + def login(self): + self.app.set_user(self.member) + + @mock.patch(MODULE_PATH + '.views.DiscordOAuthManager') + def test_activate(self, manager): + self.login() + manager.generate_oauth_redirect_url.return_value = '/example.com/oauth/' + response = self.app.get('/discord/activate/', auto_follow=False) + self.assertRedirects(response, expected_url='/example.com/oauth/', target_status_code=404) + + @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') + def test_callback(self, manager): + self.login() + manager.add_user.return_value = '1234' + response = self.app.get('/discord/callback/', params={'code': '1234'}) + + self.member = User.objects.get(pk=self.member.pk) + + self.assertTrue(manager.add_user.called) + self.assertEqual(manager.update_nickname.called, settings.DISCORD_SYNC_NAMES) + self.assertEqual(self.member.discord.uid, '1234') + self.assertRedirects(response, expected_url='/services/', target_status_code=200) + + @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') + def test_reset(self, manager): + self.login() + DiscordUser.objects.create(user=self.member, uid='12345') + manager.delete_user.return_value = True + + response = self.app.get('/discord/reset/') + + self.assertRedirects(response, expected_url='/discord/activate/', target_status_code=302) + + @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') + def test_deactivate(self, manager): + self.login() + DiscordUser.objects.create(user=self.member, uid='12345') + manager.delete_user.return_value = True + + response = self.app.get('/discord/deactivate/') + + self.assertTrue(manager.delete_user.called) + self.assertRedirects(response, expected_url='/services/', target_status_code=200) + with self.assertRaises(ObjectDoesNotExist): + discord_user = User.objects.get(pk=self.member.pk).discord