diff --git a/zerver/lib/create_user.py b/zerver/lib/create_user.py index 3f5cca8781..cb0b8d0f0b 100644 --- a/zerver/lib/create_user.py +++ b/zerver/lib/create_user.py @@ -14,6 +14,19 @@ def random_api_key() -> str: altchars = ''.join([choices[ord(os.urandom(1)) % 62] for _ in range(2)]).encode("utf-8") return base64.b64encode(os.urandom(24), altchars=altchars).decode("utf-8") +def copy_user_settings(source_profile: UserProfile, + target_profile: UserProfile) -> UserProfile: + """Warning: Does not save, to avoid extra database queries""" + for settings_name in UserProfile.property_types: + value = getattr(source_profile, settings_name) + setattr(target_profile, settings_name, value) + + for settings_name in UserProfile.notification_setting_types: + value = getattr(source_profile, settings_name) + setattr(target_profile, settings_name, value) + + return target_profile + # create_user_profile is based on Django's User.objects.create_user, # except that we don't save to the database so it can used in # bulk_creates diff --git a/zerver/tests/test_users.py b/zerver/tests/test_users.py index a25f580110..8f46b4e48a 100644 --- a/zerver/tests/test_users.py +++ b/zerver/tests/test_users.py @@ -35,6 +35,7 @@ from zerver.lib.actions import ( do_change_is_admin, do_create_user, ) +from zerver.lib.create_user import copy_user_settings from zerver.lib.topic_mutes import add_topic_mute from zerver.lib.stream_topic import StreamTopicTarget from zerver.lib.users import user_ids_to_users @@ -369,6 +370,46 @@ class UserProfileTest(ZulipTestCase): self.assertIsNone(get_source_profile("iago@zulip.com", "ZULIP")) self.assertIsNone(get_source_profile("iago@zulip.com", "lear")) + def test_copy_user_settings(self) -> None: + iago = self.example_user("iago") + cordelia = self.example_user("cordelia") + hamlet = self.example_user("hamlet") + + cordelia.default_language = "de" + cordelia.emojiset = "apple" + cordelia.timezone = "America/Phoenix" + cordelia.night_mode = True + cordelia.enable_offline_email_notifications = False + cordelia.enable_stream_push_notifications = True + cordelia.save() + + cordelia = copy_user_settings(cordelia, iago) + + # We verify that cordelia and iago match, but hamlet has the defaults. + self.assertEqual(iago.default_language, "de") + self.assertEqual(cordelia.default_language, "de") + self.assertEqual(hamlet.default_language, "en") + + self.assertEqual(iago.emojiset, "apple") + self.assertEqual(cordelia.emojiset, "apple") + self.assertEqual(hamlet.emojiset, "google") + + self.assertEqual(iago.timezone, "America/Phoenix") + self.assertEqual(cordelia.timezone, "America/Phoenix") + self.assertEqual(hamlet.timezone, "") + + self.assertEqual(iago.night_mode, True) + self.assertEqual(cordelia.night_mode, True) + self.assertEqual(hamlet.night_mode, False) + + self.assertEqual(iago.enable_offline_email_notifications, False) + self.assertEqual(cordelia.enable_offline_email_notifications, False) + self.assertEqual(hamlet.enable_offline_email_notifications, True) + + self.assertEqual(iago.enable_stream_push_notifications, True) + self.assertEqual(cordelia.enable_stream_push_notifications, True) + self.assertEqual(hamlet.enable_stream_push_notifications, False) + class ActivateTest(ZulipTestCase): def test_basics(self) -> None: user = self.example_user('hamlet')