def test_email_translation(self) -> None: def check_translation(phrase: str, request_type: str, *args: Any, **kwargs: Any) -> None: if request_type == "post": self.client_post(*args, **kwargs) elif request_type == "patch": # nocoverage: see comment below self.client_patch(*args, **kwargs) email_message = mail.outbox[0] self.assertIn(phrase, email_message.body) for i in range(len(mail.outbox)): mail.outbox.pop() hamlet = self.example_user("hamlet") hamlet.default_language = "de" hamlet.save() realm = hamlet.realm realm.default_language = "de" realm.save() stream = get_realm_stream("Denmark", realm.id) self.login_user(hamlet) # TODO: Uncomment and replace with translation once we have German translations for the strings # in confirm_new_email.txt. # Also remove the "nocoverage" from check_translation above. # check_translation("Viele Grüße", "patch", "/json/settings", {"email": "*****@*****.**"}) check_translation("Incrível!", "post", "/accounts/home/", {"email": "*****@*****.**"}, HTTP_ACCEPT_LANGUAGE="pt") check_translation("Danke, dass du", "post", '/accounts/find/', {'emails': hamlet.delivery_email}) check_translation("Hallo", "post", "/json/invites", {"invitee_emails": "*****@*****.**", "stream_ids": orjson.dumps([stream.id]).decode()}) with self.settings(DEVELOPMENT_LOG_EMAILS=True): enqueue_welcome_emails(hamlet) check_translation("Viele Grüße", "")
def test_followup_emails_count(self) -> None: hamlet = self.example_user("hamlet") cordelia = self.example_user("cordelia") enqueue_welcome_emails(self.example_user("hamlet")) # Hamlet has account only in Zulip realm so both day1 and day2 emails should be sent scheduled_emails = ScheduledEmail.objects.filter( users=hamlet).order_by("scheduled_timestamp") self.assertEqual(2, len(scheduled_emails)) self.assertEqual( ujson.loads(scheduled_emails[1].data)["template_prefix"], 'zerver/emails/followup_day2') self.assertEqual( ujson.loads(scheduled_emails[0].data)["template_prefix"], 'zerver/emails/followup_day1') ScheduledEmail.objects.all().delete() enqueue_welcome_emails(cordelia) scheduled_emails = ScheduledEmail.objects.filter(users=cordelia) # Cordelia has account in more than 1 realm so day2 email should not be sent self.assertEqual(len(scheduled_emails), 1) email_data = ujson.loads(scheduled_emails[0].data) self.assertEqual(email_data["template_prefix"], 'zerver/emails/followup_day1')
def test_day1_email_context(self) -> None: hamlet = self.example_user("hamlet") enqueue_welcome_emails(hamlet) scheduled_emails = ScheduledEmail.objects.filter(users=hamlet) email_data = ujson.loads(scheduled_emails[0].data) self.assertEqual(email_data["context"]["email"], self.example_email("hamlet")) self.assertEqual(email_data["context"]["is_realm_admin"], False) self.assertEqual(email_data["context"]["getting_started_link"], "https://zulipchat.com") self.assertNotIn("ldap_username", email_data["context"]) ScheduledEmail.objects.all().delete() iago = self.example_user("iago") enqueue_welcome_emails(iago) scheduled_emails = ScheduledEmail.objects.filter(users=iago) email_data = ujson.loads(scheduled_emails[0].data) self.assertEqual(email_data["context"]["email"], self.example_email("iago")) self.assertEqual(email_data["context"]["is_realm_admin"], True) self.assertEqual( email_data["context"]["getting_started_link"], "http://zulip.testserver/help/getting-your-organization-started-with-zulip" ) self.assertNotIn("ldap_username", email_data["context"])
def generate_all_emails(request: HttpRequest) -> HttpResponse: if not settings.TEST_SUITE: # nocoverage # It's really convenient to automatically inline the email CSS # here, since that saves a step when testing out changes to # the email CSS. But we don't run this inside the test suite, # because by role, the tests shouldn't be doing a provision-like thing. subprocess.check_call(["./scripts/setup/inline_email_css.py"]) # We import the Django test client inside the view function, # because it isn't needed in production elsewhere, and not # importing it saves ~50ms of unnecessary manage.py startup time. from django.test import Client client = Client() # write fake data for all variables registered_email = "*****@*****.**" unregistered_email_1 = "*****@*****.**" unregistered_email_2 = "*****@*****.**" realm = get_realm("zulip") other_realm = Realm.objects.exclude(string_id='zulip').first() user = get_user_by_delivery_email(registered_email, realm) host_kwargs = {'HTTP_HOST': realm.host} # Password reset emails # active account in realm result = client.post('/accounts/password/reset/', {'email': registered_email}, **host_kwargs) assert result.status_code == 302 # deactivated user user.is_active = False user.save(update_fields=['is_active']) result = client.post('/accounts/password/reset/', {'email': registered_email}, **host_kwargs) assert result.status_code == 302 user.is_active = True user.save(update_fields=['is_active']) # account on different realm result = client.post('/accounts/password/reset/', {'email': registered_email}, HTTP_HOST=other_realm.host) assert result.status_code == 302 # no account anywhere result = client.post('/accounts/password/reset/', {'email': unregistered_email_1}, **host_kwargs) assert result.status_code == 302 # Confirm account email result = client.post('/accounts/home/', {'email': unregistered_email_1}, **host_kwargs) assert result.status_code == 302 # Find account email result = client.post('/accounts/find/', {'emails': registered_email}, **host_kwargs) assert result.status_code == 302 # New login email logged_in = client.login(dev_auth_username=registered_email, realm=realm) assert logged_in # New user invite and reminder emails stream = get_realm_stream("Denmark", user.realm.id) result = client.post( "/json/invites", { "invitee_emails": unregistered_email_2, "stream_ids": ujson.dumps([stream.id]) }, **host_kwargs) assert result.status_code == 200 # Verification for new email result = client.patch( '/json/settings', urllib.parse.urlencode({'email': '*****@*****.**'}), **host_kwargs) assert result.status_code == 200 # Email change successful key = Confirmation.objects.filter( type=Confirmation.EMAIL_CHANGE).latest('id').confirmation_key url = confirmation_url(key, realm.host, Confirmation.EMAIL_CHANGE) user_profile = get_user_by_delivery_email(registered_email, realm) result = client.get(url) assert result.status_code == 200 # Reset the email value so we can run this again do_change_user_delivery_email(user_profile, registered_email) # Follow up day1 day2 emails for normal user enqueue_welcome_emails(user_profile) # Follow up day1 day2 emails for admin user enqueue_welcome_emails(get_user_by_delivery_email("*****@*****.**", realm), realm_creation=True) # Realm reactivation email do_send_realm_reactivation_email(realm) return redirect(email_page)
def process_new_human_user( user_profile: UserProfile, prereg_user: Optional[PreregistrationUser] = None, default_stream_groups: Sequence[DefaultStreamGroup] = [], realm_creation: bool = False, ) -> None: realm = user_profile.realm mit_beta_user = realm.is_zephyr_mirror_realm if prereg_user is not None: streams: List[Stream] = list(prereg_user.streams.all()) acting_user: Optional[UserProfile] = prereg_user.referred_by # A PregistrationUser should not be used for another UserProfile assert prereg_user.created_user is None, "PregistrationUser should not be reused" else: streams = [] acting_user = None # If the user's invitation didn't explicitly list some streams, we # add the default streams if len(streams) == 0: streams = get_default_subs(user_profile) for default_stream_group in default_stream_groups: default_stream_group_streams = default_stream_group.streams.all() for stream in default_stream_group_streams: if stream not in streams: streams.append(stream) bulk_add_subscriptions( realm, streams, [user_profile], from_user_creation=True, acting_user=acting_user, ) add_new_user_history(user_profile, streams) # mit_beta_users don't have a referred_by field if (not mit_beta_user and prereg_user is not None and prereg_user.referred_by is not None and prereg_user.referred_by.is_active): # This is a cross-realm private message. with override_language(prereg_user.referred_by.default_language): internal_send_private_message( get_system_bot(settings.NOTIFICATION_BOT, prereg_user.referred_by.realm_id), prereg_user.referred_by, _("{user} accepted your invitation to join Zulip!").format( user=f"{user_profile.full_name} <`{user_profile.email}`>"), ) # Revoke all preregistration users except prereg_user, and link prereg_user to # the created user if prereg_user is None: assert not realm_creation, "realm_creation should only happen with a PreregistrationUser" if prereg_user is not None: prereg_user.status = confirmation_settings.STATUS_ACTIVE prereg_user.created_user = user_profile prereg_user.save(update_fields=["status", "created_user"]) # In the special case of realm creation, there can be no additional PreregistrationUser # for us to want to modify - because other realm_creation PreregistrationUsers should be # left usable for creating different realms. if not realm_creation: # Mark any other PreregistrationUsers in the realm that are STATUS_ACTIVE as # inactive so we can keep track of the PreregistrationUser we # actually used for analytics. if prereg_user is not None: PreregistrationUser.objects.filter( email__iexact=user_profile.delivery_email, realm=user_profile.realm).exclude(id=prereg_user.id).update( status=confirmation_settings.STATUS_REVOKED) else: PreregistrationUser.objects.filter( email__iexact=user_profile.delivery_email, realm=user_profile.realm).update( status=confirmation_settings.STATUS_REVOKED) if prereg_user is not None and prereg_user.referred_by is not None: notify_invites_changed(user_profile.realm) notify_new_user(user_profile) # Clear any scheduled invitation emails to prevent them # from being sent after the user is created. clear_scheduled_invitation_emails(user_profile.delivery_email) if realm.send_welcome_emails: enqueue_welcome_emails(user_profile, realm_creation) # We have an import loop here; it's intentional, because we want # to keep all the onboarding code in zerver/lib/onboarding.py. from zerver.lib.onboarding import send_initial_pms send_initial_pms(user_profile)