[v2] Alliance and Corp Autogroups (#902)

* Add pseudo foreign keys to EveCharacter model

* Ensure populate alliance is called on create

* Add unit tests for model

* Add extra signal for state removal/addition

* Add unit tests for signals

* Add tests for manager

* Add migrations

* Add sync command to admin control

* Prevent whitespace being stripped from group names

* Add documentation
This commit is contained in:
Basraah
2017-12-04 12:52:05 +10:00
committed by GitHub
parent 995a44de0a
commit 70c4b17518
15 changed files with 1075 additions and 0 deletions

View File

@@ -0,0 +1 @@
default_app_config = 'allianceauth.eveonline.autogroups.apps.EveAutogroupsConfig'

View File

@@ -0,0 +1,39 @@
from django.contrib import admin
from django.db import models
from .models import AutogroupsConfig
import logging
logger = logging.getLogger(__name__)
def sync_user_groups(modeladmin, request, queryset):
for agc in queryset:
logger.debug("update_all_states_group_membership for {}".format(agc))
agc.update_all_states_group_membership()
class AutogroupsConfigAdmin(admin.ModelAdmin):
formfield_overrides = {
models.CharField: {'strip': False}
}
def get_readonly_fields(self, request, obj=None):
if obj: # This is the case when obj is already created i.e. it's an edit
return [
'corp_group_prefix', 'corp_name_source', 'alliance_group_prefix', 'alliance_name_source',
'replace_spaces', 'replace_spaces_with'
]
else:
return []
def get_actions(self, request):
actions = super(AutogroupsConfigAdmin, self).get_actions(request)
actions['sync_user_groups'] = (sync_user_groups,
'sync_user_groups',
'Sync all users groups for this Autogroup Config')
return actions
admin.site.register(AutogroupsConfig, AutogroupsConfigAdmin)

View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class EveAutogroupsConfig(AppConfig):
name = 'allianceauth.eveonline.autogroups'
label = 'eve_autogroups'

View File

@@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-29 14:44
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('authentication', '0015_user_profiles'),
('auth', '0008_alter_user_username_max_length'),
('eveonline', '0009_on_delete'),
]
operations = [
migrations.CreateModel(
name='AutogroupsConfig',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('corp_groups', models.BooleanField(default=False, help_text='Setting this to false will delete all the created groups.')),
('corp_group_prefix', models.CharField(blank=True, default='Corp ', max_length=50)),
('corp_name_source', models.CharField(choices=[('ticker', 'Ticker'), ('name', 'Full name')], default='name', max_length=20)),
('alliance_groups', models.BooleanField(default=False, help_text='Setting this to false will delete all the created groups.')),
('alliance_group_prefix', models.CharField(blank=True, default='Alliance ', max_length=50)),
('alliance_name_source', models.CharField(choices=[('ticker', 'Ticker'), ('name', 'Full name')], default='name', max_length=20)),
('replace_spaces', models.BooleanField(default=False)),
('replace_spaces_with', models.CharField(blank=True, default='', help_text='Any spaces in the group name will be replaced with this.', max_length=10)),
('states', models.ManyToManyField(related_name='autogroups', to='authentication.State')),
],
),
migrations.CreateModel(
name='ManagedGroup',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
),
migrations.CreateModel(
name='ManagedAllianceGroup',
fields=[
('managedgroup_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='eve_autogroups.ManagedGroup')),
('alliance', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eveonline.EveAllianceInfo')),
],
bases=('eve_autogroups.managedgroup',),
),
migrations.CreateModel(
name='ManagedCorpGroup',
fields=[
('managedgroup_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='eve_autogroups.ManagedGroup')),
('corp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eveonline.EveCorporationInfo')),
],
bases=('eve_autogroups.managedgroup',),
),
migrations.AddField(
model_name='managedgroup',
name='config',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eve_autogroups.AutogroupsConfig'),
),
migrations.AddField(
model_name='managedgroup',
name='group',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group'),
),
migrations.AddField(
model_name='autogroupsconfig',
name='alliance_managed_groups',
field=models.ManyToManyField(help_text="A list of alliance groups created and maintained by this AutogroupConfig. You should not edit this list unless you know what you're doing.", related_name='alliance_managed_config', through='eve_autogroups.ManagedAllianceGroup', to='auth.Group'),
),
migrations.AddField(
model_name='autogroupsconfig',
name='corp_managed_groups',
field=models.ManyToManyField(help_text="A list of corporation groups created and maintained by this AutogroupConfig. You should not edit this list unless you know what you're doing.", related_name='corp_managed_config', through='eve_autogroups.ManagedCorpGroup', to='auth.Group'),
),
]

View File

@@ -0,0 +1,238 @@
import logging
from django.db import models, transaction
from django.contrib.auth.models import Group, User
from django.core.exceptions import ObjectDoesNotExist
from allianceauth.authentication.models import State
from allianceauth.eveonline.models import EveCorporationInfo, EveAllianceInfo
logger = logging.getLogger(__name__)
def get_users_for_state(state: State):
return User.objects.select_related('profile').prefetch_related('profile__main_character')\
.filter(profile__state__pk=state.pk)
class AutogroupsConfigManager(models.Manager):
def update_groups_for_state(self, state: State):
"""
Update all the Group memberships for the users
who have State
:param state: State to update for
:return:
"""
users = get_users_for_state(state)
for config in self.filter(states=state):
logger.debug("in state loop")
for user in users:
logger.debug("in user loop for {}".format(user))
config.update_group_membership_for_user(user)
def update_groups_for_user(self, user: User, state: State = None):
"""
Update the Group memberships for the given users state
:param user: User to update for
:param state: State to update user for
:return:
"""
if state is None:
state = user.profile.state
for config in self.filter(states=state):
config.update_group_membership_for_user(user)
class AutogroupsConfig(models.Model):
OPT_TICKER = 'ticker'
OPT_NAME = 'name'
NAME_OPTIONS = (
(OPT_TICKER, 'Ticker'),
(OPT_NAME, 'Full name'),
)
states = models.ManyToManyField(State, related_name='autogroups')
corp_groups = models.BooleanField(default=False,
help_text="Setting this to false will delete all the created groups.")
corp_group_prefix = models.CharField(max_length=50, default='Corp ', blank=True)
corp_name_source = models.CharField(max_length=20, choices=NAME_OPTIONS, default=OPT_NAME)
alliance_groups = models.BooleanField(default=False,
help_text="Setting this to false will delete all the created groups.")
alliance_group_prefix = models.CharField(max_length=50, default='Alliance ', blank=True)
alliance_name_source = models.CharField(max_length=20, choices=NAME_OPTIONS, default=OPT_NAME)
corp_managed_groups = models.ManyToManyField(
Group, through='ManagedCorpGroup', related_name='corp_managed_config',
help_text='A list of corporation groups created and maintained by this AutogroupConfig. '
'You should not edit this list unless you know what you\'re doing.')
alliance_managed_groups = models.ManyToManyField(
Group, through='ManagedAllianceGroup', related_name='alliance_managed_config',
help_text='A list of alliance groups created and maintained by this AutogroupConfig. '
'You should not edit this list unless you know what you\'re doing.')
replace_spaces = models.BooleanField(default=False)
replace_spaces_with = models.CharField(
max_length=10, default='', blank=True,
help_text='Any spaces in the group name will be replaced with this.')
objects = AutogroupsConfigManager()
def __init__(self, *args, **kwargs):
super(AutogroupsConfig, self).__init__(*args, **kwargs)
def __repr__(self):
return self.__class__.__name__
def __str__(self):
return 'States: ' + (' '.join(list(self.states.all().values_list('name', flat=True))) if self.pk else str(None))
def update_all_states_group_membership(self):
list(map(self.update_group_membership_for_state, self.states.all()))
def update_group_membership_for_state(self, state: State):
list(map(self.update_group_membership_for_user, get_users_for_state(state)))
@transaction.atomic
def update_group_membership_for_user(self, user: User):
self.update_alliance_group_membership(user)
self.update_corp_group_membership(user)
def user_entitled_to_groups(self, user: User) -> bool:
try:
return user.profile.state in self.states.all()
except ObjectDoesNotExist:
return False
@transaction.atomic
def update_alliance_group_membership(self, user: User):
group = None
try:
if not self.alliance_groups or not self.user_entitled_to_groups(user):
logger.debug('User {} does not have required state'.format(user))
return
else:
alliance = user.profile.main_character.alliance
if alliance is None:
return
group = self.get_alliance_group(alliance)
except EveAllianceInfo.DoesNotExist:
logger.warning('User {} main characters alliance does not exist in the database.'
' Group membership not updated'.format(user))
except AttributeError:
logger.warning('User {} does not have a main character. Group membership not updated'.format(user))
finally:
self.remove_user_from_corp_groups(user, except_group=group)
if group is not None:
user.groups.add(group)
@transaction.atomic
def update_corp_group_membership(self, user: User):
group = None
try:
if not self.corp_groups or not self.user_entitled_to_groups(user):
logger.debug('User {} does not have required state'.format(user))
else:
corp = user.profile.main_character.corporation
group = self.get_corp_group(corp)
except EveCorporationInfo.DoesNotExist:
logger.warning('User {} main characters corporation does not exist in the database.'
' Group membership not updated'.format(user))
except AttributeError:
logger.warning('User {} does not have a main character. Group membership not updated'.format(user))
finally:
self.remove_user_from_corp_groups(user, except_group=group)
if group is not None:
user.groups.add(group)
@transaction.atomic
def remove_user_from_alliance_groups(self, user: User, except_group: Group = None):
remove_groups = user.groups.filter(pk__in=self.alliance_managed_groups.all().values_list('pk', flat=True))
if except_group is not None:
remove_groups = remove_groups.exclude(pk=except_group.pk)
list(map(user.groups.remove, remove_groups))
@transaction.atomic
def remove_user_from_corp_groups(self, user: User, except_group: Group = None):
remove_groups = user.groups.filter(pk__in=self.corp_managed_groups.all().values_list('pk', flat=True))
if except_group is not None:
remove_groups = remove_groups.exclude(pk=except_group.pk)
list(map(user.groups.remove, remove_groups))
def get_alliance_group(self, alliance: EveAllianceInfo) -> Group:
return self.create_alliance_group(alliance)
def get_corp_group(self, corp: EveCorporationInfo) -> Group:
return self.create_corp_group(corp)
@transaction.atomic
def create_alliance_group(self, alliance: EveAllianceInfo) -> Group:
group, created = Group.objects.get_or_create(name=self.get_alliance_group_name(alliance))
if created:
ManagedAllianceGroup.objects.create(group=group, config=self, alliance=alliance)
return group
@transaction.atomic
def create_corp_group(self, corp: EveCorporationInfo) -> Group:
group, created = Group.objects.get_or_create(name=self.get_corp_group_name(corp))
if created:
ManagedCorpGroup.objects.create(group=group, config=self, corp=corp)
return group
def delete_alliance_managed_groups(self):
"""
Deletes ALL managed alliance groups
"""
self.alliance_managed_groups.all().delete()
def delete_corp_managed_groups(self):
"""
Deletes ALL managed corp groups
"""
self.corp_managed_groups.all().delete()
def get_alliance_group_name(self, alliance: EveAllianceInfo) -> str:
if self.alliance_name_source == self.OPT_TICKER:
name = alliance.alliance_ticker
elif self.alliance_name_source == self.OPT_NAME:
name = alliance.alliance_name
else:
raise NameSourceException('Not a valid name source')
return self._replace_spaces(self.alliance_group_prefix + name)
def get_corp_group_name(self, corp: EveCorporationInfo) -> str:
if self.corp_name_source == self.OPT_TICKER:
name = corp.corporation_ticker
elif self.corp_name_source == self.OPT_NAME:
name = corp.corporation_name
else:
raise NameSourceException('Not a valid name source')
return self._replace_spaces(self.corp_group_prefix + name)
def _replace_spaces(self, name: str) -> str:
"""
Replace the spaces in the given name based on the config
:param name: name to replace spaces in
:return: name with spaces replaced with the configured character(s) or unchanged if configured
"""
if self.replace_spaces:
return name.strip().replace(' ', str(self.replace_spaces_with))
return name
class ManagedGroup(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
config = models.ForeignKey(AutogroupsConfig, on_delete=models.CASCADE)
class ManagedCorpGroup(ManagedGroup):
corp = models.ForeignKey(EveCorporationInfo, on_delete=models.CASCADE)
class ManagedAllianceGroup(ManagedGroup):
alliance = models.ForeignKey(EveAllianceInfo, on_delete=models.CASCADE)
class NameSourceException(Exception):
pass

View File

@@ -0,0 +1,66 @@
import logging
from django.dispatch import receiver
from django.db.models.signals import pre_save, post_save, pre_delete, m2m_changed
from allianceauth.authentication.models import UserProfile, State
from .models import AutogroupsConfig
logger = logging.getLogger(__name__)
@receiver(pre_save, sender=AutogroupsConfig)
def pre_save_config(sender, instance, *args, **kwargs):
"""
Checks if enable was toggled on group config and
deletes groups if necessary.
"""
logger.debug("Received pre_save from {}".format(instance))
if not instance.pk:
# new model being created
return
try:
old_instance = AutogroupsConfig.objects.get(pk=instance.pk)
# Check if enable was toggled, delete groups?
if old_instance.alliance_groups is True and instance.alliance_groups is False:
instance.delete_alliance_managed_groups()
if old_instance.corp_groups is True and instance.corp_groups is False:
instance.delete_corp_managed_groups()
except AutogroupsConfig.DoesNotExist:
pass
@receiver(pre_delete, sender=AutogroupsConfig)
def pre_delete_config(sender, instance, *args, **kwargs):
"""
Delete groups on deleting config
"""
instance.delete_corp_managed_groups()
instance.delete_alliance_managed_groups()
@receiver(post_save, sender=UserProfile)
def check_groups_on_profile_update(sender, instance, created, *args, **kwargs):
"""
Trigger check when main character or state changes.
"""
update_fields = kwargs.pop('update_fields', []) or []
if 'main_character' in update_fields or 'state' in update_fields:
AutogroupsConfig.objects.update_groups_for_user(instance.user)
@receiver(m2m_changed, sender=AutogroupsConfig.states.through)
def autogroups_states_changed(sender, instance, action, reverse, model, pk_set, *args, **kwargs):
"""
Trigger group membership update when a state is added or removed from
an autogroup config.
"""
if action.startswith('post_'):
for pk in pk_set:
try:
state = State.objects.get(pk=pk)
instance.update_group_membership_for_state(state)
except State.DoesNotExist:
# Deleted States handled by the profile state change
pass

View File

@@ -0,0 +1,27 @@
from unittest import mock
from django.db.models.signals import pre_save, post_save, pre_delete, m2m_changed
from allianceauth.authentication.models import UserProfile
from allianceauth.authentication.signals import state_changed
from allianceauth.eveonline.models import EveCharacter
from .. import signals
from ..models import AutogroupsConfig
MODULE_PATH = 'allianceauth.eveonline.autogroups'
def patch(target, *args, **kwargs):
return mock.patch('{}{}'.format(MODULE_PATH, target), *args, **kwargs)
def connect_signals():
pre_save.connect(receiver=signals.pre_save_config, sender=AutogroupsConfig)
pre_delete.connect(receiver=signals.pre_delete_config, sender=AutogroupsConfig)
post_save.connect(receiver=signals.check_groups_on_profile_update, sender=UserProfile)
m2m_changed.connect(receiver=signals.autogroups_states_changed, sender=AutogroupsConfig.states.through)
def disconnect_signals():
pre_save.disconnect(receiver=signals.pre_save_config, sender=AutogroupsConfig)
pre_delete.disconnect(receiver=signals.pre_delete_config, sender=AutogroupsConfig)
post_save.disconnect(receiver=signals.check_groups_on_profile_update, sender=UserProfile)
m2m_changed.disconnect(receiver=signals.autogroups_states_changed, sender=AutogroupsConfig.states.through)

View File

@@ -0,0 +1,34 @@
from django.test import TestCase
from allianceauth.tests.auth_utils import AuthUtils
from ..models import AutogroupsConfig
from . import patch
class AutogroupsConfigManagerTestCase(TestCase):
def test_update_groups_for_state(self, ):
member = AuthUtils.create_member('test member')
obj = AutogroupsConfig.objects.create()
obj.states.add(member.profile.state)
with patch('.models.AutogroupsConfig.update_group_membership_for_user') as update_group_membership_for_user:
AutogroupsConfig.objects.update_groups_for_state(member.profile.state)
self.assertTrue(update_group_membership_for_user.called)
self.assertEqual(update_group_membership_for_user.call_count, 1)
args, kwargs = update_group_membership_for_user.call_args
self.assertEqual(args[0], member)
def test_update_groups_for_user(self):
member = AuthUtils.create_member('test member')
obj = AutogroupsConfig.objects.create()
obj.states.add(member.profile.state)
with patch('.models.AutogroupsConfig.update_group_membership_for_user') as update_group_membership_for_user:
AutogroupsConfig.objects.update_groups_for_user(member)
self.assertTrue(update_group_membership_for_user.called)
self.assertEqual(update_group_membership_for_user.call_count, 1)
args, kwargs = update_group_membership_for_user.call_args
self.assertEqual(args[0], member)

View File

@@ -0,0 +1,342 @@
from django.test import TestCase
from django.contrib.auth.models import Group
from allianceauth.tests.auth_utils import AuthUtils
from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo
from ..models import AutogroupsConfig, get_users_for_state
from . import patch, connect_signals, disconnect_signals
class AutogroupsConfigTestCase(TestCase):
def setUp(self):
# Disconnect signals
disconnect_signals()
self.member = AuthUtils.create_member('test user')
state = AuthUtils.get_member_state()
self.alliance = EveAllianceInfo.objects.create(
alliance_id='3456',
alliance_name='alliance name',
alliance_ticker='TIKR',
executor_corp_id='2345',
)
self.corp = EveCorporationInfo.objects.create(
corporation_id='2345',
corporation_name='corp name',
corporation_ticker='TIKK',
member_count=10,
alliance=self.alliance,
)
state.member_alliances.add(self.alliance)
state.member_corporations.add(self.corp)
def tearDown(self):
# Reconnect signals
connect_signals()
def test_get_users_for_state(self):
result = get_users_for_state(self.member.profile.state)
self.assertIn(self.member, result)
self.assertEqual(len(result), 1)
@patch('.models.AutogroupsConfig.update_alliance_group_membership')
@patch('.models.AutogroupsConfig.update_corp_group_membership')
def test_update_group_membership(self, update_corp, update_alliance):
agc = AutogroupsConfig.objects.create()
agc.update_group_membership_for_user(self.member)
self.assertTrue(update_corp.called)
self.assertTrue(update_alliance.called)
args, kwargs = update_corp.call_args
self.assertEqual(args[0], self.member)
args, kwargs = update_alliance.call_args
self.assertEqual(args[0], self.member)
def test_update_alliance_group_membership(self):
obj = AutogroupsConfig.objects.create(alliance_groups=True)
obj.states.add(AuthUtils.get_member_state())
char = EveCharacter.objects.create(
character_id='1234',
character_name='test character',
corporation_id='2345',
corporation_name='test corp',
corporation_ticker='tickr',
alliance_id='3456',
alliance_name='alliance name',
)
self.member.profile.main_character = char
self.member.profile.save()
pre_groups = self.member.groups.all()
# Act
obj.update_alliance_group_membership(self.member)
group = obj.create_alliance_group(self.alliance)
group_qs = Group.objects.filter(pk=group.pk)
self.assertIn(group, self.member.groups.all())
self.assertQuerysetEqual(self.member.groups.all(), map(repr, pre_groups | group_qs), ordered=False)
def test_update_alliance_group_membership_no_main_character(self):
obj = AutogroupsConfig.objects.create()
obj.states.add(AuthUtils.get_member_state())
# Act
obj.update_alliance_group_membership(self.member)
group = obj.get_alliance_group(self.alliance)
self.assertNotIn(group, self.member.groups.all())
def test_update_alliance_group_membership_no_alliance_model(self):
obj = AutogroupsConfig.objects.create()
obj.states.add(AuthUtils.get_member_state())
char = EveCharacter.objects.create(
character_id='1234',
character_name='test character',
corporation_id='2345',
corporation_name='test corp',
corporation_ticker='tickr',
alliance_id='3459',
alliance_name='alliance name',
)
self.member.profile.main_character = char
self.member.profile.save()
# Act
obj.update_alliance_group_membership(self.member)
group = obj.get_alliance_group(self.alliance)
self.assertNotIn(group, self.member.groups.all())
def test_update_corp_group_membership(self):
obj = AutogroupsConfig.objects.create(corp_groups=True)
obj.states.add(AuthUtils.get_member_state())
char = EveCharacter.objects.create(
character_id='1234',
character_name='test character',
corporation_id='2345',
corporation_name='test corp',
corporation_ticker='tickr',
alliance_id='3456',
alliance_name='alliance name',
)
self.member.profile.main_character = char
self.member.profile.save()
pre_groups = self.member.groups.all()
# Act
obj.update_corp_group_membership(self.member)
group = obj.get_corp_group(self.corp)
group_qs = Group.objects.filter(pk=group.pk)
self.assertIn(group, self.member.groups.all())
self.assertQuerysetEqual(self.member.groups.all(), map(repr, pre_groups | group_qs), ordered=False)
def test_update_corp_group_membership_no_state(self):
obj = AutogroupsConfig.objects.create(corp_groups=True)
char = EveCharacter.objects.create(
character_id='1234',
character_name='test character',
corporation_id='2345',
corporation_name='test corp',
corporation_ticker='tickr',
alliance_id='3456',
alliance_name='alliance name',
)
self.member.profile.main_character = char
self.member.profile.save()
pre_groups = list(self.member.groups.all())
# Act
obj.update_corp_group_membership(self.member)
group = obj.get_corp_group(self.corp)
post_groups = list(self.member.groups.all())
self.assertNotIn(group, post_groups)
self.assertListEqual(pre_groups, post_groups)
def test_update_corp_group_membership_no_main_character(self):
obj = AutogroupsConfig.objects.create()
obj.states.add(AuthUtils.get_member_state())
# Act
obj.update_corp_group_membership(self.member)
group = obj.get_corp_group(self.corp)
self.assertNotIn(group, self.member.groups.all())
def test_update_corp_group_membership_no_corp_model(self):
obj = AutogroupsConfig.objects.create()
obj.states.add(AuthUtils.get_member_state())
char = EveCharacter.objects.create(
character_id='1234',
character_name='test character',
corporation_id='2348',
corporation_name='test corp',
corporation_ticker='tickr',
alliance_id='3456',
alliance_name='alliance name',
)
self.member.profile.main_character = char
self.member.profile.save()
# Act
obj.update_corp_group_membership(self.member)
group = obj.get_corp_group(self.corp)
self.assertNotIn(group, self.member.groups.all())
def test_remove_user_from_alliance_groups(self):
obj = AutogroupsConfig.objects.create()
result = obj.get_alliance_group(self.alliance)
result.user_set.add(self.member)
self.assertIn(result, self.member.groups.all())
# Act
obj.remove_user_from_alliance_groups(self.member)
self.assertNotIn(result, self.member.groups.all())
def test_remove_user_from_corp_groups(self):
obj = AutogroupsConfig.objects.create()
result = obj.get_corp_group(self.corp)
result.user_set.add(self.member)
self.assertIn(result, self.member.groups.all())
# Act
obj.remove_user_from_corp_groups(self.member)
self.assertNotIn(result, self.member.groups.all())
def test_get_alliance_group(self):
obj = AutogroupsConfig.objects.create()
result = obj.get_alliance_group(self.alliance)
group = Group.objects.get(name='Alliance alliance name')
self.assertEqual(result, group)
self.assertEqual(obj.get_alliance_group_name(self.alliance), result.name)
self.assertTrue(obj.alliance_managed_groups.filter(pk=result.pk).exists())
def test_get_corp_group(self):
obj = AutogroupsConfig.objects.create()
result = obj.get_corp_group(self.corp)
group = Group.objects.get(name='Corp corp name')
self.assertEqual(result, group)
self.assertEqual(obj.get_corp_group_name(self.corp), group.name)
self.assertTrue(obj.corp_managed_groups.filter(pk=group.pk).exists())
def test_create_alliance_group(self):
obj = AutogroupsConfig.objects.create()
result = obj.create_alliance_group(self.alliance)
group = Group.objects.get(name='Alliance alliance name')
self.assertEqual(result, group)
self.assertEqual(obj.get_alliance_group_name(self.alliance), group.name)
self.assertTrue(obj.alliance_managed_groups.filter(pk=group.pk).exists())
def test_create_corp_group(self):
obj = AutogroupsConfig.objects.create()
result = obj.create_corp_group(self.corp)
group = Group.objects.get(name='Corp corp name')
self.assertEqual(result, group)
self.assertEqual(obj.get_corp_group_name(self.corp), group.name)
self.assertTrue(obj.corp_managed_groups.filter(pk=group.pk).exists())
def test_delete_alliance_managed_groups(self):
obj = AutogroupsConfig.objects.create()
obj.create_alliance_group(self.alliance)
self.assertTrue(obj.alliance_managed_groups.all().exists())
obj.delete_alliance_managed_groups()
self.assertFalse(obj.alliance_managed_groups.all().exists())
def test_delete_corp_managed_groups(self):
obj = AutogroupsConfig.objects.create()
obj.create_corp_group(self.corp)
self.assertTrue(obj.corp_managed_groups.all().exists())
obj.delete_corp_managed_groups()
self.assertFalse(obj.corp_managed_groups.all().exists())
def test_get_alliance_group_name(self):
obj = AutogroupsConfig()
obj.replace_spaces = True
obj.replace_spaces_with = '_'
result = obj.get_alliance_group_name(self.alliance)
self.assertEqual(result, 'Alliance_alliance_name')
def test_get_alliance_group_name_ticker(self):
obj = AutogroupsConfig()
obj.replace_spaces = True
obj.replace_spaces_with = '_'
obj.alliance_name_source = obj.OPT_TICKER
result = obj.get_alliance_group_name(self.alliance)
self.assertEqual(result, 'Alliance_TIKR')
def test_get_corp_group_name(self):
obj = AutogroupsConfig()
obj.replace_spaces = True
obj.replace_spaces_with = '_'
result = obj.get_corp_group_name(self.corp)
self.assertEqual(result, 'Corp_corp_name')
def test_get_corp_group_name_ticker(self):
obj = AutogroupsConfig()
obj.replace_spaces = True
obj.replace_spaces_with = '_'
obj.corp_name_source = obj.OPT_TICKER
result = obj.get_corp_group_name(self.corp)
self.assertEqual(result, 'Corp_TIKK')
def test__replace_spaces(self):
obj = AutogroupsConfig()
obj.replace_spaces = True
obj.replace_spaces_with = '*'
name = ' test name '
result = obj._replace_spaces(name)
self.assertEqual(result, 'test*name')

View File

@@ -0,0 +1,208 @@
from django.test import TestCase
from django.contrib.auth.models import Group, User
from allianceauth.tests.auth_utils import AuthUtils
from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo
from ..models import AutogroupsConfig, ManagedAllianceGroup
from . import patch, disconnect_signals, connect_signals
class SignalsTestCase(TestCase):
def setUp(self):
disconnect_signals()
self.member = AuthUtils.create_member('test user')
state = AuthUtils.get_member_state()
self.char = EveCharacter.objects.create(
character_id='1234',
character_name='test character',
corporation_id='2345',
corporation_name='test corp',
corporation_ticker='tickr',
alliance_id='3456',
alliance_name='alliance name',
)
self.member.profile.main_character = self.char
self.member.profile.save()
self.alliance = EveAllianceInfo.objects.create(
alliance_id='3456',
alliance_name='alliance name',
alliance_ticker='TIKR',
executor_corp_id='2345',
)
self.corp = EveCorporationInfo.objects.create(
corporation_id='2345',
corporation_name='corp name',
corporation_ticker='TIKK',
member_count=10,
alliance=self.alliance,
)
state.member_alliances.add(self.alliance)
state.member_corporations.add(self.corp)
connect_signals()
@patch('.models.AutogroupsConfigManager.update_groups_for_user')
def test_check_groups_on_profile_update_state(self, update_groups_for_user):
# Trigger signal
self.member.profile.state = AuthUtils.get_guest_state()
self.member.profile.save()
self.assertTrue(update_groups_for_user.called)
self.assertEqual(update_groups_for_user.call_count, 1)
args, kwargs = update_groups_for_user.call_args
self.assertEqual(args[0], self.member)
@patch('.models.AutogroupsConfigManager.update_groups_for_user')
def test_check_groups_on_profile_update_main_character(self, update_groups_for_user):
char = EveCharacter.objects.create(
character_id='1266',
character_name='test character2',
corporation_id='2345',
corporation_name='test corp',
corporation_ticker='tickr',
alliance_id='3456',
alliance_name='alliance name',
)
# Trigger signal
self.member.profile.main_character = char
self.member.profile.save()
self.assertTrue(update_groups_for_user.called)
self.assertEqual(update_groups_for_user.call_count, 1)
args, kwargs = update_groups_for_user.call_args
self.assertEqual(args[0], self.member)
member = User.objects.get(pk=self.member.pk)
self.assertEqual(member.profile.state, AuthUtils.get_member_state())
@patch('.models.AutogroupsConfigManager.update_groups_for_user')
def test_check_groups_on_character_update(self, update_groups_for_user):
"""
Test update_groups_for_user is called when main_character properties
are changed.
"""
# Trigger signal
self.member.profile.main_character.corporation_id = '2300'
self.member.profile.main_character.save()
self.assertTrue(update_groups_for_user.called)
self.assertEqual(update_groups_for_user.call_count, 1)
args, kwargs = update_groups_for_user.call_args
self.assertEqual(args[0], self.member)
member = User.objects.get(pk=self.member.pk)
self.assertEqual(member.profile.state, AuthUtils.get_member_state())
@patch('.models.AutogroupsConfig.delete_corp_managed_groups')
@patch('.models.AutogroupsConfig.delete_alliance_managed_groups')
def test_pre_save_config_deletes_alliance_groups(self, delete_alliance_managed_groups, delete_corp_managed_groups):
"""
Test that delete_alliance_managed_groups is called when the alliance_groups
setting is toggled to False
"""
obj = AutogroupsConfig.objects.create(alliance_groups=True)
obj.create_alliance_group(self.alliance)
# Trigger signal
obj.alliance_groups = False
obj.save()
self.assertTrue(delete_alliance_managed_groups.called)
self.assertFalse(delete_corp_managed_groups.called)
self.assertEqual(delete_alliance_managed_groups.call_count, 1)
@patch('.models.AutogroupsConfig.delete_alliance_managed_groups')
@patch('.models.AutogroupsConfig.delete_corp_managed_groups')
def test_pre_save_config_deletes_corp_groups(self, delete_corp_managed_groups, delete_alliance_managed_groups):
"""
Test that delete_corp_managed_groups is called when the corp_groups
setting is toggled to False
"""
obj = AutogroupsConfig.objects.create(corp_groups=True)
obj.create_corp_group(self.corp)
# Trigger signal
obj.corp_groups = False
obj.save()
self.assertTrue(delete_corp_managed_groups.called)
self.assertFalse(delete_alliance_managed_groups.called)
self.assertEqual(delete_corp_managed_groups.call_count, 1)
@patch('.models.AutogroupsConfig.delete_alliance_managed_groups')
@patch('.models.AutogroupsConfig.delete_corp_managed_groups')
def test_pre_save_config_does_nothing(self, delete_corp_managed_groups, delete_alliance_managed_groups):
"""
Test groups arent deleted if we arent setting the enabled params to False
"""
obj = AutogroupsConfig.objects.create(corp_groups=True)
obj.create_corp_group(self.corp)
# Trigger signal
obj.alliance_groups = True
obj.save()
self.assertFalse(delete_corp_managed_groups.called)
self.assertFalse(delete_alliance_managed_groups.called)
@patch('.models.AutogroupsConfig.delete_alliance_managed_groups')
@patch('.models.AutogroupsConfig.delete_corp_managed_groups')
def test_pre_delete_config(self, delete_corp_managed_groups, delete_alliance_managed_groups):
"""
Test groups are deleted if config is deleted
"""
obj = AutogroupsConfig.objects.create()
# Trigger signal
obj.delete()
self.assertTrue(delete_corp_managed_groups.called)
self.assertTrue(delete_alliance_managed_groups.called)
@patch('.models.AutogroupsConfig.update_group_membership_for_state')
def test_autogroups_states_changed_add(self, update_group_membership_for_state):
"""
Test update_group_membership_for_state is called when a state is added to
the AutogroupsConfig
"""
obj = AutogroupsConfig.objects.create(alliance_groups=True)
state = AuthUtils.get_member_state()
# Trigger
obj.states.add(state)
self.assertTrue(update_group_membership_for_state.called)
self.assertEqual(update_group_membership_for_state.call_count, 1)
args, kwargs = update_group_membership_for_state.call_args
self.assertEqual(args[0], state)
@patch('.models.AutogroupsConfig.update_group_membership_for_state')
def test_autogroups_states_changed_remove(self, update_group_membership_for_state):
"""
Test update_group_membership_for_state is called when a state is removed from
the AutogroupsConfig
"""
obj = AutogroupsConfig.objects.create(alliance_groups=True)
state = AuthUtils.get_member_state()
disconnect_signals()
obj.states.add(state)
connect_signals()
# Trigger
obj.states.remove(state)
self.assertTrue(update_group_membership_for_state.called)
self.assertEqual(update_group_membership_for_state.call_count, 1)
args, kwargs = update_group_membership_for_state.call_args
self.assertEqual(args[0], state)