Repository: danidee10/django-notifs (language: python)

Issue:
Create RQ Backend



Discussion / hints:

Fix patch:
diff --git a/notifications/backends/__init__.py b/notifications/backends/__init__.py
index c2e7a5c..6824f64 100644
--- a/notifications/backends/__init__.py
+++ b/notifications/backends/__init__.py
@@ -1,2 +1,3 @@
+from .rq import RQBackend as RQ  # noqa
 from .celery import CeleryBackend as Celery  # noqa
 from .synchronous import SynchronousBackend as Synchronous  # noqa
diff --git a/notifications/backends/rq.py b/notifications/backends/rq.py
new file mode 100644
index 0000000..c2e6c1b
--- /dev/null
+++ b/notifications/backends/rq.py
@@ -0,0 +1,20 @@
+"""RQ Backend"""
+
+import logging
+
+import django_rq
+
+from .base import BaseBackend
+from .utils import _send_notification
+
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger('django_notifs.backends.rq')
+
+
+class RQBackend(BaseBackend):
+
+    def run(self):
+        django_rq.enqueue(
+            _send_notification, self.notification.to_json(), logger
+        )
diff --git a/notifs/settings.py b/notifs/settings.py
index b46a70d..1d9776d 100644
--- a/notifs/settings.py
+++ b/notifs/settings.py
@@ -41,6 +41,7 @@
     'django.contrib.humanize',
 
     'notifications',
+    'django_rq'
 ]
 
 MIDDLEWARE = [
@@ -131,4 +132,12 @@
     'console': 'notifications.channels.ConsoleChannel'
 }
 
-CELERY_TASK_ALWAYS_EAGER = True
+RQ_QUEUES = {
+    'default': {
+        'HOST': 'localhost',
+        'PORT': 6379,
+        'DB': 0,
+        'PASSWORD': '',
+        'DEFAULT_TIMEOUT': 360,
+    }
+}
diff --git a/requirements.txt b/requirements.txt
index ec4b832..8867c08 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,5 @@
 celery==4.1.0
+django-rq==2.4.0
 pika==0.12.0
 pytz==2017.2
 requests==2.25.1
diff --git a/setup.py b/setup.py
index 9f9b703..4d160c9 100644
--- a/setup.py
+++ b/setup.py
@@ -14,9 +14,13 @@
 VERSION = '2.6.5'
 
 REQUIRED = [
-    'celery>=4.1.0', 'django>=2.0', 'pika>=0.12.0', 'requests==2.25.1'
+    'django>=2.0', 'pika>=0.12.0', 'requests==2.25.1',
 ]
 TEST_REQUIRES = ['coverage>=4.3.4']
+EXTRAS_REQUIRE = {
+    'celery': ['celery>=4.1.0'],
+    'rq': ['django-rq==2.4.0']
+}
 EXCLUDE = ['notifs', 'tests', '*.tests', '*.tests.*', 'tests.*']
 
 setup(
@@ -32,5 +36,6 @@
     packages=find_packages(exclude=EXCLUDE),
     install_requires=REQUIRED,
     test_requires=TEST_REQUIRES,
+    extras_require=EXTRAS_REQUIRE,
     license='MIT'
 )


Test patch:
diff --git a/notifications/tests/tests.py b/notifications/tests/tests.py
index 0869420..af5e493 100644
--- a/notifications/tests/tests.py
+++ b/notifications/tests/tests.py
@@ -1,4 +1,6 @@
-"""Tests."""
+"""General Tests."""
+
+import logging
 
 from django.test import TestCase
 from django.contrib.auth import get_user_model
@@ -6,7 +8,7 @@
 from ..utils import notify, read
 from .. import NotificationError
 from ..models import Notification
-from ..backends.celery import send_notification
+from ..backends.utils import _send_notification
 
 
 class GeneralTestCase(TestCase):
@@ -73,6 +75,25 @@ def test_to_json_with_extra_data(self):
             }
         )
 
+    def test_send_notification(self):
+        """
+       This is the default method that's used by all backends
+
+        There's really nothing to assert here but `_send_notification`
+        should run without any Exception.
+        (This might change in the future)
+        """
+        notification = Notification(
+            source=self.user2, source_display_name='User 2',
+            recipient=self.user1, action='Notified',
+            category='Silent notification', obj=1, url='http://example.com',
+            short_description='Short Description', is_read=False,
+            channels=('console',)
+        )
+
+        logger = logging.getLogger(__name__)
+        self.assertIsNone(_send_notification(notification.to_json(), logger))
+
 
 class NotificationTestCase(TestCase):
     """Tests for the notifications"""
@@ -90,27 +111,6 @@ def setUpTestData(cls):
             username='user2@gmail.com', password='password'
         )
 
-    def test_celery_task(self):
-        """
-        THIS IS PROBABLY THE MOST IMPORTANT TEST because:
-
-        It tests the actual Celery task i.e `send_notification`
-        Other tests that call `notify` simply test an emulation
-        of a celery worker.
-
-        There's really nothing to assert here but `send_notification`
-        should run without any Exception
-        """
-        notification = Notification(
-            source=self.user2, source_display_name='User 2',
-            recipient=self.user1, action='Notified',
-            category='Silent notification', obj=1, url='http://example.com',
-            short_description='Short Description', is_read=False,
-            channels=('console',)
-        )
-
-        self.assertIsNone(send_notification(notification.to_json()))
-
     def test_user_cant_read_others_notifications(self):
         """A user should only be able to read THEIR notifications."""
         # Create Notification for User2
@@ -170,11 +170,7 @@ def test_notify_invalid_channel(self):
         self.assertRaises(AttributeError, notify, **notification_kwargs)
 
     def test_send_notification_invalid_channel(self):
-        """
-        An invalid channel should raise an AttributeError.
-
-        This tests the actual Celery task
-        """
+        """An invalid channel should raise an AttributeError."""
         notification = Notification(
             source=self.user2, source_display_name='User 2',
             recipient=self.user1, action='Notified',
@@ -183,8 +179,9 @@ def test_send_notification_invalid_channel(self):
             channels=('invalid channel',)
         )
 
+        logger = logging.getLogger(__name__)
         self.assertRaises(
-            AttributeError, send_notification, notification.to_json()
+            AttributeError, _send_notification, notification.to_json(), logger
         )
 
     def test_queryset_methods(self):