Skip to content

Commit

Permalink
[chore] Add Global Notification
Browse files Browse the repository at this point in the history
  • Loading branch information
Dhanus3133 committed Jul 19, 2024
1 parent f795a65 commit 74a48f5
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 13 deletions.
25 changes: 15 additions & 10 deletions openwisp_notifications/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ def get_api_urls(api_views=None):
name='notification_read_redirect',
),
# WIP
# path(
# 'user/user-setting/',
# views.notification_setting_list,
# name='notification_setting_list',
# ),
# path(
# 'user/user-setting/<uuid:pk>/',
# views.notification_setting,
# name='notification_setting',
# ),
path(
'user/user-setting/',
views.notification_setting_list,
name='notification_setting_list',
),
path(
'user/user-setting/<uuid:pk>/',
views.notification_setting,
name='notification_setting',
),
path(
'notification/ignore/',
views.ignore_object_notification_list,
Expand All @@ -51,4 +51,9 @@ def get_api_urls(api_views=None):
views.organization_notification_setting,
name='organization_notification_setting',
),
path(
'user/<uuid:user_id>/preference/',
views.notification_preference,
name='notification_preference',
),
]
26 changes: 24 additions & 2 deletions openwisp_notifications/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,29 @@ def post(self, request, user_id, organization_id):
for notification_setting in notification_settings:
serializer.update(notification_setting, serializer.validated_data)
return Response(status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class NotificationPreferenceView(GenericAPIView):
permission_classes = [IsAuthenticated, IsAuthenticatedToUpdateNotificationSetting]
serializer_class = NotificationSettingUpdateSerializer

def post(self, request, user_id):
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
email = serializer.validated_data.get('email')
web = serializer.validated_data.get('web')
(
notification_settings,
created,
) = NotificationSetting.objects.update_or_create(
user_id=user_id,
organization=None,
type=None,
defaults={'email': email, 'web': web},
)
return Response(status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


notifications_list = NotificationListView.as_view()
Expand All @@ -228,3 +249,4 @@ def post(self, request, user_id, organization_id):
organization_notification_setting = OrganizationNotificationSettingView.as_view()
ignore_object_notification_list = IgnoreObjectNotificationListView.as_view()
ignore_object_notification = IgnoreObjectNotificationView.as_view()
notification_preference = NotificationPreferenceView.as_view()
2 changes: 2 additions & 0 deletions openwisp_notifications/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ class AbstractNotificationSetting(UUIDModel):
organization = models.ForeignKey(
get_model_name('openwisp_users', 'Organization'),
on_delete=models.CASCADE,
null=True,
blank=True,
)
web = models.BooleanField(
_('web notifications'), null=True, blank=True, help_text=_(_RECEIVE_HELP)
Expand Down
11 changes: 11 additions & 0 deletions openwisp_notifications/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,17 @@ def send_email_notification(sender, instance, created, **kwargs):
return
# Get email preference of user for this type of notification.
target_org = getattr(getattr(instance, 'target', None), 'organization_id', None)

# Check for global notification setting
try:
notification_setting = instance.recipient.notificationsetting_set.get(
organization=None, type=None
)
if not notification_setting.email_notification:
return
except NotificationSetting.DoesNotExist:
pass

if instance.type and target_org:
try:
notification_setting = instance.recipient.notificationsetting_set.get(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.2.11 on 2024-06-18 13:05

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("openwisp_users", "0020_populate_password_updated_field"),
("openwisp_notifications", "0007_notificationsetting_deleted"),
]

operations = [
migrations.AlterField(
model_name="notificationsetting",
name="organization",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="openwisp_users.organization",
),
),
]
44 changes: 43 additions & 1 deletion openwisp_notifications/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,49 @@ def test_organization_notification_setting_update(self):

with self.subTest('Test for non-admin user'):
self.client.force_login(tester)
url = self._get_path('organization_notification_setting', self.admin.pk, org.pk)
url = self._get_path(
'organization_notification_setting',
self.admin.pk,
org.pk,
)
response = self.client.post(url, data={'web': True, 'email': True})
self.assertEqual(response.status_code, 403)

def test_notification_preference_update(self):
tester = self._create_user()

with self.subTest('Test for current user'):
url = self._get_path(
'notification_preference',
self.admin.pk,
)
response = self.client.post(url, data={'web': True, 'email': True})
self.assertEqual(response.status_code, 200)
notification_setting = NotificationSetting.objects.get(
user=self.admin, organization_id=None, type=None
)
self.assertTrue(notification_setting.web, True)
self.assertTrue(notification_setting.email, True)

with self.subTest('Test for admin user'):
url = self._get_path(
'notification_preference',
tester.pk,
)
response = self.client.post(url, data={'web': True, 'email': True})
self.assertEqual(response.status_code, 200)
notification_setting = NotificationSetting.objects.get(
user=tester, organization_id=None, type=None
)
self.assertTrue(notification_setting.web, True)
self.assertTrue(notification_setting.email, True)

with self.subTest('Test for non-admin user'):
self.client.force_login(tester)
url = self._get_path(
'notification_preference',
self.admin.pk,
)
response = self.client.post(url, data={'web': True, 'email': True})
self.assertEqual(response.status_code, 403)

Expand Down
22 changes: 22 additions & 0 deletions openwisp_notifications/tests/test_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,28 @@ def test_notification_type_web_notification_setting_true(self):
self._create_notification()
self.assertEqual(notification_queryset.count(), 0)

@mock_notification_types
def test_global_email_notification_setting(self):
with self.subTest('Test email global preference is "False"'):
NotificationSetting.objects.update_or_create(
user=self.admin,
organization=None,
type=None,
defaults={'email': False, 'web': False},
)
self._create_notification()
self.assertEqual(len(mail.outbox), 0)

with self.subTest('Test email global preference is "True"'):
NotificationSetting.objects.update_or_create(
user=self.admin,
organization=None,
type=None,
defaults={'email': True, 'web': True},
)
self._create_notification()
self.assertEqual(len(mail.outbox), 1)

@mock_notification_types
def test_notification_type_web_notification_setting_false(self):
target_obj = self._get_org_user()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.2.11 on 2024-06-20 13:02

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("openwisp_users", "0020_populate_password_updated_field"),
("sample_notifications", "0002_testapp"),
]

operations = [
migrations.AlterField(
model_name="notificationsetting",
name="organization",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="openwisp_users.organization",
),
),
]

0 comments on commit 74a48f5

Please sign in to comment.