def setUp(self): self.admin = self._login_admin() self.notification_options = dict( sender=self.admin, recipient=self.admin, description='Test Notification', verb='Test Notification', email_subject='Test Email subject', url='localhost:8000/admin', ) self.site = AdminSite() self.ns_inline = NotificationSettingInline(NotificationSetting, self.site)
class TestAdmin(TestOrganizationMixin, TestMultitenantAdminMixin, TestCase): """ Tests notifications in admin """ app_label = 'openwisp_notifications' def _login_admin(self): u = User.objects.create_superuser('admin', 'admin', '*****@*****.**') self.client.force_login(u) return u def setUp(self): self.admin = self._login_admin() self.notification_options = dict( sender=self.admin, recipient=self.admin, description='Test Notification', verb='Test Notification', email_subject='Test Email subject', url='localhost:8000/admin', ) self.site = AdminSite() self.ns_inline = NotificationSettingInline(NotificationSetting, self.site) @property def _url(self): return reverse('admin:index') def _expected_output(self, count=None): if count: return '<span id="ow-notification-count">{0}</span>'.format(count) return f'id="{self.app_label}">' def test_zero_notifications(self): r = self.client.get(self._url) self.assertContains(r, self._expected_output()) def test_non_zero_notifications(self): patched_function = 'openwisp_notifications.templatetags.notification_tags.base_notification_unread' with self.subTest("Test UI for less than 100 notifications"): with patch(patched_function, return_value=10): r = self.client.get(self._url) self.assertContains(r, self._expected_output('10')) Notification.invalidate_unread_cache(self.admin) with self.subTest("Test UI for 99+ notifications"): with patch(patched_function, return_value=100): r = self.client.get(self._url) self.assertContains(r, self._expected_output('99+')) def test_cached_value(self): self.client.get(self._url) cache_key = Notification.count_cache_key(self.admin.pk) self.assertEqual(cache.get(cache_key), 0) return cache_key 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) def test_default_notification_setting(self): res = self.client.get(self._url) self.assertContains( res, '/static/openwisp-notifications/audio/notification_bell.mp3') self.assertContains(res, 'window.location') @patch.object( app_settings, 'OPENWISP_NOTIFICATIONS_SOUND', '/static/notification.mp3', ) def test_notification_sound_setting(self): res = self.client.get(self._url) self.assertContains(res, '/static/notification.mp3') self.assertNotContains( res, '/static/openwisp-notifications/audio/notification_bell.mp3') @patch.object( app_settings, 'OPENWISP_NOTIFICATIONS_HOST', 'https://example.com', ) def test_notification_host_setting(self): res = self.client.get(self._url) self.assertContains(res, 'https://example.com') self.assertNotContains(res, 'window.location') def test_jquery_import(self): response = self.client.get(self._url) self.assertInHTML( '<script src="/static/admin/js/jquery.init.js">', str(response.content), 1, ) self.assertInHTML( '<script src="/static/admin/js/vendor/jquery/jquery.min.js">', str(response.content), 1, ) response = self.client.get(reverse('admin:sites_site_changelist')) self.assertIn( '/static/admin/js/jquery.init.js', str(response.content), 1, ) self.assertIn( '/static/admin/js/vendor/jquery/jquery.min.js', str(response.content), 1, ) def test_login_load_javascript(self): self.client.logout() response = self.client.get(reverse('admin:login')) self.assertNotContains(response, 'notifications.js') def test_websocket_protocol(self): with self.subTest('Test in production environment'): response = self.client.get(self._url) self.assertContains(response, 'wss') def test_notification_setting_inline_read_only_fields(self): with self.subTest('Test for superuser'): self.assertListEqual( self.ns_inline.get_readonly_fields(su_request), []) with self.subTest('Test for non-superuser'): self.assertListEqual( self.ns_inline.get_readonly_fields(op_request), ['type', 'organization'], ) def test_notification_setting_inline_add_permission(self): with self.subTest('Test for superuser'): self.assertTrue(self.ns_inline.has_add_permission(su_request)) with self.subTest('Test for non-superuser'): self.assertFalse(self.ns_inline.has_add_permission(op_request), ) def test_notification_setting_inline_delete_permission(self): with self.subTest('Test for superuser'): self.assertTrue(self.ns_inline.has_delete_permission(su_request)) with self.subTest('Test for non-superuser'): self.assertFalse(self.ns_inline.has_delete_permission(op_request)) def test_notification_setting_inline_organization_formfield(self): response = self.client.get( reverse('admin:openwisp_users_user_change', args=(self.admin.pk, ))) self.assertContains( response, '<option value="default" selected>Default Type</option>') def test_notification_setting_inline_admin_has_change_permission(self): with self.subTest('Test for superuser'): self.assertTrue(self.ns_inline.has_change_permission(su_request), ) with self.subTest('Test for non-superuser'): self.assertFalse( self.ns_inline.has_change_permission(op_request), ) self.assertTrue( self.ns_inline.has_change_permission(op_request, obj=op_request.user), ) def test_org_admin_view_same_org_user_notification_setting(self): org_owner = self._create_org_user( user=self._get_operator(), is_admin=True, ) org_admin = self._create_org_user( user=self._create_user(username='******', email='*****@*****.**', is_staff=True), is_admin=True, ) permissions = Permission.objects.all() org_owner.user.user_permissions.set(permissions) org_admin.user.user_permissions.set(permissions) self.client.force_login(org_owner.user) response = self.client.get( reverse('admin:openwisp_users_user_change', args=(org_admin.user_id, )), ) self.assertEqual(response.status_code, 200) self.assertContains(response, 'User notification settings') self.assertNotContains( response, '<option value="default" selected>Default Type</option>') def test_object_notification_setting_empty(self): response = self.client.get( reverse('admin:openwisp_users_user_change', args=(self.admin.pk, ))) self.assertNotContains( response, 'src="/static/openwisp-notifications/js/object-notifications.js"') @override_settings( OPENWISP_NOTIFICATIONS_IGNORE_ENABLED_ADMIN=[ 'openwisp_users.admin.UserAdmin' ], ) def test_object_notification_setting_configured(self): _add_object_notification_widget() response = self.client.get( reverse('admin:openwisp_users_user_change', args=(self.admin.pk, ))) self.assertContains( response, 'src="/static/openwisp-notifications/js/object-notifications.js"', 1, ) # If a ModelAdmin already has a Media class with self.assertWarns(MediaOrderConflictWarning): _add_object_notification_widget() response = self.client.get( reverse('admin:openwisp_users_user_change', args=(self.admin.pk, ))) # If a ModelAdmin has list instances of js and css UserAdmin.Media.css = {'all': list()} UserAdmin.Media.js = list() _add_object_notification_widget() response = self.client.get( reverse('admin:openwisp_users_user_change', args=(self.admin.pk, ))) # If ModelAdmin has empty attributes UserAdmin.Media.js = [] UserAdmin.Media.css = {} _add_object_notification_widget() response = self.client.get( reverse('admin:openwisp_users_user_change', args=(self.admin.pk, ))) UserAdmin.Media = None def test_ignore_notification_widget_add_view(self): url = reverse('admin:openwisp_users_organization_add') response = self.client.get(url) self.assertNotContains(response, 'owIsChangeForm')