notification_settings: Refactor notification preference settings.

Previously, all notification preference setting had a dedicated test
and setter. Now, all are handled through a modular function using the
property_types framework.
This commit is contained in:
Matt Long 2017-05-23 01:19:21 +00:00 committed by Tim Abbott
parent fe1fc45a9e
commit 19363b2b77
6 changed files with 54 additions and 304 deletions

View File

@ -2233,120 +2233,28 @@ system-generated notifications.""" % (stream_name,)
"signups", string_id, signup_message)
return (realm, created)
def do_change_enable_stream_desktop_notifications(user_profile,
enable_stream_desktop_notifications,
log=True):
# type: (UserProfile, bool, bool) -> None
user_profile.enable_stream_desktop_notifications = enable_stream_desktop_notifications
user_profile.save(update_fields=["enable_stream_desktop_notifications"])
event = {'type': 'update_global_notifications',
'user': user_profile.email,
'notification_name': 'enable_stream_desktop_notifications',
'setting': enable_stream_desktop_notifications}
if log:
log_event(event)
send_event(event, [user_profile.id])
def do_change_notification_settings(user_profile, name, value, log=True):
# type: (UserProfile, str, bool, bool) -> None
"""Takes in a UserProfile object, the name of a global notification
preference to update, and the value to update to
"""
def do_change_enable_stream_sounds(user_profile, enable_stream_sounds, log=True):
# type: (UserProfile, bool, bool) -> None
user_profile.enable_stream_sounds = enable_stream_sounds
user_profile.save(update_fields=["enable_stream_sounds"])
event = {'type': 'update_global_notifications',
'user': user_profile.email,
'notification_name': 'enable_stream_sounds',
'setting': enable_stream_sounds}
if log:
log_event(event)
send_event(event, [user_profile.id])
notification_setting_type = UserProfile.notification_setting_types[name]
assert isinstance(value, notification_setting_type), (
'Cannot update %s: %s is not an instance of %s' % (
name, value, notification_setting_type,))
def do_change_enable_desktop_notifications(user_profile, enable_desktop_notifications, log=True):
# type: (UserProfile, bool, bool) -> None
user_profile.enable_desktop_notifications = enable_desktop_notifications
user_profile.save(update_fields=["enable_desktop_notifications"])
event = {'type': 'update_global_notifications',
'user': user_profile.email,
'notification_name': 'enable_desktop_notifications',
'setting': enable_desktop_notifications}
if log:
log_event(event)
send_event(event, [user_profile.id])
setattr(user_profile, name, value)
def do_change_pm_content_in_desktop_notifications(user_profile,
pm_content_in_desktop_notifications, log=True):
# type: (UserProfile, bool, bool) -> None
user_profile.pm_content_in_desktop_notifications \
= pm_content_in_desktop_notifications
user_profile.save(update_fields=["pm_content_in_desktop_notifications"])
event = {'type': 'update_global_notifications',
'user': user_profile.email,
'notification_name': 'pm_content_in_desktop_notifications',
'setting': pm_content_in_desktop_notifications}
if log:
log_event(event)
send_event(event, [user_profile.id])
def do_change_enable_sounds(user_profile, enable_sounds, log=True):
# type: (UserProfile, bool, bool) -> None
user_profile.enable_sounds = enable_sounds
user_profile.save(update_fields=["enable_sounds"])
event = {'type': 'update_global_notifications',
'user': user_profile.email,
'notification_name': 'enable_sounds',
'setting': enable_sounds}
if log:
log_event(event)
send_event(event, [user_profile.id])
def do_change_enable_offline_email_notifications(user_profile, offline_email_notifications, log=True):
# type: (UserProfile, bool, bool) -> None
user_profile.enable_offline_email_notifications = offline_email_notifications
user_profile.save(update_fields=["enable_offline_email_notifications"])
event = {'type': 'update_global_notifications',
'user': user_profile.email,
'notification_name': 'enable_offline_email_notifications',
'setting': offline_email_notifications}
if log:
log_event(event)
send_event(event, [user_profile.id])
def do_change_enable_offline_push_notifications(user_profile, offline_push_notifications, log=True):
# type: (UserProfile, bool, bool) -> None
user_profile.enable_offline_push_notifications = offline_push_notifications
user_profile.save(update_fields=["enable_offline_push_notifications"])
event = {'type': 'update_global_notifications',
'user': user_profile.email,
'notification_name': 'enable_offline_push_notifications',
'setting': offline_push_notifications}
if log:
log_event(event)
send_event(event, [user_profile.id])
def do_change_enable_online_push_notifications(user_profile, enable_online_push_notifications, log=True):
# type: (UserProfile, bool, bool) -> None
user_profile.enable_online_push_notifications = enable_online_push_notifications
user_profile.save(update_fields=["enable_online_push_notifications"])
event = {'type': 'update_global_notifications',
'user': user_profile.email,
'notification_name': 'enable_online_push_notifications',
'setting': enable_online_push_notifications}
if log:
log_event(event)
send_event(event, [user_profile.id])
def do_change_enable_digest_emails(user_profile, enable_digest_emails, log=True):
# type: (UserProfile, bool, bool) -> None
user_profile.enable_digest_emails = enable_digest_emails
user_profile.save(update_fields=["enable_digest_emails"])
if not enable_digest_emails:
# Remove any digest emails that have been enqueued.
# Disabling digest emails should clear a user's email queue
if name == 'enable_digest_emails' and value == False:
clear_followup_emails_queue(user_profile.email)
user_profile.save(update_fields=[name])
event = {'type': 'update_global_notifications',
'user': user_profile.email,
'notification_name': 'enable_digest_emails',
'setting': enable_digest_emails}
'notification_name': name,
'setting': value}
if log:
log_event(event)
send_event(event, [user_profile.id])

View File

@ -7,7 +7,7 @@ from optparse import make_option
from django.core.management.base import BaseCommand, CommandParser
from zerver.lib.actions import do_change_enable_digest_emails
from zerver.lib.actions import do_change_notification_settings
from zerver.models import Realm, UserProfile, get_realm, get_user_profile_by_email
class Command(BaseCommand):
@ -45,7 +45,7 @@ class Command(BaseCommand):
for user_profile in user_profiles:
already_disabled_prefix = ""
if user_profile.enable_digest_emails:
do_change_enable_digest_emails(user_profile, False)
do_change_notification_settings(user_profile, 'enable_digest_emails', False)
else:
already_disabled_prefix = "(already off) "
print("%s%s <%s>" % (already_disabled_prefix, user_profile.full_name,

View File

@ -661,6 +661,18 @@ class UserProfile(ModelReprMixin, AbstractBaseUser, PermissionsMixin):
twenty_four_hour_time=bool,
)
notification_setting_types = dict(
enable_desktop_notifications=bool,
enable_digest_emails=bool,
enable_offline_email_notifications=bool,
enable_offline_push_notifications=bool,
enable_online_push_notifications=bool,
enable_sounds=bool,
enable_stream_desktop_notifications=bool,
enable_stream_sounds=bool,
pm_content_in_desktop_notifications=bool,
)
@property
def profile_data(self):
# type: () -> List[Dict[str, Union[int, float, Text]]]

View File

@ -59,15 +59,7 @@ from zerver.lib.actions import (
do_update_pointer,
do_update_user_presence,
do_set_user_display_setting,
do_change_enable_stream_desktop_notifications,
do_change_enable_stream_sounds,
do_change_enable_desktop_notifications,
do_change_enable_sounds,
do_change_enable_offline_email_notifications,
do_change_enable_offline_push_notifications,
do_change_enable_online_push_notifications,
do_change_pm_content_in_desktop_notifications,
do_change_enable_digest_emails,
do_change_notification_settings,
do_add_realm_domain,
do_change_realm_domain,
do_remove_realm_domain,
@ -1037,136 +1029,21 @@ class EventsRegisterTest(ZulipTestCase):
# type: () -> None
self.do_set_user_display_settings_test("timezone", [u'US/Mountain', u'US/Samoa', u'Pacific/Galapagos', u''])
def test_change_enable_stream_desktop_notifications(self):
def test_change_notification_settings(self):
# type: () -> None
schema_checker = self.check_events_dict([
('type', equals('update_global_notifications')),
('notification_name', equals('enable_stream_desktop_notifications')),
('user', check_string),
('setting', check_bool),
])
do_change_enable_stream_desktop_notifications(self.user_profile, False)
for setting_value in [True, False]:
events = self.do_test(lambda: do_change_enable_stream_desktop_notifications(self.user_profile, setting_value, log=False))
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_change_enable_stream_sounds(self):
# type: () -> None
schema_checker = self.check_events_dict([
('type', equals('update_global_notifications')),
('notification_name', equals('enable_stream_sounds')),
('user', check_string),
('setting', check_bool),
])
do_change_enable_stream_sounds(self.user_profile, False)
for setting_value in [True, False]:
events = self.do_test(lambda: do_change_enable_stream_sounds(self.user_profile, setting_value, log=False))
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_change_enable_desktop_notifications(self):
# type: () -> None
schema_checker = self.check_events_dict([
('type', equals('update_global_notifications')),
('notification_name', equals('enable_desktop_notifications')),
('user', check_string),
('setting', check_bool),
])
do_change_enable_desktop_notifications(self.user_profile, False)
for setting_value in [True, False]:
events = self.do_test(lambda: do_change_enable_desktop_notifications(self.user_profile, setting_value, log=False))
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_change_enable_sounds(self):
# type: () -> None
schema_checker = self.check_events_dict([
('type', equals('update_global_notifications')),
('notification_name', equals('enable_sounds')),
('user', check_string),
('setting', check_bool),
])
do_change_enable_sounds(self.user_profile, False)
for setting_value in [True, False]:
events = self.do_test(lambda: do_change_enable_sounds(self.user_profile, setting_value, log=False))
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_change_enable_offline_email_notifications(self):
# type: () -> None
schema_checker = self.check_events_dict([
('type', equals('update_global_notifications')),
('notification_name', equals('enable_offline_email_notifications')),
('user', check_string),
('setting', check_bool),
])
do_change_enable_offline_email_notifications(self.user_profile, False)
for setting_value in [True, False]:
events = self.do_test(lambda: do_change_enable_offline_email_notifications(self.user_profile, setting_value, log=False))
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_change_enable_offline_push_notifications(self):
# type: () -> None
schema_checker = self.check_events_dict([
('type', equals('update_global_notifications')),
('notification_name', equals('enable_offline_push_notifications')),
('user', check_string),
('setting', check_bool),
])
do_change_enable_offline_push_notifications(self.user_profile, False)
for setting_value in [True, False]:
events = self.do_test(lambda: do_change_enable_offline_push_notifications(self.user_profile, setting_value, log=False))
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_change_enable_online_push_notifications(self):
# type: () -> None
schema_checker = self.check_events_dict([
('type', equals('update_global_notifications')),
('notification_name', equals('enable_online_push_notifications')),
('user', check_string),
('setting', check_bool),
])
do_change_enable_online_push_notifications(self.user_profile, False)
for setting_value in [True, False]:
events = self.do_test(lambda: do_change_enable_online_push_notifications(self.user_profile, setting_value, log=False))
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_change_pm_content_in_desktop_notifications(self):
# type: () -> None
schema_checker = self.check_events_dict([
('type', equals('update_global_notifications')),
('notification_name', equals('pm_content_in_desktop_notifications')),
('user', check_string),
('setting', check_bool),
])
do_change_pm_content_in_desktop_notifications(self.user_profile, False)
for setting_value in [True, False]:
events = self.do_test(
lambda: do_change_pm_content_in_desktop_notifications(self.user_profile,
setting_value,
log=False),
)
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_change_enable_digest_emails(self):
# type: () -> None
schema_checker = self.check_events_dict([
('type', equals('update_global_notifications')),
('notification_name', equals('enable_digest_emails')),
('user', check_string),
('setting', check_bool),
])
do_change_enable_digest_emails(self.user_profile, False)
for setting_value in [True, False]:
events = self.do_test(lambda: do_change_enable_digest_emails(self.user_profile, setting_value, log=False))
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
for notification_setting, v in self.user_profile.notification_setting_types.items():
schema_checker = self.check_events_dict([
('type', equals('update_global_notifications')),
('notification_name', equals(notification_setting)),
('user', check_string),
('setting', check_bool),
])
do_change_notification_settings(self.user_profile, notification_setting, False)
for setting_value in [True, False]:
events = self.do_test(lambda: do_change_notification_settings(
self.user_profile, notification_setting, setting_value, log=False))
error = schema_checker('events[0]', events[0])
self.assert_on_error(error)
def test_realm_emoji_events(self):
# type: () -> None

View File

@ -6,8 +6,7 @@ from django.shortcuts import render
from typing import Callable
from confirmation.models import Confirmation
from zerver.lib.actions import do_change_enable_offline_email_notifications, \
do_change_enable_digest_emails, clear_followup_emails_queue
from zerver.lib.actions import do_change_notification_settings, clear_followup_emails_queue
from zerver.models import UserProfile
from zerver.context_processors import common_context
@ -29,7 +28,7 @@ def process_unsubscribe(request, token, subscription_type, unsubscribe_function)
def do_missedmessage_unsubscribe(user_profile):
# type: (UserProfile) -> None
do_change_enable_offline_email_notifications(user_profile, False)
do_change_notification_settings(user_profile, 'enable_offline_email_notifications', False)
def do_welcome_unsubscribe(user_profile):
# type: (UserProfile) -> None
@ -37,7 +36,7 @@ def do_welcome_unsubscribe(user_profile):
def do_digest_unsubscribe(user_profile):
# type: (UserProfile) -> None
do_change_enable_digest_emails(user_profile, False)
do_change_notification_settings(user_profile, 'enable_digest_emails', False)
# The keys are part of the URL for the unsubscribe link and must be valid
# without encoding.

View File

@ -12,15 +12,10 @@ from django.urls import reverse
from zerver.decorator import authenticated_json_post_view, has_request_variables, \
zulip_login_required, REQ, human_users_only
from zerver.lib.actions import do_change_password, \
do_change_enable_desktop_notifications, \
do_change_enter_sends, do_change_enable_sounds, \
do_change_enable_offline_email_notifications, do_change_enable_digest_emails, \
do_change_enable_offline_push_notifications, do_change_enable_online_push_notifications, \
do_change_enter_sends, do_change_notification_settings, \
do_change_default_desktop_notifications, do_change_autoscroll_forever, \
do_change_enable_stream_desktop_notifications, do_change_enable_stream_sounds, \
do_regenerate_api_key, do_change_avatar_fields, do_set_user_display_setting, \
do_change_pm_content_in_desktop_notifications, validate_email, \
do_change_user_email, do_start_email_change_process
validate_email, do_change_user_email, do_start_email_change_process
from zerver.lib.avatar import avatar_url
from zerver.lib.send_email import send_email, display_email
from zerver.lib.i18n import get_available_language_codes
@ -206,53 +201,12 @@ def json_change_notify_settings(request, user_profile,
# Stream notification settings.
if enable_stream_desktop_notifications is not None and \
user_profile.enable_stream_desktop_notifications != enable_stream_desktop_notifications:
do_change_enable_stream_desktop_notifications(
user_profile, enable_stream_desktop_notifications)
result['enable_stream_desktop_notifications'] = enable_stream_desktop_notifications
req_vars = {k: v for k, v in list(locals().items()) if k in user_profile.notification_setting_types}
if enable_stream_sounds is not None and \
user_profile.enable_stream_sounds != enable_stream_sounds:
do_change_enable_stream_sounds(user_profile, enable_stream_sounds)
result['enable_stream_sounds'] = enable_stream_sounds
# PM and @-mention settings.
if enable_desktop_notifications is not None and \
user_profile.enable_desktop_notifications != enable_desktop_notifications:
do_change_enable_desktop_notifications(user_profile, enable_desktop_notifications)
result['enable_desktop_notifications'] = enable_desktop_notifications
if enable_sounds is not None and \
user_profile.enable_sounds != enable_sounds:
do_change_enable_sounds(user_profile, enable_sounds)
result['enable_sounds'] = enable_sounds
if enable_offline_email_notifications is not None and \
user_profile.enable_offline_email_notifications != enable_offline_email_notifications:
do_change_enable_offline_email_notifications(user_profile, enable_offline_email_notifications)
result['enable_offline_email_notifications'] = enable_offline_email_notifications
if enable_offline_push_notifications is not None and \
user_profile.enable_offline_push_notifications != enable_offline_push_notifications:
do_change_enable_offline_push_notifications(user_profile, enable_offline_push_notifications)
result['enable_offline_push_notifications'] = enable_offline_push_notifications
if enable_online_push_notifications is not None and \
user_profile.enable_online_push_notifications != enable_online_push_notifications:
do_change_enable_online_push_notifications(user_profile, enable_online_push_notifications)
result['enable_online_push_notifications'] = enable_online_push_notifications
if enable_digest_emails is not None and \
user_profile.enable_digest_emails != enable_digest_emails:
do_change_enable_digest_emails(user_profile, enable_digest_emails)
result['enable_digest_emails'] = enable_digest_emails
if pm_content_in_desktop_notifications is not None and \
user_profile.pm_content_in_desktop_notifications != pm_content_in_desktop_notifications:
do_change_pm_content_in_desktop_notifications(user_profile, pm_content_in_desktop_notifications)
result['pm_content_in_desktop_notifications'] = pm_content_in_desktop_notifications
for k, v in list(req_vars.items()):
if v is not None and getattr(user_profile, k) != v:
do_change_notification_settings(user_profile, k, v)
result[k] = v
return json_success(result)