realm: Migrate to typed_endpoint.

This commit is contained in:
Kenneth Rodrigues 2024-07-12 21:19:28 +05:30 committed by Tim Abbott
parent a7da24a36f
commit ba79d759f1
2 changed files with 116 additions and 113 deletions

View File

@ -2016,6 +2016,12 @@ class RealmAPITest(ZulipTestCase):
) )
self.assert_json_error(result, "Invalid email batching period: 604810 seconds") self.assert_json_error(result, "Invalid email batching period: 604810 seconds")
def test_invalid_emojiset_value(self) -> None:
result = self.client_patch("/json/realm/user_settings_defaults", {"emojiset": "invalid"})
self.assert_json_error(
result, "Invalid emojiset: Value error, Not in the list of possible values"
)
def test_ignored_parameters_in_realm_default_endpoint(self) -> None: def test_ignored_parameters_in_realm_default_endpoint(self) -> None:
params = {"starred_message_counts": orjson.dumps(False).decode(), "emoji_set": "twitter"} params = {"starred_message_counts": orjson.dumps(False).decode(), "emoji_set": "twitter"}
result = self.client_patch("/json/realm/user_settings_defaults", params) result = self.client_patch("/json/realm/user_settings_defaults", params)

View File

@ -1,5 +1,5 @@
from collections.abc import Mapping from collections.abc import Mapping
from typing import Annotated, Any from typing import Annotated, Any, Literal
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import transaction from django.db import transaction
@ -31,11 +31,15 @@ from zerver.decorator import require_realm_admin, require_realm_owner
from zerver.forms import check_subdomain_available as check_subdomain from zerver.forms import check_subdomain_available as check_subdomain
from zerver.lib.exceptions import JsonableError, OrganizationOwnerRequiredError from zerver.lib.exceptions import JsonableError, OrganizationOwnerRequiredError
from zerver.lib.i18n import get_available_language_codes from zerver.lib.i18n import get_available_language_codes
from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.retention import parse_message_retention_days from zerver.lib.retention import parse_message_retention_days
from zerver.lib.streams import access_stream_by_id from zerver.lib.streams import access_stream_by_id
from zerver.lib.typed_endpoint import ApiParamConfig, typed_endpoint from zerver.lib.typed_endpoint import (
ApiParamConfig,
typed_endpoint,
typed_endpoint_without_parameters,
)
from zerver.lib.typed_endpoint_validators import check_int_in_validator, check_string_in_validator
from zerver.lib.user_groups import ( from zerver.lib.user_groups import (
GroupSettingChangeRequest, GroupSettingChangeRequest,
access_user_group_for_setting, access_user_group_for_setting,
@ -43,14 +47,7 @@ from zerver.lib.user_groups import (
parse_group_setting_value, parse_group_setting_value,
validate_group_setting_value_change, validate_group_setting_value_change,
) )
from zerver.lib.validator import ( from zerver.lib.validator import check_capped_url, check_string
check_bool,
check_capped_url,
check_int,
check_int_in,
check_string,
check_string_in,
)
from zerver.models import Realm, RealmReactivationStatus, RealmUserDefault, UserProfile from zerver.models import Realm, RealmReactivationStatus, RealmUserDefault, UserProfile
from zerver.models.realms import ( from zerver.models.realms import (
BotCreationPolicyEnum, BotCreationPolicyEnum,
@ -485,7 +482,7 @@ def update_realm(
@require_realm_owner @require_realm_owner
@has_request_variables @typed_endpoint_without_parameters
def deactivate_realm(request: HttpRequest, user: UserProfile) -> HttpResponse: def deactivate_realm(request: HttpRequest, user: UserProfile) -> HttpResponse:
realm = user.realm realm = user.realm
do_deactivate_realm( do_deactivate_realm(
@ -521,74 +518,68 @@ def realm_reactivation(request: HttpRequest, confirmation_key: str) -> HttpRespo
emojiset_choices = {emojiset["key"] for emojiset in RealmUserDefault.emojiset_choices()} emojiset_choices = {emojiset["key"] for emojiset in RealmUserDefault.emojiset_choices()}
web_home_view_options = ["recent_topics", "inbox", "all_messages"]
@require_realm_admin @require_realm_admin
@has_request_variables @typed_endpoint
def update_realm_user_settings_defaults( def update_realm_user_settings_defaults(
request: HttpRequest, request: HttpRequest,
user_profile: UserProfile, user_profile: UserProfile,
dense_mode: bool | None = REQ(json_validator=check_bool, default=None), *,
web_mark_read_on_scroll_policy: int | None = REQ( dense_mode: Json[bool] | None = None,
json_validator=check_int_in(UserProfile.WEB_MARK_READ_ON_SCROLL_POLICY_CHOICES), web_mark_read_on_scroll_policy: Json[
default=None, Annotated[
), int,
web_channel_default_view: int | None = REQ( check_int_in_validator(UserProfile.WEB_MARK_READ_ON_SCROLL_POLICY_CHOICES),
json_validator=check_int_in(UserProfile.WEB_CHANNEL_DEFAULT_VIEW_CHOICES), ]
default=None, ]
), | None = None,
starred_message_counts: bool | None = REQ(json_validator=check_bool, default=None), web_channel_default_view: Json[
receives_typing_notifications: bool | None = REQ(json_validator=check_bool, default=None), Annotated[int, check_int_in_validator(UserProfile.WEB_CHANNEL_DEFAULT_VIEW_CHOICES)]
web_stream_unreads_count_display_policy: int | None = REQ( ]
json_validator=check_int_in(UserProfile.WEB_STREAM_UNREADS_COUNT_DISPLAY_POLICY_CHOICES), | None = None,
default=None, starred_message_counts: Json[bool] | None = None,
), receives_typing_notifications: Json[bool] | None = None,
fluid_layout_width: bool | None = REQ(json_validator=check_bool, default=None), web_stream_unreads_count_display_policy: Json[
high_contrast_mode: bool | None = REQ(json_validator=check_bool, default=None), Annotated[
color_scheme: int | None = REQ( int,
json_validator=check_int_in(UserProfile.COLOR_SCHEME_CHOICES), default=None check_int_in_validator(UserProfile.WEB_STREAM_UNREADS_COUNT_DISPLAY_POLICY_CHOICES),
), ]
web_font_size_px: int | None = REQ(json_validator=check_int, default=None), ]
web_line_height_percent: int | None = REQ(json_validator=check_int, default=None), | None = None,
translate_emoticons: bool | None = REQ(json_validator=check_bool, default=None), fluid_layout_width: Json[bool] | None = None,
display_emoji_reaction_users: bool | None = REQ(json_validator=check_bool, default=None), high_contrast_mode: Json[bool] | None = None,
web_home_view: str | None = REQ( color_scheme: Json[Annotated[int, check_int_in_validator(UserProfile.COLOR_SCHEME_CHOICES)]]
str_validator=check_string_in(web_home_view_options), default=None | None = None,
), web_font_size_px: Json[int] | None = None,
web_escape_navigates_to_home_view: bool | None = REQ(json_validator=check_bool, default=None), web_line_height_percent: Json[int] | None = None,
left_side_userlist: bool | None = REQ(json_validator=check_bool, default=None), translate_emoticons: Json[bool] | None = None,
emojiset: str | None = REQ(str_validator=check_string_in(emojiset_choices), default=None), display_emoji_reaction_users: Json[bool] | None = None,
demote_inactive_streams: int | None = REQ( web_home_view: Literal["recent_topics", "inbox", "all_messages"] | None = None,
json_validator=check_int_in(UserProfile.DEMOTE_STREAMS_CHOICES), default=None web_escape_navigates_to_home_view: Json[bool] | None = None,
), left_side_userlist: Json[bool] | None = None,
enable_stream_desktop_notifications: bool | None = REQ(json_validator=check_bool, default=None), emojiset: Annotated[str, check_string_in_validator(emojiset_choices)] | None = None,
enable_stream_email_notifications: bool | None = REQ(json_validator=check_bool, default=None), demote_inactive_streams: Json[
enable_stream_push_notifications: bool | None = REQ(json_validator=check_bool, default=None), Annotated[int, check_int_in_validator(UserProfile.DEMOTE_STREAMS_CHOICES)]
enable_stream_audible_notifications: bool | None = REQ(json_validator=check_bool, default=None), ]
wildcard_mentions_notify: bool | None = REQ(json_validator=check_bool, default=None), | None = None,
enable_followed_topic_desktop_notifications: bool | None = REQ( enable_stream_desktop_notifications: Json[bool] | None = None,
json_validator=check_bool, default=None enable_stream_email_notifications: Json[bool] | None = None,
), enable_stream_push_notifications: Json[bool] | None = None,
enable_followed_topic_email_notifications: bool | None = REQ( enable_stream_audible_notifications: Json[bool] | None = None,
json_validator=check_bool, default=None wildcard_mentions_notify: Json[bool] | None = None,
), enable_followed_topic_desktop_notifications: Json[bool] | None = None,
enable_followed_topic_push_notifications: bool | None = REQ( enable_followed_topic_email_notifications: Json[bool] | None = None,
json_validator=check_bool, default=None enable_followed_topic_push_notifications: Json[bool] | None = None,
), enable_followed_topic_audible_notifications: Json[bool] | None = None,
enable_followed_topic_audible_notifications: bool | None = REQ( enable_followed_topic_wildcard_mentions_notify: Json[bool] | None = None,
json_validator=check_bool, default=None notification_sound: str | None = None,
), enable_desktop_notifications: Json[bool] | None = None,
enable_followed_topic_wildcard_mentions_notify: bool | None = REQ( enable_sounds: Json[bool] | None = None,
json_validator=check_bool, default=None enable_offline_email_notifications: Json[bool] | None = None,
), enable_offline_push_notifications: Json[bool] | None = None,
notification_sound: str | None = REQ(default=None), enable_online_push_notifications: Json[bool] | None = None,
enable_desktop_notifications: bool | None = REQ(json_validator=check_bool, default=None), enable_digest_emails: Json[bool] | None = None,
enable_sounds: bool | None = REQ(json_validator=check_bool, default=None),
enable_offline_email_notifications: bool | None = REQ(json_validator=check_bool, default=None),
enable_offline_push_notifications: bool | None = REQ(json_validator=check_bool, default=None),
enable_online_push_notifications: bool | None = REQ(json_validator=check_bool, default=None),
enable_digest_emails: bool | None = REQ(json_validator=check_bool, default=None),
# enable_login_emails is not included here, because we don't want # enable_login_emails is not included here, because we don't want
# security-related settings to be controlled by organization administrators. # security-related settings to be controlled by organization administrators.
# enable_marketing_emails is not included here, since we don't at # enable_marketing_emails is not included here, since we don't at
@ -597,45 +588,51 @@ def update_realm_user_settings_defaults(
# #
# We may want to change this model in the future, since some SSO signups # We may want to change this model in the future, since some SSO signups
# do not offer an opportunity to prompt the user at all during signup. # do not offer an opportunity to prompt the user at all during signup.
message_content_in_email_notifications: bool | None = REQ( message_content_in_email_notifications: Json[bool] | None = None,
json_validator=check_bool, default=None pm_content_in_desktop_notifications: Json[bool] | None = None,
), desktop_icon_count_display: Json[
pm_content_in_desktop_notifications: bool | None = REQ(json_validator=check_bool, default=None), Annotated[int, check_int_in_validator(UserProfile.DESKTOP_ICON_COUNT_DISPLAY_CHOICES)]
desktop_icon_count_display: int | None = REQ( ]
json_validator=check_int_in(UserProfile.DESKTOP_ICON_COUNT_DISPLAY_CHOICES), default=None | None = None,
), realm_name_in_email_notifications_policy: Json[
realm_name_in_email_notifications_policy: int | None = REQ( Annotated[
json_validator=check_int_in(UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_CHOICES), int,
default=None, check_int_in_validator(UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_CHOICES),
), ]
automatically_follow_topics_policy: int | None = REQ( ]
json_validator=check_int_in(UserProfile.AUTOMATICALLY_CHANGE_VISIBILITY_POLICY_CHOICES), | None = None,
default=None, automatically_follow_topics_policy: Json[
), Annotated[
automatically_unmute_topics_in_muted_streams_policy: int | None = REQ( int,
json_validator=check_int_in(UserProfile.AUTOMATICALLY_CHANGE_VISIBILITY_POLICY_CHOICES), check_int_in_validator(UserProfile.AUTOMATICALLY_CHANGE_VISIBILITY_POLICY_CHOICES),
default=None, ]
), ]
automatically_follow_topics_where_mentioned: bool | None = REQ( | None = None,
json_validator=check_bool, default=None automatically_unmute_topics_in_muted_streams_policy: Json[
), Annotated[
presence_enabled: bool | None = REQ(json_validator=check_bool, default=None), int,
enter_sends: bool | None = REQ(json_validator=check_bool, default=None), check_int_in_validator(UserProfile.AUTOMATICALLY_CHANGE_VISIBILITY_POLICY_CHOICES),
enable_drafts_synchronization: bool | None = REQ(json_validator=check_bool, default=None), ]
email_notifications_batching_period_seconds: int | None = REQ( ]
json_validator=check_int, default=None | None = None,
), automatically_follow_topics_where_mentioned: Json[bool] | None = None,
twenty_four_hour_time: bool | None = REQ(json_validator=check_bool, default=None), presence_enabled: Json[bool] | None = None,
send_stream_typing_notifications: bool | None = REQ(json_validator=check_bool, default=None), enter_sends: Json[bool] | None = None,
send_private_typing_notifications: bool | None = REQ(json_validator=check_bool, default=None), enable_drafts_synchronization: Json[bool] | None = None,
send_read_receipts: bool | None = REQ(json_validator=check_bool, default=None), email_notifications_batching_period_seconds: Json[int] | None = None,
user_list_style: int | None = REQ( twenty_four_hour_time: Json[bool] | None = None,
json_validator=check_int_in(UserProfile.USER_LIST_STYLE_CHOICES), default=None send_stream_typing_notifications: Json[bool] | None = None,
), send_private_typing_notifications: Json[bool] | None = None,
email_address_visibility: int | None = REQ( send_read_receipts: Json[bool] | None = None,
json_validator=check_int_in(UserProfile.EMAIL_ADDRESS_VISIBILITY_TYPES), default=None user_list_style: Json[
), Annotated[int, check_int_in_validator(UserProfile.USER_LIST_STYLE_CHOICES)]
web_navigate_to_sent_message: bool | None = REQ(json_validator=check_bool, default=None), ]
| None = None,
email_address_visibility: Json[
Annotated[int, check_int_in_validator(UserProfile.EMAIL_ADDRESS_VISIBILITY_TYPES)]
]
| None = None,
web_navigate_to_sent_message: Json[bool] | None = None,
) -> HttpResponse: ) -> HttpResponse:
if notification_sound is not None or email_notifications_batching_period_seconds is not None: if notification_sound is not None or email_notifications_batching_period_seconds is not None:
check_settings_values(notification_sound, email_notifications_batching_period_seconds) check_settings_values(notification_sound, email_notifications_batching_period_seconds)