users: Use browser locale to set the default language of new user.

This commit reads the browser locale during user registration, and
sets it as default language of user if it is supported by Zulip.
Otherwise, it is set to realm's default language.
This commit is contained in:
Siddharth Asthana
2021-04-04 20:28:41 +05:30
committed by Tim Abbott
parent 807c73ef17
commit 9954db4b59
4 changed files with 47 additions and 5 deletions

View File

@@ -344,6 +344,7 @@ def do_create_user(
tos_version: Optional[str] = None, tos_version: Optional[str] = None,
timezone: str = "", timezone: str = "",
avatar_source: str = UserProfile.AVATAR_FROM_GRAVATAR, avatar_source: str = UserProfile.AVATAR_FROM_GRAVATAR,
default_language: str = "en",
default_sending_stream: Optional[Stream] = None, default_sending_stream: Optional[Stream] = None,
default_events_register_stream: Optional[Stream] = None, default_events_register_stream: Optional[Stream] = None,
default_all_public_streams: Optional[bool] = None, default_all_public_streams: Optional[bool] = None,
@@ -367,6 +368,7 @@ def do_create_user(
tos_version=tos_version, tos_version=tos_version,
timezone=timezone, timezone=timezone,
avatar_source=avatar_source, avatar_source=avatar_source,
default_language=default_language,
default_sending_stream=default_sending_stream, default_sending_stream=default_sending_stream,
default_events_register_stream=default_events_register_stream, default_events_register_stream=default_events_register_stream,
default_all_public_streams=default_all_public_streams, default_all_public_streams=default_all_public_streams,

View File

@@ -84,6 +84,7 @@ def create_user_profile(
is_mirror_dummy: bool, is_mirror_dummy: bool,
tos_version: Optional[str], tos_version: Optional[str],
timezone: Optional[str], timezone: Optional[str],
default_language: str = "en",
tutorial_status: str = UserProfile.TUTORIAL_WAITING, tutorial_status: str = UserProfile.TUTORIAL_WAITING,
enter_sends: bool = False, enter_sends: bool = False,
force_id: Optional[int] = None, force_id: Optional[int] = None,
@@ -116,7 +117,7 @@ def create_user_profile(
tutorial_status=tutorial_status, tutorial_status=tutorial_status,
enter_sends=enter_sends, enter_sends=enter_sends,
onboarding_steps=orjson.dumps([]).decode(), onboarding_steps=orjson.dumps([]).decode(),
default_language=realm.default_language, default_language=default_language,
delivery_email=email, delivery_email=email,
**extra_kwargs, **extra_kwargs,
) )
@@ -143,6 +144,7 @@ def create_user(
timezone: str = "", timezone: str = "",
avatar_source: str = UserProfile.AVATAR_FROM_GRAVATAR, avatar_source: str = UserProfile.AVATAR_FROM_GRAVATAR,
is_mirror_dummy: bool = False, is_mirror_dummy: bool = False,
default_language: str = "en",
default_sending_stream: Optional[Stream] = None, default_sending_stream: Optional[Stream] = None,
default_events_register_stream: Optional[Stream] = None, default_events_register_stream: Optional[Stream] = None,
default_all_public_streams: Optional[bool] = None, default_all_public_streams: Optional[bool] = None,
@@ -162,6 +164,7 @@ def create_user(
is_mirror_dummy, is_mirror_dummy,
tos_version, tos_version,
timezone, timezone,
default_language,
force_id=force_id, force_id=force_id,
force_date_joined=force_date_joined, force_date_joined=force_date_joined,
) )

View File

@@ -3933,8 +3933,7 @@ class UserSignUpTest(InviteUserBase):
def test_user_default_language_and_timezone(self) -> None: def test_user_default_language_and_timezone(self) -> None:
""" """
Check if the default language of new user is the default language Check if the default language of new user is set using the browser locale
of the realm.
""" """
email = self.nonreg_email("newguy") email = self.nonreg_email("newguy")
password = "newpassword" password = "newpassword"
@@ -3954,12 +3953,42 @@ class UserSignUpTest(InviteUserBase):
self.assertEqual(result.status_code, 200) self.assertEqual(result.status_code, 200)
# Pick a password and agree to the ToS. # Pick a password and agree to the ToS.
result = self.submit_reg_form_for_user(email, password, timezone=timezone) result = self.submit_reg_form_for_user(
email, password, timezone=timezone, HTTP_ACCEPT_LANGUAGE="fr,en;q=0.9"
)
self.assertEqual(result.status_code, 302)
user_profile = self.nonreg_user("newguy")
self.assertNotEqual(user_profile.default_language, realm.default_language)
self.assertEqual(user_profile.default_language, "fr")
self.assertEqual(user_profile.timezone, timezone)
from django.core.mail import outbox
outbox.pop()
def test_default_language_with_unsupported_browser_locale(self) -> None:
email = self.nonreg_email("newguy")
password = "newpassword"
realm = get_realm("zulip")
do_set_realm_property(realm, "default_language", "de", acting_user=None)
result = self.client_post("/accounts/home/", {"email": email})
self.assertEqual(result.status_code, 302)
self.assertTrue(result["Location"].endswith(f"/accounts/send_confirm/{email}"))
result = self.client_get(result["Location"])
self.assert_in_response("Check your email so we can get started.", result)
# Visit the confirmation link.
confirmation_url = self.get_confirmation_url_from_outbox(email)
result = self.client_get(confirmation_url)
self.assertEqual(result.status_code, 200)
# Pick a password and agree to the ToS.
result = self.submit_reg_form_for_user(email, password, HTTP_ACCEPT_LANGUAGE="en-IND")
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
user_profile = self.nonreg_user("newguy") user_profile = self.nonreg_user("newguy")
self.assertEqual(user_profile.default_language, realm.default_language) self.assertEqual(user_profile.default_language, realm.default_language)
self.assertEqual(user_profile.timezone, timezone)
from django.core.mail import outbox from django.core.mail import outbox
outbox.pop() outbox.pop()

View File

@@ -44,6 +44,7 @@ from zerver.forms import (
) )
from zerver.lib.email_validation import email_allowed_for_realm, validate_email_not_already_in_realm from zerver.lib.email_validation import email_allowed_for_realm, validate_email_not_already_in_realm
from zerver.lib.exceptions import RateLimited from zerver.lib.exceptions import RateLimited
from zerver.lib.i18n import get_default_language_for_new_user
from zerver.lib.pysa import mark_sanitized from zerver.lib.pysa import mark_sanitized
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.send_email import EmailNotDeliveredException, FromAddress, send_email from zerver.lib.send_email import EmailNotDeliveredException, FromAddress, send_email
@@ -432,6 +433,12 @@ def accounts_register(
do_change_password(user_profile, password) do_change_password(user_profile, password)
do_change_full_name(user_profile, full_name, user_profile) do_change_full_name(user_profile, full_name, user_profile)
do_change_user_setting(user_profile, "timezone", timezone, acting_user=user_profile) do_change_user_setting(user_profile, "timezone", timezone, acting_user=user_profile)
do_change_user_setting(
user_profile,
"default_language",
get_default_language_for_new_user(request, realm),
acting_user=None,
)
# TODO: When we clean up the `do_activate_mirror_dummy_user` code path, # TODO: When we clean up the `do_activate_mirror_dummy_user` code path,
# make it respect invited_as_admin / is_realm_admin. # make it respect invited_as_admin / is_realm_admin.
@@ -445,6 +452,7 @@ def accounts_register(
role=role, role=role,
tos_version=settings.TERMS_OF_SERVICE_VERSION, tos_version=settings.TERMS_OF_SERVICE_VERSION,
timezone=timezone, timezone=timezone,
default_language=get_default_language_for_new_user(request, realm),
default_stream_groups=default_stream_groups, default_stream_groups=default_stream_groups,
source_profile=source_profile, source_profile=source_profile,
realm_creation=realm_creation, realm_creation=realm_creation,