Ejemplo n.º 1
0
    def test_list_notification_filtering(self):
        url = self._get_path('notifications_list')
        notify.send(sender=self.admin, type='default', target=self.admin)
        notify.send(sender=self.admin, type='default', target=self.admin)
        # Mark one notification as read
        n_read = Notification.objects.first()
        n_read.mark_as_read()

        with self.subTest('Test listing notifications without filters'):
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(len(response.data['results']), 2)

        with self.subTest('Test listing read notifications'):
            read_url = f'{url}?unread=false'
            response = self.client.get(read_url)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(len(response.data['results']), 1)
            n = response.data['results'].pop()
            self.assertEqual(n['id'], str(n_read.id))
            self.assertFalse(n['unread'])

        with self.subTest('Test listing unread notifications'):
            unread_url = f'{url}?unread=true'
            response = self.client.get(unread_url)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(len(response.data['results']), 1)
            n = response.data['results'].pop()
            self.assertNotEqual(n['id'], str(n_read.id))
            self.assertTrue(n['unread'])
Ejemplo n.º 2
0
    def test_malformed_notifications(self):
        test_type = {
            'verbose_name': 'Test Notification Type',
            'level': 'warning',
            'verb': 'testing',
            'message': '{notification.actor.random}',
            'email_subject': '[{site.name}] {notification.actor.random}',
        }
        register_notification_type('test_type', test_type)

        with self.subTest('Test list notifications'):
            notify.send(sender=self.admin, type='default')
            notify.send(sender=self.admin, type='test_type')
            url = self._get_path('notifications_list')
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.data['count'], 1)
            self.assertEqual(
                response.data['next'], None,
            )
            self.assertEqual(response.data['previous'], None)
            self.assertEqual(len(response.data['results']), 1)

        with self.subTest('Test retrieve notification'):
            [(_, [n])] = notify.send(
                sender=self.admin, type='test_type', target=self._get_org_user()
            )
            url = self._get_path('notification_detail', n.pk)
            response = self.client.get(url)
            self.assertEqual(response.status_code, 404)
            self.assertDictEqual(response.data, {'detail': NOT_FOUND_ERROR})

        unregister_notification_type('test_type')
Ejemplo n.º 3
0
    def test_notification_redirect_api(self):
        def _unread_notification(notification):
            notification.unread = True
            notification.save()

        notify.send(sender=self.admin, type='default', target=self.admin)
        notification = Notification.objects.first()

        with self.subTest('Test non-existent notification'):
            url = self._get_path('notification_read_redirect', uuid.uuid4())
            response = self.client.get(url)
            self.assertEqual(response.status_code, 404)
            self.assertDictEqual(response.data, {'detail': NOT_FOUND_ERROR})

        with self.subTest('Test existent notification'):
            url = self._get_path('notification_read_redirect', notification.pk)
            response = self.client.get(url)
            self.assertEqual(response.status_code, 302)
            self.assertEqual(response.url, notification.target_url)
            notification.refresh_from_db()
            self.assertEqual(notification.unread, False)

        _unread_notification(notification)

        with self.subTest('Test user not logged in'):
            self.client.logout()
            url = self._get_path('notification_read_redirect', notification.pk)
            response = self.client.get(url)
            self.assertEqual(response.status_code, 302)
            self.assertEqual(
                response.url,
                '{view}?next={url}'.format(view=reverse('admin:login'), url=url),
            )
Ejemplo n.º 4
0
 def test_handler_optional_tag(self):
     operator = self._create_operator()
     notify.send(action_object=operator, **self.notification_options)
     n = notification_queryset.first()
     self.assertEqual(n.action_object_content_type,
                      ContentType.objects.get_for_model(operator))
     self.assertEqual(n.action_object_object_id, str(operator.id))
 def test_notification_for_disabled_object(self, mocked_task):
     IgnoreObjectNotification.objects.create(
         object=self.obj,
         user=self.admin,
         valid_till=(timezone.now() + timezone.timedelta(days=1)),
     )
     notify.send(sender=self.admin, type='default', target=self.obj)
     self.assertEqual(Notification.objects.count(), 0)
Ejemplo n.º 6
0
 def _notify_users(self, notification_type, alert_settings):
     """ creates notifications for users """
     opts = dict(sender=self,
                 type=notification_type,
                 action_object=alert_settings)
     if self.content_object is not None:
         opts['target'] = self.content_object
     notify.send(**opts)
Ejemplo n.º 7
0
def config_status_error_notification(sender, instance, **kwargs):
    """
    Creates notification when status of a configuration changes to "error".
    """
    if instance.status == 'error':
        notify.send(sender=instance,
                    type='config_error',
                    target=instance.device)
Ejemplo n.º 8
0
 def test_mark_as_read_action(self):
     notify.send(**self.notification_options)
     qs = Notification.objects.all()
     self.model_admin.mark_as_read(request, qs)
     self.assertEqual(qs.count(), 1)
     m = list(request.get_messages())
     self.assertEqual(len(m), 1)
     self.assertEqual(str(m[0]), '1 notification was marked as read.')
Ejemplo n.º 9
0
def device_registered_notification(sender, instance, is_new, **kwargs):
    """
    Creates notification when a new device is registered automatically
    through controller.
    """
    condition = _('A new') if is_new else _('The existing')
    notify.send(
        sender=instance, type='device_registered', target=instance, condition=condition
    )
Ejemplo n.º 10
0
 def test_notification_view_webpage(self):
     notify.send(**self.notification_options)
     n = notification_queryset.first()
     url = reverse(f'admin:{self.app_label}_notification_change',
                   args=(n.id, ))
     response = self.client.get(url)
     self.assertContains(response, 'id="actor-object-url"')
     self.assertContains(response,
                         '<div class="readonly">Test Notification</div>')
Ejemplo n.º 11
0
    def test_list_view_notification_cache(self):
        number_of_notifications = 5
        url = self._get_path('notifications_list', page_size=number_of_notifications)
        operator = self._get_operator()
        for _ in range(number_of_notifications):
            notify.send(sender=self.admin, type='default', target=operator)

        with self.assertNumQueries(3):
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.data['count'], number_of_notifications)
Ejemplo n.º 12
0
    def test_notifications_read_all_api(self):
        number_of_notifications = 2
        for _ in range(number_of_notifications):
            notify.send(sender=self.admin, type='default', target=self.admin)

        url = self._get_path('notifications_read_all')
        response = self.client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertIsNone(response.data)
        # Verify notifications are marked read in database
        for n in Notification.objects.all():
            self.assertFalse(n.unread)
Ejemplo n.º 13
0
    def test_deleted_notification_type(self, *args):
        notify.send(sender=self.admin, type='default', target=self.admin)
        with patch('openwisp_notifications.types.NOTIFICATION_TYPES', {}):
            url = self._get_path('notifications_list')
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(len(response.data['results']), 0)
            self.assertEqual(Notification.objects.count(), 1)

            notification = Notification.objects.first()
            url = self._get_path('notification_detail', notification.pk)
            response = self.client.get(url)
            self.assertEqual(response.status_code, 404)
Ejemplo n.º 14
0
 def is_working_changed_receiver(cls, instance, is_working, old_is_working,
                                 **kwargs):
     # if old_is_working is None, it's a new device connection which wasn't
     # used yet, so nothing is really changing and we won't notify the user
     if old_is_working is None:
         return
     device = instance.device
     notification_opts = dict(sender=instance, target=device)
     if not is_working:
         notification_opts['type'] = 'connection_is_not_working'
     else:
         notification_opts['type'] = 'connection_is_working'
     notify.send(**notification_opts)
Ejemplo n.º 15
0
    def test_non_zero_notifications(self):
        with self.subTest("Test UI for less than 100 notifications"):
            no_of_notifications = 10
            for _ in range(no_of_notifications):
                notify.send(**self.notification_options)
            r = self.client.get(self._url)
            self.assertContains(r, self._expected_output('10'))

        with self.subTest("Test UI for 99+ notifications"):
            no_of_notifications = 100
            for _ in range(no_of_notifications):
                notify.send(**self.notification_options)
            r = self.client.get(self._url)
            self.assertContains(r, self._expected_output('99+'))
Ejemplo n.º 16
0
    def test_notification_recipients(self):
        # Tests user can only interact with notifications assigned to them
        self.client.logout()
        joe = self._create_user(username='******', email='*****@*****.**')
        karen = self._create_user(username='******', email='*****@*****.**')
        notify.send(sender=self.admin, type='default', recipient=karen)
        self.client.force_login(joe)

        with self.subTest('Test listing all notifications'):
            url = reverse(f'{self.app_label}:notifications_list')
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.data['count'], 0)
            self.assertEqual(len(response.data['results']), 0)
            self.assertEqual(response.data['next'], None)

        with self.subTest('Test marking all notifications as read'):
            url = reverse(f'{self.app_label}:notifications_read_all')
            response = self.client.post(url)
            self.assertEqual(response.status_code, 200)
            self.assertIsNone(response.data)
            # Check Karen's notification is still unread
            n = Notification.objects.first()
            self.assertTrue(n.unread)

        with self.subTest('Test retrieving notification'):
            url = reverse(f'{self.app_label}:notification_detail',
                          kwargs={'pk': n.id})
            response = self.client.get(url)
            self.assertEqual(response.status_code, 404)
            self.assertDictEqual(response.data, {'detail': NOT_FOUND_ERROR})

        with self.subTest('Test marking a notification as read'):
            url = reverse(f'{self.app_label}:notification_detail',
                          kwargs={'pk': n.id})
            response = self.client.patch(url)
            self.assertEqual(response.status_code, 404)
            self.assertDictEqual(response.data, {'detail': NOT_FOUND_ERROR})
            # Check Karen's notification is still unread
            n = Notification.objects.first()
            self.assertTrue(n.unread)

        with self.subTest('Test deleting notification'):
            url = reverse(f'{self.app_label}:notification_detail',
                          kwargs={'pk': n.id})
            response = self.client.delete(url)
            self.assertEqual(response.status_code, 404)
            self.assertDictEqual(response.data, {'detail': NOT_FOUND_ERROR})
            # Check Karen's notification is not deleted
            self.assertEqual(Notification.objects.count(), 1)
    def _generic_test_obj_link(self, field):
        notify.send(**self.notification_options)
        n = notification_queryset.first()
        get_actual_obj_link = getattr(self.model_admin, f'{field}_object_link')
        object_id = getattr(n, f'{field}_object_id', None)

        exp_obj_link = '<a href="{0}" id="{1}-object-url">{2}</a>'.format(
            reverse('admin:openwisp_users_user_change', args=(object_id, )),
            field,
            object_id,
        )
        self.assertEqual(get_actual_obj_link(n), exp_obj_link)

        setattr(n, f'{field}_content_type', ContentType())
        self.assertEqual(get_actual_obj_link(n), object_id)

        setattr(n, f'{field}_content_type', None)
        self.assertEqual(get_actual_obj_link(n), '-')
Ejemplo n.º 18
0
    def test_notification_delete_api(self):
        notify.send(sender=self.admin, type='default', target=self.admin)
        n = Notification.objects.first()

        with self.subTest('Test for non-existing notification'):
            url = self._get_path('notification_detail', uuid.uuid4())
            response = self.client.delete(url)
            self.assertEqual(response.status_code, 404)
            self.assertDictEqual(
                response.data, {'detail': NOT_FOUND_ERROR},
            )

        with self.subTest('Test for valid notification'):
            url = self._get_path('notification_detail', n.pk)
            response = self.client.delete(url)
            self.assertEqual(response.status_code, 204)
            self.assertIsNone(response.data)
            self.assertFalse(Notification.objects.all())
Ejemplo n.º 19
0
    def test_obsolete_notifications_busy_worker(self, mocked_task):
        """
        This test simulates deletion of related object when all celery
        workers are busy and related objects are not cached.
        """
        operator = self._get_operator()
        test_type = {
            'verbose_name': 'Test Notification Type',
            'level': 'warning',
            'verb': 'testing',
            'message': 'Test notification for {notification.target.pk}',
            'email_subject': '[{site.name}] {notification.target.pk}',
        }
        register_notification_type('test_type', test_type)

        notify.send(sender=self.admin, type='test_type', target=operator)
        notification = Notification.objects.first()
        self.assertEqual(
            notification.message, f'<p>Test notification for {operator.pk}</p>'
        )
        operator.delete()
        notification.refresh_from_db()

        # Delete target object from cache
        cache_key = Notification._cache_key(
            notification.target_content_type_id, notification.target_object_id
        )
        cache.delete(cache_key)
        self.assertIsNone(cache.get(cache_key))

        with self.subTest('Test list notifications'):
            url = self._get_path('notifications_list')
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.data['count'], 1)
            self.assertFalse(response.data['results'])

        with self.subTest('Test retrieve notification'):
            url = self._get_path('notification_read_redirect', notification.pk)
            response = self.client.get(url)
            self.assertEqual(response.status_code, 404)
            self.assertDictEqual(response.data, {'detail': NOT_FOUND_ERROR})

        unregister_notification_type('test_type')
Ejemplo n.º 20
0
    def test_bearer_authentication(self):
        self.client.logout()
        notify.send(sender=self.admin, type='default', target=self.admin)
        n = Notification.objects.first()
        token = self._obtain_auth_token(username='******', password='******')

        with self.subTest('Test listing all notifications'):
            url = reverse(f'{self.app_label}:notifications_list')
            response = self.client.get(url,
                                       HTTP_AUTHORIZATION=f'Bearer {token}')
            self.assertEqual(response.status_code, 200)
            self.assertEqual(len(response.data['results']), 1)

        with self.subTest('Test marking all notifications as read'):
            url = reverse(f'{self.app_label}:notifications_read_all')
            response = self.client.post(url,
                                        HTTP_AUTHORIZATION=f'Bearer {token}')
            self.assertEqual(response.status_code, 200)
            self.assertIsNone(response.data)

        with self.subTest('Test retrieving notification'):
            url = reverse(f'{self.app_label}:notification_detail',
                          kwargs={'pk': n.id})
            response = self.client.get(url,
                                       HTTP_AUTHORIZATION=f'Bearer {token}')
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.data['id'], str(n.id))

        with self.subTest('Test marking a notification as read'):
            url = reverse(f'{self.app_label}:notification_detail',
                          kwargs={'pk': n.id})
            response = self.client.patch(url,
                                         HTTP_AUTHORIZATION=f'Bearer {token}')
            self.assertEqual(response.status_code, 200)
            self.assertIsNone(response.data)

        with self.subTest('Test deleting notification'):
            url = reverse(f'{self.app_label}:notification_detail',
                          kwargs={'pk': n.id})
            response = self.client.delete(url,
                                          HTTP_AUTHORIZATION=f'Bearer {token}')
            self.assertEqual(response.status_code, 204)
            self.assertIsNone(response.data)
Ejemplo n.º 21
0
    def test_read_single_notification_api(self):
        notify.send(sender=self.admin, type='default', target=self.admin)
        n = Notification.objects.first()

        with self.subTest('Test for non-existing notification'):
            url = self._get_path('notification_detail', uuid.uuid4())
            response = self.client.patch(url)
            self.assertEqual(response.status_code, 404)
            self.assertDictEqual(
                response.data, {'detail': NOT_FOUND_ERROR},
            )

        with self.subTest('Test for existing notification'):
            self.assertTrue(n.unread)
            url = self._get_path('notification_detail', n.pk)
            response = self.client.patch(url)
            self.assertEqual(response.status_code, 200)
            self.assertIsNone(response.data)
            n = Notification.objects.first()
            self.assertEqual(n.unread, False)
    def test_callable_related_object(self):
        self.notification_options.update({'target': self.admin})
        notify.send(**self.notification_options)
        n = notification_queryset.first()

        exp_related_obj_link = '<a href="{0}" id="related-object-url">{1}: {2}</a>'.format(
            reverse('admin:openwisp_users_user_change',
                    args=(self.admin.id, )),
            ContentType.objects.get_for_model(self.admin).model,
            self.admin,
        )
        self.assertEqual(self.model_admin.related_object(n),
                         exp_related_obj_link)

        n.target_content_type = ContentType()
        self.assertEqual(self.model_admin.related_object(n),
                         n.target_object_id)

        n.target_content_type = None
        self.assertEqual(self.model_admin.related_object(n), '-')
Ejemplo n.º 23
0
    def test_notification_delete_api(self):
        notify.send(sender=self.admin, type='default', target=self.admin)
        n = Notification.objects.first()

        with self.subTest('Test for non-existing notification'):
            url = reverse(f'{self.app_label}:notification_detail',
                          kwargs={'pk': uuid.uuid4()})
            response = self.client.delete(url)
            self.assertEqual(response.status_code, 404)
            self.assertDictEqual(
                response.data,
                {'detail': NOT_FOUND_ERROR},
            )

        with self.subTest('Test for valid notificaton'):
            url = reverse(f'{self.app_label}:notification_detail',
                          kwargs={'pk': n.id})
            response = self.client.delete(url)
            self.assertEqual(response.status_code, 204)
            self.assertIsNone(response.data)
            self.assertFalse(Notification.objects.all())
Ejemplo n.º 24
0
    def test_retreive_notification_api(self):
        notify.send(sender=self.admin, type='default', target=self.admin)
        n = Notification.objects.first()

        with self.subTest('Test for non-existing notification'):
            url = self._get_path('notification_detail', uuid.uuid4())
            response = self.client.get(url)
            self.assertEqual(response.status_code, 404)
            self.assertDictEqual(
                response.data, {'detail': NOT_FOUND_ERROR},
            )

        with self.subTest('Test retrieving details for existing notification'):
            url = self._get_path('notification_detail', n.pk)
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)
            data = response.data
            self.assertEqual(data['id'], str(n.id))
            self.assertEqual(data['message'], n.message)
            self.assertEqual(data['email_subject'], n.email_subject)
            self.assertEqual(data['unread'], n.unread)
Ejemplo n.º 25
0
    def test_mark_as_read_action(self):
        with self.subTest('Test marking a single notification read'):
            notify.send(**self.notification_options)
            qs = notification_queryset
            self.model_admin.mark_as_read(request, qs)
            self.assertEqual(qs.count(), 1)
            m = list(request.get_messages())
            self.assertEqual(len(m), 1)
            self.assertEqual(str(m[0]), '1 notification was marked as read.')

        with self.subTest('Test marking mutiple notifications read'):
            no_of_notifications = 10
            for _ in range(no_of_notifications):
                notify.send(**self.notification_options)
            qs = Notification.objects.all()
            self.model_admin.mark_as_read(request, qs)
            self.assertEqual(qs.count(), no_of_notifications + 1)
            m = list(request.get_messages())
            self.assertEqual(len(m), 2)
            self.assertEqual(
                str(m[1]),
                f'{no_of_notifications} notifications were marked as read.')
Ejemplo n.º 26
0
 def test_create_with_extra_data(self):
     register_notification_type(
         'error_type',
         {
             'verbose_name': 'Error',
             'level': 'error',
             'verb': 'error',
             'message': 'Error: {error}',
             'email_subject': 'Error subject: {error}',
         },
     )
     error = '500 Internal Server Error'
     notify.send(
         type='error_type',
         url='https://localhost:8000/admin',
         recipient=self.admin,
         sender=self.admin,
         error=error,
     )
     self.assertEqual(notification_queryset.count(), 1)
     n = notification_queryset.first()
     self.assertIn(f'Error: {error}', n.message)
     self.assertEqual(n.email_subject, f'Error subject: {error}')
Ejemplo n.º 27
0
 def is_working_changed_receiver(
     cls,
     instance,
     is_working,
     old_is_working,
     failure_reason,
     old_failure_reason,
     **kwargs,
 ):
     # if old_is_working is None, it's a new device connection which wasn't
     # used yet, so nothing is really changing and we won't notify the user
     if old_is_working is None:
         return
     # don't send notification if error occurred due to connectivity issues
     for ignore_reason in cls._ignore_connection_notification_reasons:
         if ignore_reason in failure_reason or ignore_reason in old_failure_reason:
             return
     device = instance.device
     notification_opts = dict(sender=instance, target=device)
     if not is_working:
         notification_opts['type'] = 'connection_is_not_working'
     else:
         notification_opts['type'] = 'connection_is_working'
     notify.send(**notification_opts)
Ejemplo n.º 28
0
 def test_non_zero_notifications(self):
     no_of_notifications = 10
     for _ in range(no_of_notifications):
         notify.send(**self.notification_options)
     r = self.client.get(self._url)
     self.assertContains(r, self._expected_output(no_of_notifications))
Ejemplo n.º 29
0
 def _create_notification(self):
     return notify.send(**self.notification_options)
Ejemplo n.º 30
0
 def test_cached_invalidation(self):
     cache_key = self.test_cached_value()
     notify.send(**self.notification_options)
     self.assertIsNone(cache.get(cache_key))
     self.client.get(self._url)
     self.assertEqual(cache.get(cache_key), 1)