diff --git a/allianceauth/eveonline/templatetags/examples.html b/allianceauth/eveonline/templatetags/examples.html index 69482457..47962f5e 100644 --- a/allianceauth/eveonline/templatetags/examples.html +++ b/allianceauth/eveonline/templatetags/examples.html @@ -14,15 +14,13 @@ Needs to be called with a context containing three objects: {% block page_title %}Evelinks Examples{% endblock page_title %} {% block content %} +
+ {% include "framework/header/page-header.html" with title="Evelinks templatetags examples" %} -
-

Evelinks templatetags examples

-

profile URLs

-

evewho

character from character object

@@ -57,7 +55,6 @@ Needs to be called with a context containing three objects:

image URLs

-

character from ID:

character from character object:

@@ -77,5 +74,4 @@ Needs to be called with a context containing three objects:
- {% endblock content %} diff --git a/allianceauth/fleetactivitytracking/migrations/0007_sentinel_user.py b/allianceauth/fleetactivitytracking/migrations/0007_sentinel_user.py new file mode 100644 index 00000000..0ac26d3e --- /dev/null +++ b/allianceauth/fleetactivitytracking/migrations/0007_sentinel_user.py @@ -0,0 +1,26 @@ +""" +Migration to AA Framework API method +""" + +from django.conf import settings +from django.db import migrations, models + +import allianceauth.framework.api.user + + +class Migration(migrations.Migration): + + dependencies = [ + ("fleetactivitytracking", "0006_auto_20180803_0430"), + ] + + operations = [ + migrations.AlterField( + model_name="fatlink", + name="creator", + field=models.ForeignKey( + on_delete=models.SET(allianceauth.framework.api.user.get_sentinel_user), + to=settings.AUTH_USER_MODEL + ), + ), + ] diff --git a/allianceauth/fleetactivitytracking/models.py b/allianceauth/fleetactivitytracking/models.py index e772cdc4..3cbd3d63 100644 --- a/allianceauth/fleetactivitytracking/models.py +++ b/allianceauth/fleetactivitytracking/models.py @@ -3,10 +3,7 @@ from django.db import models from django.utils import timezone from allianceauth.eveonline.models import EveCharacter - - -def get_sentinel_user(): - return User.objects.get_or_create(username='deleted')[0] +from allianceauth.framework.api.user import get_sentinel_user class Fatlink(models.Model): diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html index 8183da5d..3feec878 100644 --- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html +++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html @@ -12,9 +12,8 @@ {% block content %}
-

- {% translate "Character not found!" %} -

+ {% translate "Character not found!" as page_header %} + {% include "framework/header/page-header.html" with title=page_header %}
diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkcreate.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkcreate.html index e23df8de..cd0106f6 100644 --- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkcreate.html +++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkcreate.html @@ -13,9 +13,8 @@ {% block content %}
-

- {% translate "Create Fatlink" %} -

+ {% translate "Create Fatlink" as page_header %} + {% include "framework/header/page-header.html" with title=page_header %}
{% if badrequest %} diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html index d3476c04..24943440 100644 --- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html +++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html @@ -14,16 +14,16 @@

{% translate "Edit fatlink" %} "{{ fatlink }}" - -
-
- -
-

+
+
+ +
+
+
{% translate "Registered characters" %}
diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalmonthlystatisticsview.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalmonthlystatisticsview.html index 991a051f..24256381 100644 --- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalmonthlystatisticsview.html +++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalmonthlystatisticsview.html @@ -14,20 +14,20 @@

{% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %} - - {% if char_id %} - - {% endif %}

-
+ {% if char_id %} + + {% endif %} + +
{% blocktranslate count links=n_fats trimmed %} diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalstatisticsview.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalstatisticsview.html index 30b19512..fbff4660 100644 --- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalstatisticsview.html +++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalstatisticsview.html @@ -14,16 +14,16 @@

{% blocktranslate %}Participation data statistics for {{ year }}{% endblocktranslate %} - -
- {% translate "Previous year" %} - - {% if next_year %} - {% translate "Next year" %} - {% endif %} -

+
+ {% translate "Previous year" %} + + {% if next_year %} + {% translate "Next year" %} + {% endif %} +
+
diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html index 3132d889..e05b7f0a 100644 --- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html +++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html @@ -11,19 +11,19 @@ {% endblock header_nav_brand %} {% block content %} -
+

{% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %} - -
- {% translate "Previous month" %} - - {% if next_month %} - {% translate "Next month" %} - {% endif %} -

+
+ {% translate "Previous month" %} + + {% if next_month %} + {% translate "Next month" %} + {% endif %} +
+ {% if fatStats %}
diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html index 924011c9..724fe95c 100644 --- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html +++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html @@ -14,16 +14,16 @@

{% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %} - -
- {% translate "Previous month" %} - - {% if next_month %} - {% translate "Next month" %} - {% endif %} -

+
+ {% translate "Previous month" %} + + {% if next_month %} + {% translate "Next month" %} + {% endif %} +
+ {% if fatStats %}
diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html index 53131194..72470ab0 100644 --- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html +++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html @@ -11,10 +11,9 @@ {% endblock header_nav_brand %} {% block content %} -
-

- {% translate "Participation data" %} -

+
+ {% translate "Participation data" as page_header %} + {% include "framework/header/page-header.html" with title=page_header %}
diff --git a/allianceauth/framework/__init__.py b/allianceauth/framework/__init__.py new file mode 100644 index 00000000..95461f25 --- /dev/null +++ b/allianceauth/framework/__init__.py @@ -0,0 +1,3 @@ +""" +Alliance Auth Framework +""" diff --git a/allianceauth/framework/api/user.py b/allianceauth/framework/api/user.py new file mode 100644 index 00000000..8840b928 --- /dev/null +++ b/allianceauth/framework/api/user.py @@ -0,0 +1,64 @@ +""" +Alliance Auth User API +""" + +from typing import Optional + +from django.contrib.auth.models import User + +from allianceauth.eveonline.models import EveCharacter + + +def get_sentinel_user() -> User: + """ + Get the sentinel user or create one + + :return: + """ + + return User.objects.get_or_create(username="deleted")[0] + +def get_main_character_from_user(user: User) -> Optional[EveCharacter]: + """ + Get the main character from a user + + :param user: + :type user: + :return: + :rtype: + """ + + if user is None: + return None + + try: + main_character = user.profile.main_character + except AttributeError: + return None + + return main_character + + +def get_main_character_name_from_user(user: User) -> str: + """ + Get the main character name from a user + + :param user: + :type user: + :return: + :rtype: + """ + + if user is None: + sentinel_user = get_sentinel_user() + + return sentinel_user.username + + main_character = get_main_character_from_user(user=user) + + try: + username = main_character.character_name + except AttributeError: + return str(user) + + return username diff --git a/allianceauth/framework/apps.py b/allianceauth/framework/apps.py new file mode 100644 index 00000000..77264525 --- /dev/null +++ b/allianceauth/framework/apps.py @@ -0,0 +1,14 @@ +""" +Framework App Config +""" + +from django.apps import AppConfig + + +class FrameworkConfig(AppConfig): + """ + Framework App Config + """ + + name = "allianceauth.framework" + label = "framework" diff --git a/allianceauth/static/allianceauth/css/auth-framework.css b/allianceauth/framework/static/allianceauth/framework/css/auth-framework.css similarity index 100% rename from allianceauth/static/allianceauth/css/auth-framework.css rename to allianceauth/framework/static/allianceauth/framework/css/auth-framework.css diff --git a/allianceauth/framework/templates/framework/header/page-header.html b/allianceauth/framework/templates/framework/header/page-header.html new file mode 100644 index 00000000..ed067db3 --- /dev/null +++ b/allianceauth/framework/templates/framework/header/page-header.html @@ -0,0 +1,13 @@ +{#Usage:#} +{# {% include "framework/header/page-header.html" with title="Foobar" subtitle="Barfoo" %}#} + +{% if title %} +

+ {{ title }} + + {% if subtitle %} +
+ {{ subtitle }} + {% endif %} +

+{% endif %} diff --git a/allianceauth/framework/tests/__init__.py b/allianceauth/framework/tests/__init__.py new file mode 100644 index 00000000..2666d875 --- /dev/null +++ b/allianceauth/framework/tests/__init__.py @@ -0,0 +1,3 @@ +""" +Initializing our tests +""" diff --git a/allianceauth/framework/tests/test_api_user.py b/allianceauth/framework/tests/test_api_user.py new file mode 100644 index 00000000..1b43b75c --- /dev/null +++ b/allianceauth/framework/tests/test_api_user.py @@ -0,0 +1,179 @@ +""" +Test sentinel user +""" + +import re + +# Django +from django.contrib.auth.models import User +from django.test import TestCase + +# Alliance Auth +from allianceauth.framework.api.user import ( + get_sentinel_user, + get_main_character_from_user, + get_main_character_name_from_user +) +from allianceauth.tests.auth_utils import AuthUtils + + +class TestSentinelUser(TestCase): + """ + Tests for the sentinel user + """ + + def test_should_create_user_when_it_does_not_exist(self) -> None: + """ + Test should create a sentinel user when it doesn't exist + + :return: + :rtype: + """ + + # when + user = get_sentinel_user() + + # then + self.assertEqual(first=user.username, second="deleted") + + def test_should_return_user_when_it_does(self) -> None: + """ + Test should return sentinel user when it exists + + :return: + :rtype: + """ + + # given + User.objects.create_user(username="deleted") + + # when + user = get_sentinel_user() + + # then + self.assertEqual(first=user.username, second="deleted") + + +class TestGetMainForUser(TestCase): + """ + Tests for get_main_character_from_user + """ + + @classmethod + def setUpClass(cls) -> None: + """ + Set up groups and users + """ + + super().setUpClass() + + cls.character_name = "William T. Riker" + cls.character_name_2 = "Christopher Pike" + + cls.username = re.sub(pattern=r"[^\w\d@\.\+-]", repl="_", string=cls.character_name) + cls.username_2 = re.sub( + pattern=r"[^\w\d@\.\+-]", repl="_", string=cls.character_name_2 + ) + + cls.user = AuthUtils.create_user(username=cls.username) + cls.user_without_main = AuthUtils.create_user( + username=cls.username_2, disconnect_signals=True + ) + + cls.character = AuthUtils.add_main_character_2( + user=cls.user, name=cls.character_name, character_id=1001 + ) + + + def test_get_main_character_from_user_should_return_character_name(self): + """ + Test should return the main character name for a regular user + + :return: + :rtype: + """ + + character = get_main_character_from_user(user=self.user) + + self.assertEqual(first=character, second=self.character) + + + def test_get_main_character_from_user_should_return_none_for_no_main_character(self): + """ + Test should return None for User without a main character + + :return: + :rtype: + """ + + character = get_main_character_from_user(user=self.user_without_main) + + self.assertIsNone(obj=character) + + + def test_get_main_character_from_user_should_none(self): + """ + Test should return None when user is None + + :return: + :rtype: + """ + + user = None + + character = get_main_character_from_user(user=user) + + self.assertIsNone(obj=character) + + + def test_get_main_character_name_from_user_should_return_character_name(self): + """ + Test should return the main character name for a regular user + + :return: + :rtype: + """ + + character_name = get_main_character_name_from_user(user=self.user) + + self.assertEqual(first=character_name, second=self.character_name) + + def test_get_main_character_name_from_user_should_return_user_name(self): + """ + Test should return just the username for a user without a main character + + :return: + :rtype: + """ + + character_name = get_main_character_name_from_user(user=self.user_without_main) + + self.assertEqual(first=character_name, second=self.username_2) + + def test_get_main_character_name_from_user_should_return_sentinel_user(self): + """ + Test should return "deleted" as username (Sentinel User) + + :return: + :rtype: + """ + + user = get_sentinel_user() + + character_name = get_main_character_name_from_user(user=user) + + self.assertEqual(first=character_name, second="deleted") + + def test_get_main_character_name_from_user_should_return_sentinel_user_for_none(self): + """ + Test should return "deleted" (Sentinel User) if user is None + + :return: + :rtype: + """ + + user = None + + character_name = get_main_character_name_from_user(user=user) + + self.assertEqual(first=character_name, second="deleted") diff --git a/allianceauth/hrapplications/templates/hrapplications/corpchoice.html b/allianceauth/hrapplications/templates/hrapplications/corpchoice.html index e36a18ba..07166a4e 100644 --- a/allianceauth/hrapplications/templates/hrapplications/corpchoice.html +++ b/allianceauth/hrapplications/templates/hrapplications/corpchoice.html @@ -12,9 +12,8 @@ {% block content %}
-

- {% translate "Choose a Corp" %} -

+ {% translate "Choose a Corp" as page_header %} + {% include "framework/header/page-header.html" with title=page_header %} {% if choices %}
diff --git a/allianceauth/hrapplications/templates/hrapplications/management.html b/allianceauth/hrapplications/templates/hrapplications/management.html index b67127ea..370b6300 100644 --- a/allianceauth/hrapplications/templates/hrapplications/management.html +++ b/allianceauth/hrapplications/templates/hrapplications/management.html @@ -13,17 +13,18 @@ {% block content %}
-

{% translate "Personal Applications" %} -
- {% if create %} - - - - {% else %} - - {% endif %} -
-

+ {% translate "Personal Applications" as page_header %} + {% include "framework/header/page-header.html" with title=page_header %} + +
+ {% if create %} + + + + {% else %} + + {% endif %} +
{% if personal_apps %}
@@ -68,16 +69,17 @@ {% endif %} {% if perms.auth.human_resources %} -

{% translate "Application Management" %} -
- - -
-

+ {% translate "Application Management" as page_header %} + {% include "framework/header/page-header.html" with title=page_header %} -
+
+ + +
+ +