From 75bccf1b0fe90889537f2a6a4ef7e2f397d4374a Mon Sep 17 00:00:00 2001 From: Erik Kalkoken Date: Thu, 12 May 2022 04:02:17 +0000 Subject: [PATCH] Improve notifications --- allianceauth/notifications/__init__.py | 10 +- allianceauth/notifications/core.py | 33 ++++++ .../templates/notifications/list.html | 109 +++++------------- .../templates/notifications/list_partial.html | 29 +++++ .../templates/notifications/view.html | 31 +++-- allianceauth/notifications/tests/test_core.py | 85 ++++++++++++++ allianceauth/notifications/tests/test_init.py | 19 ++- 7 files changed, 203 insertions(+), 113 deletions(-) create mode 100644 allianceauth/notifications/core.py create mode 100644 allianceauth/notifications/templates/notifications/list_partial.html create mode 100644 allianceauth/notifications/tests/test_core.py diff --git a/allianceauth/notifications/__init__.py b/allianceauth/notifications/__init__.py index 6e044162..e22e6ad7 100644 --- a/allianceauth/notifications/__init__.py +++ b/allianceauth/notifications/__init__.py @@ -1,9 +1,3 @@ +from .core import notify # noqa: F401 + default_app_config = 'allianceauth.notifications.apps.NotificationsConfig' - - -def notify( - user: object, title: str, message: str = None, level: str = 'info' -) -> None: - """Sends a new notification to user. Convenience function to manager pendant.""" - from .models import Notification - Notification.objects.notify_user(user, title, message, level) diff --git a/allianceauth/notifications/core.py b/allianceauth/notifications/core.py new file mode 100644 index 00000000..b750ba4d --- /dev/null +++ b/allianceauth/notifications/core.py @@ -0,0 +1,33 @@ +class NotifyApiWrapper: + """Wrapper to create notify API.""" + + def __call__(self, *args, **kwargs): # provide old API for backwards compatibility + return self._add_notification(*args, **kwargs) + + def danger(self, user: object, title: str, message: str = None) -> None: + """Add danger notification for user.""" + self._add_notification(user, title, message, level="danger") + + def info(self, user: object, title: str, message: str = None) -> None: + """Add info notification for user.""" + self._add_notification(user=user, title=title, message=message, level="info") + + def success(self, user: object, title: str, message: str = None) -> None: + """Add success notification for user.""" + self._add_notification(user, title, message, level="success") + + def warning(self, user: object, title: str, message: str = None) -> None: + """Add warning notification for user.""" + self._add_notification(user, title, message, level="warning") + + def _add_notification( + self, user: object, title: str, message: str = None, level: str = "info" + ) -> None: + from .models import Notification + + Notification.objects.notify_user( + user=user, title=title, message=message, level=level + ) + + +notify = NotifyApiWrapper() diff --git a/allianceauth/notifications/templates/notifications/list.html b/allianceauth/notifications/templates/notifications/list.html index f940bac1..1e332ad4 100644 --- a/allianceauth/notifications/templates/notifications/list.html +++ b/allianceauth/notifications/templates/notifications/list.html @@ -5,91 +5,34 @@ {% block page_title %}{% translate "Notifications" %}{% endblock %} {% block content %} -
-

{% translate "Notifications" %}

-
-
-
-
- -
-
-
-
- {% if unread %} - - - - - - - {% for notif in unread %} - - - - - - {% endfor %} -
{% translate "Timestamp" %}{% translate "Title" %}{% translate "Action" %}
{{ notif.timestamp }}{{ notif.title }} - - - - - - -
- {% else %} -
{% translate "No unread notifications." %}
- {% endif %} -
-
-
-
-
- {% if read %} - - - - - - - {% for notif in read %} - - - - - - {% endfor %} -
{% translate "Timestamp" %}{% translate "Title" %}{% translate "Action" %}
{{ notif.timestamp }}{{ notif.title }} - - - - - - -
- {% else %} -
{% translate "No read notifications." %}
- {% endif %} -
-
-
-
-
-
+

{% translate "Notifications" %}

+ +
+ + + +
+
+ +
+ {% include "notifications/list_partial.html" with notifications=unread %} +
+ +
+ {% include "notifications/list_partial.html" with notifications=read %} +
+
+
{% endblock %} diff --git a/allianceauth/notifications/templates/notifications/list_partial.html b/allianceauth/notifications/templates/notifications/list_partial.html new file mode 100644 index 00000000..cdd0e559 --- /dev/null +++ b/allianceauth/notifications/templates/notifications/list_partial.html @@ -0,0 +1,29 @@ +{% load i18n %} + +{% if notifications %} +
+ + + + + + + {% for notif in notifications %} + + + + + + {% endfor %} +
{% translate "Timestamp" %}{% translate "Title" %}{% translate "Action" %}
{{ notif.timestamp }}{{ notif.title }} + + + + + + +
+
+{% else %} +
{% translate "No notifications." %}
+{% endif %} diff --git a/allianceauth/notifications/templates/notifications/view.html b/allianceauth/notifications/templates/notifications/view.html index c09257ef..e6a50167 100644 --- a/allianceauth/notifications/templates/notifications/view.html +++ b/allianceauth/notifications/templates/notifications/view.html @@ -5,25 +5,22 @@ {% block page_title %}{% translate "View Notification" %}{% endblock page_title %} {% block content %} +

+ {% translate "View Notification" %} +
+ + + +
+

-
-

- {% translate "View Notification" %} -
- - - -
-

-
-
-
-
-
{{ notif.timestamp }} {{ notif.title }}
-
{{ notif.message }}
-
-
+
+
+
+
{{ notif.timestamp }} {{ notif.title }}
+
{{ notif.message }}
+ {% endblock %} diff --git a/allianceauth/notifications/tests/test_core.py b/allianceauth/notifications/tests/test_core.py new file mode 100644 index 00000000..6665afe3 --- /dev/null +++ b/allianceauth/notifications/tests/test_core.py @@ -0,0 +1,85 @@ +from django.test import TestCase + +from allianceauth.tests.auth_utils import AuthUtils + +from ..core import NotifyApiWrapper +from ..models import Notification + + +class TestUserNotificationCount(TestCase): + @classmethod + def setUpClass(cls) -> None: + super().setUpClass() + cls.user = AuthUtils.create_user("bruce_wayne") + + def test_should_add_danger_notification(self): + # given + notify = NotifyApiWrapper() + # when + notify.danger(user=self.user, title="title", message="message") + # then + obj = Notification.objects.first() + self.assertEqual(obj.user, self.user) + self.assertEqual(obj.title, "title") + self.assertEqual(obj.message, "message") + self.assertEqual(obj.level, Notification.Level.DANGER) + + def test_should_add_info_notification(self): + # given + notify = NotifyApiWrapper() + # when + notify.info(user=self.user, title="title", message="message") + # then + obj = Notification.objects.first() + self.assertEqual(obj.user, self.user) + self.assertEqual(obj.title, "title") + self.assertEqual(obj.message, "message") + self.assertEqual(obj.level, Notification.Level.INFO) + + def test_should_add_success_notification(self): + # given + notify = NotifyApiWrapper() + # when + notify.success(user=self.user, title="title", message="message") + # then + obj = Notification.objects.first() + self.assertEqual(obj.user, self.user) + self.assertEqual(obj.title, "title") + self.assertEqual(obj.message, "message") + self.assertEqual(obj.level, Notification.Level.SUCCESS) + + def test_should_add_warning_notification(self): + # given + notify = NotifyApiWrapper() + # when + notify.warning(user=self.user, title="title", message="message") + # then + obj = Notification.objects.first() + self.assertEqual(obj.user, self.user) + self.assertEqual(obj.title, "title") + self.assertEqual(obj.message, "message") + self.assertEqual(obj.level, Notification.Level.WARNING) + + def test_should_add_info_notification_via_callable(self): + # given + notify = NotifyApiWrapper() + # when + notify(user=self.user, title="title", message="message") + # then + obj = Notification.objects.first() + self.assertEqual(obj.user, self.user) + self.assertEqual(obj.title, "title") + self.assertEqual(obj.message, "message") + self.assertEqual(obj.level, Notification.Level.INFO) + + def test_should_add_danger_notification_via_callable(self): + # given + notify = NotifyApiWrapper() + # when + notify(user=self.user, title="title", message="message", level="danger") + # then + obj = Notification.objects.first() + self.assertEqual(obj.user, self.user) + self.assertEqual(obj.title, "title") + self.assertEqual(obj.message, "message") + self.assertEqual(obj.level, Notification.Level.DANGER) diff --git a/allianceauth/notifications/tests/test_init.py b/allianceauth/notifications/tests/test_init.py index de3b9f25..e09e1ee7 100644 --- a/allianceauth/notifications/tests/test_init.py +++ b/allianceauth/notifications/tests/test_init.py @@ -4,11 +4,8 @@ from allianceauth.tests.auth_utils import AuthUtils from .. import notify from ..models import Notification -MODULE_PATH = 'allianceauth.notifications' - class TestUserNotificationCount(TestCase): - @classmethod def setUpTestData(cls): cls.user = AuthUtils.create_user('magic_mike') @@ -23,6 +20,18 @@ class TestUserNotificationCount(TestCase): alliance_name='RIDERS' ) - def test_can_notify(self): - notify(self.user, 'dummy') + def test_can_notify_short(self): + # when + notify(self.user, "dummy") + # then self.assertEqual(Notification.objects.filter(user=self.user).count(), 1) + + def test_can_notify_full(self): + # when + notify(user=self.user, title="title", message="message", level="danger") + # then + obj = Notification.objects.first() + self.assertEqual(obj.user, self.user) + self.assertEqual(obj.title, "title") + self.assertEqual(obj.message, "message") + self.assertEqual(obj.level, "danger")