mirror of https://github.com/zulip/zulip.git
user_settings: Automate 'Include realm name in message email subject'.
Currently, there is a checkbox setting for whether to "Include realm name in subject of message notification emails". This commit replaces the checkbox setting with a dropdown having values: Automatic [default], Always, Never. The Automatic option includes the realm name if, and only if, there are multiple Zulip realms associated with the user's email. Tests are added and(or) modified. Fixes: #19905.
This commit is contained in:
parent
ab8222c4ae
commit
ae72777c77
|
@ -20,6 +20,13 @@ format used by the Zulip server that they are interacting with.
|
||||||
|
|
||||||
## Changes in Zulip 7.0
|
## Changes in Zulip 7.0
|
||||||
|
|
||||||
|
**Feature level 168**
|
||||||
|
|
||||||
|
* [`PATCH /realm/user_settings_defaults`](/api/update-realm-user-settings-defaults),
|
||||||
|
[`POST /register`](/api/register-queue),
|
||||||
|
[`PATCH /settings`](/api/update-settings): Replaced the `realm_name_in_notifications`
|
||||||
|
boolean field with an integer field `realm_name_in_email_notifications_policy`.
|
||||||
|
|
||||||
**Feature level 167**
|
**Feature level 167**
|
||||||
|
|
||||||
* [All REST API endpoints](/api/rest-error-handling#ignored-parameters):
|
* [All REST API endpoints](/api/rest-error-handling#ignored-parameters):
|
||||||
|
|
|
@ -16,5 +16,5 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
{% trans %}New messages{% endtrans %}
|
{% trans %}New messages{% endtrans %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if realm_name_in_notifications %} [{{ realm_str }}]
|
{% if include_realm_name_in_missedmessage_emails_subject %} [{{ realm_str }}]
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.4.3"
|
||||||
# Changes should be accompanied by documentation explaining what the
|
# Changes should be accompanied by documentation explaining what the
|
||||||
# new level means in api_docs/changelog.md, as well as "**Changes**"
|
# new level means in api_docs/changelog.md, as well as "**Changes**"
|
||||||
# entries in the endpoint's documentation in `zulip.yaml`.
|
# entries in the endpoint's documentation in `zulip.yaml`.
|
||||||
API_FEATURE_LEVEL = 167
|
API_FEATURE_LEVEL = 168
|
||||||
|
|
||||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
||||||
# only when going from an old version of the code to a newer version. Bump
|
# only when going from an old version of the code to a newer version. Bump
|
||||||
|
|
|
@ -181,6 +181,8 @@ export function build_page() {
|
||||||
realm_user_settings_defaults.enable_stream_audible_notifications,
|
realm_user_settings_defaults.enable_stream_audible_notifications,
|
||||||
email_notifications_batching_period_values:
|
email_notifications_batching_period_values:
|
||||||
settings_config.email_notifications_batching_period_values,
|
settings_config.email_notifications_batching_period_values,
|
||||||
|
realm_name_in_email_notifications_policy_values:
|
||||||
|
settings_config.realm_name_in_email_notifications_policy_values,
|
||||||
twenty_four_hour_time_values: settings_config.twenty_four_hour_time_values,
|
twenty_four_hour_time_values: settings_config.twenty_four_hour_time_values,
|
||||||
create_web_public_stream_policy_values:
|
create_web_public_stream_policy_values:
|
||||||
settings_config.create_web_public_stream_policy_values,
|
settings_config.create_web_public_stream_policy_values,
|
||||||
|
|
|
@ -29,7 +29,7 @@ export type RealmDefaultSettings = {
|
||||||
notification_sound: string;
|
notification_sound: string;
|
||||||
pm_content_in_desktop_notifications: boolean;
|
pm_content_in_desktop_notifications: boolean;
|
||||||
presence_enabled: boolean;
|
presence_enabled: boolean;
|
||||||
realm_name_in_notifications: boolean;
|
realm_name_in_email_notifications_policy: number;
|
||||||
starred_message_counts: boolean;
|
starred_message_counts: boolean;
|
||||||
translate_emoticons: boolean;
|
translate_emoticons: boolean;
|
||||||
twenty_four_hour_time: boolean;
|
twenty_four_hour_time: boolean;
|
||||||
|
|
|
@ -95,6 +95,8 @@ export function build_page() {
|
||||||
notification_settings: settings_config.all_notifications(user_settings).settings,
|
notification_settings: settings_config.all_notifications(user_settings).settings,
|
||||||
email_notifications_batching_period_values:
|
email_notifications_batching_period_values:
|
||||||
settings_config.email_notifications_batching_period_values,
|
settings_config.email_notifications_batching_period_values,
|
||||||
|
realm_name_in_email_notifications_policy_values:
|
||||||
|
settings_config.realm_name_in_email_notifications_policy_values,
|
||||||
desktop_icon_count_display_values: settings_config.desktop_icon_count_display_values,
|
desktop_icon_count_display_values: settings_config.desktop_icon_count_display_values,
|
||||||
show_push_notifications_tooltip:
|
show_push_notifications_tooltip:
|
||||||
settings_config.all_notifications(user_settings).show_push_notifications_tooltip,
|
settings_config.all_notifications(user_settings).show_push_notifications_tooltip,
|
||||||
|
|
|
@ -541,7 +541,7 @@ export const notification_settings_labels = {
|
||||||
message_content_in_email_notifications: $t({
|
message_content_in_email_notifications: $t({
|
||||||
defaultMessage: "Include message content in message notification emails",
|
defaultMessage: "Include message content in message notification emails",
|
||||||
}),
|
}),
|
||||||
realm_name_in_notifications: $t({
|
realm_name_in_email_notifications_policy: $t({
|
||||||
defaultMessage: "Include organization name in subject of message notification emails",
|
defaultMessage: "Include organization name in subject of message notification emails",
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
@ -677,10 +677,7 @@ export const email_notifications_batching_period_values = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const email_message_notification_settings = [
|
const email_message_notification_settings = ["message_content_in_email_notifications"];
|
||||||
"message_content_in_email_notifications",
|
|
||||||
"realm_name_in_notifications",
|
|
||||||
];
|
|
||||||
|
|
||||||
const other_email_settings = [
|
const other_email_settings = [
|
||||||
"enable_digest_emails",
|
"enable_digest_emails",
|
||||||
|
@ -699,6 +696,7 @@ const other_notification_settings = [
|
||||||
...mobile_notification_settings,
|
...mobile_notification_settings,
|
||||||
...email_notification_settings,
|
...email_notification_settings,
|
||||||
"email_notifications_batching_period_seconds",
|
"email_notifications_batching_period_seconds",
|
||||||
|
"realm_name_in_email_notifications_policy",
|
||||||
"notification_sound",
|
"notification_sound",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -790,6 +788,21 @@ export const all_notifications = (settings_object: Settings): AllNotifications =
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const realm_name_in_email_notifications_policy_values = {
|
||||||
|
automatic: {
|
||||||
|
code: 1,
|
||||||
|
description: $t({defaultMessage: "Automatic"}),
|
||||||
|
},
|
||||||
|
always: {
|
||||||
|
code: 2,
|
||||||
|
description: $t({defaultMessage: "Always"}),
|
||||||
|
},
|
||||||
|
never: {
|
||||||
|
code: 3,
|
||||||
|
description: $t({defaultMessage: "Never"}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const desktop_icon_count_display_values = {
|
export const desktop_icon_count_display_values = {
|
||||||
messages: {
|
messages: {
|
||||||
code: 1,
|
code: 1,
|
||||||
|
|
|
@ -150,6 +150,13 @@ export function set_up(settings_panel) {
|
||||||
settings_object.email_notifications_batching_period_seconds,
|
settings_object.email_notifications_batching_period_seconds,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const $realm_name_in_email_notifications_policy_dropdown = $container.find(
|
||||||
|
".setting_realm_name_in_email_notifications_policy",
|
||||||
|
);
|
||||||
|
$realm_name_in_email_notifications_policy_dropdown.val(
|
||||||
|
settings_object.realm_name_in_email_notifications_policy,
|
||||||
|
);
|
||||||
|
|
||||||
set_enable_digest_emails_visibility(settings_panel);
|
set_enable_digest_emails_visibility(settings_panel);
|
||||||
|
|
||||||
if (for_realm_settings) {
|
if (for_realm_settings) {
|
||||||
|
@ -232,7 +239,8 @@ export function update_page(settings_panel) {
|
||||||
set_notification_batching_ui($container, settings_object[setting]);
|
set_notification_batching_ui($container, settings_object[setting]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "notification_sound": {
|
case "notification_sound":
|
||||||
|
case "realm_name_in_email_notifications_policy": {
|
||||||
$container.find(`.setting_${CSS.escape(setting)}`).val(settings_object[setting]);
|
$container.find(`.setting_${CSS.escape(setting)}`).val(settings_object[setting]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ export type UserSettings = (StreamNotificationSettings & PmNotificationSettings)
|
||||||
notification_sound: string;
|
notification_sound: string;
|
||||||
pm_content_in_desktop_notifications: boolean;
|
pm_content_in_desktop_notifications: boolean;
|
||||||
presence_enabled: boolean;
|
presence_enabled: boolean;
|
||||||
realm_name_in_notifications: boolean;
|
realm_name_in_email_notifications_policy: number;
|
||||||
user_list_style: number;
|
user_list_style: number;
|
||||||
starred_message_counts: boolean;
|
starred_message_counts: boolean;
|
||||||
translate_emoticons: boolean;
|
translate_emoticons: boolean;
|
||||||
|
|
|
@ -147,6 +147,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="realm_name_in_email_notifications_policy" class="dropdown-title">{{ settings_label.realm_name_in_email_notifications_policy }}</label>
|
||||||
|
<select name="realm_name_in_email_notifications_policy" class="setting_realm_name_in_email_notifications_policy prop-element settings_select bootstrap-focus-style" id="{{prefix}}realm_name_in_email_notifications_policy" data-setting-widget-type="number">
|
||||||
|
{{> dropdown_options_widget option_values=realm_name_in_email_notifications_policy_values}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{#each notification_settings.email_message_notification_settings}}
|
{{#each notification_settings.email_message_notification_settings}}
|
||||||
{{> settings_checkbox
|
{{> settings_checkbox
|
||||||
setting_name=this
|
setting_name=this
|
||||||
|
|
|
@ -385,6 +385,28 @@ def message_content_allowed_in_missedmessage_emails(user_profile: UserProfile) -
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def include_realm_name_in_missedmessage_emails_subject(user_profile: UserProfile) -> bool:
|
||||||
|
# Determines whether to include the realm name in the subject line
|
||||||
|
# of missedmessage email notifications, based on the user's
|
||||||
|
# realm_name_in_email_notifications_policy settings and whether the
|
||||||
|
# user's delivery_email is associated with other active realms.
|
||||||
|
if (
|
||||||
|
user_profile.realm_name_in_email_notifications_policy
|
||||||
|
== UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_AUTOMATIC
|
||||||
|
):
|
||||||
|
realms_count = UserProfile.objects.filter(
|
||||||
|
delivery_email=user_profile.delivery_email,
|
||||||
|
is_active=True,
|
||||||
|
is_bot=False,
|
||||||
|
realm__deactivated=False,
|
||||||
|
).count()
|
||||||
|
return realms_count > 1
|
||||||
|
return (
|
||||||
|
user_profile.realm_name_in_email_notifications_policy
|
||||||
|
== UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_ALWAYS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@statsd_increment("missed_message_reminders")
|
@statsd_increment("missed_message_reminders")
|
||||||
def do_send_missedmessage_events_reply_in_zulip(
|
def do_send_missedmessage_events_reply_in_zulip(
|
||||||
user_profile: UserProfile, missed_messages: List[Dict[str, Any]], message_count: int
|
user_profile: UserProfile, missed_messages: List[Dict[str, Any]], message_count: int
|
||||||
|
@ -417,7 +439,9 @@ def do_send_missedmessage_events_reply_in_zulip(
|
||||||
name=user_profile.full_name,
|
name=user_profile.full_name,
|
||||||
message_count=message_count,
|
message_count=message_count,
|
||||||
unsubscribe_link=unsubscribe_link,
|
unsubscribe_link=unsubscribe_link,
|
||||||
realm_name_in_notifications=user_profile.realm_name_in_notifications,
|
include_realm_name_in_missedmessage_emails_subject=include_realm_name_in_missedmessage_emails_subject(
|
||||||
|
user_profile
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
mentioned_user_group_name = get_mentioned_user_group_name(missed_messages, user_profile)
|
mentioned_user_group_name = get_mentioned_user_group_name(missed_messages, user_profile)
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
# Generated by Django 4.1.5 on 2023-01-11 20:21
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||||
|
from django.db.migrations.state import StateApps
|
||||||
|
|
||||||
|
# We include a copy of this structure as it was at the time this
|
||||||
|
# migration was merged, since future should not impact the migration.
|
||||||
|
REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_AUTOMATIC = 1
|
||||||
|
REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_ALWAYS = 2
|
||||||
|
REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_NEVER = 3
|
||||||
|
|
||||||
|
|
||||||
|
# The value of 'realm_name_in_email_notifications_policy' for those users
|
||||||
|
# who have manually changed the value of 'realm_name_in_notifications' as 'true'
|
||||||
|
# should be updated as 'Always', not 'Automatic'
|
||||||
|
def update_realm_name_in_email_notifications_policy_values(
|
||||||
|
apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
|
||||||
|
) -> None:
|
||||||
|
UserProfile = apps.get_model("zerver", "UserProfile")
|
||||||
|
UserProfile.objects.filter(realm_name_in_notifications=True).update(
|
||||||
|
realm_name_in_email_notifications_policy=REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_ALWAYS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def reverse_code(apps: StateApps, schema_editor: BaseDatabaseSchemaEditor) -> None:
|
||||||
|
UserProfile = apps.get_model("zerver", "UserProfile")
|
||||||
|
UserProfile.objects.filter(
|
||||||
|
realm_name_in_email_notifications_policy=REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_ALWAYS
|
||||||
|
).update(realm_name_in_notifications=True)
|
||||||
|
|
||||||
|
|
||||||
|
def update_realm_name_in_email_notifications_policy_values_for_realm_user_default(
|
||||||
|
apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
|
||||||
|
) -> None:
|
||||||
|
RealmUserDefault = apps.get_model("zerver", "RealmUserDefault")
|
||||||
|
RealmUserDefault.objects.filter(realm_name_in_notifications=True).update(
|
||||||
|
realm_name_in_email_notifications_policy=REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_ALWAYS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def reverse_code_for_realm_user_default(
|
||||||
|
apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
|
||||||
|
) -> None:
|
||||||
|
RealmUserDefault = apps.get_model("zerver", "RealmUserDefault")
|
||||||
|
RealmUserDefault.objects.filter(
|
||||||
|
realm_name_in_email_notifications_policy=REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_ALWAYS
|
||||||
|
).update(realm_name_in_notifications=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("zerver", "0431_alter_archivedreaction_unique_together_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="realmuserdefault",
|
||||||
|
name="realm_name_in_email_notifications_policy",
|
||||||
|
field=models.PositiveSmallIntegerField(
|
||||||
|
default=REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_AUTOMATIC
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
update_realm_name_in_email_notifications_policy_values_for_realm_user_default,
|
||||||
|
reverse_code=reverse_code_for_realm_user_default,
|
||||||
|
elidable=True,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="userprofile",
|
||||||
|
name="realm_name_in_email_notifications_policy",
|
||||||
|
field=models.PositiveSmallIntegerField(
|
||||||
|
default=REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_AUTOMATIC
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
update_realm_name_in_email_notifications_policy_values,
|
||||||
|
reverse_code=reverse_code,
|
||||||
|
elidable=True,
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="realmuserdefault",
|
||||||
|
name="realm_name_in_notifications",
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="userprofile",
|
||||||
|
name="realm_name_in_notifications",
|
||||||
|
),
|
||||||
|
]
|
|
@ -1597,9 +1597,20 @@ class UserBaseSettings(models.Model):
|
||||||
enable_digest_emails = models.BooleanField(default=True)
|
enable_digest_emails = models.BooleanField(default=True)
|
||||||
enable_login_emails = models.BooleanField(default=True)
|
enable_login_emails = models.BooleanField(default=True)
|
||||||
enable_marketing_emails = models.BooleanField(default=True)
|
enable_marketing_emails = models.BooleanField(default=True)
|
||||||
realm_name_in_notifications = models.BooleanField(default=False)
|
|
||||||
presence_enabled = models.BooleanField(default=True)
|
presence_enabled = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_AUTOMATIC = 1
|
||||||
|
REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_ALWAYS = 2
|
||||||
|
REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_NEVER = 3
|
||||||
|
REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_CHOICES = [
|
||||||
|
REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_AUTOMATIC,
|
||||||
|
REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_ALWAYS,
|
||||||
|
REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_NEVER,
|
||||||
|
]
|
||||||
|
realm_name_in_email_notifications_policy = models.PositiveSmallIntegerField(
|
||||||
|
default=REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_AUTOMATIC
|
||||||
|
)
|
||||||
|
|
||||||
# Whether or not the user wants to sync their drafts.
|
# Whether or not the user wants to sync their drafts.
|
||||||
enable_drafts_synchronization = models.BooleanField(default=True)
|
enable_drafts_synchronization = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
@ -1671,7 +1682,7 @@ class UserBaseSettings(models.Model):
|
||||||
notification_sound=str,
|
notification_sound=str,
|
||||||
pm_content_in_desktop_notifications=bool,
|
pm_content_in_desktop_notifications=bool,
|
||||||
presence_enabled=bool,
|
presence_enabled=bool,
|
||||||
realm_name_in_notifications=bool,
|
realm_name_in_email_notifications_policy=int,
|
||||||
wildcard_mentions_notify=bool,
|
wildcard_mentions_notify=bool,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -9126,13 +9126,25 @@ paths:
|
||||||
- 2
|
- 2
|
||||||
- 3
|
- 3
|
||||||
example: 1
|
example: 1
|
||||||
- name: realm_name_in_notifications
|
- name: realm_name_in_email_notifications_policy
|
||||||
in: query
|
in: query
|
||||||
description: |
|
description: |
|
||||||
Include organization name in subject of message notification emails.
|
Whether to [include organization name in subject of message notification emails](/help/email-notifications#include-organization-name-in-subject-line).
|
||||||
|
|
||||||
|
- 1 - Automatic
|
||||||
|
- 2 - Always
|
||||||
|
- 3 - Never
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 7.0 (feature level 168), replacing the
|
||||||
|
previous `realm_name_in_notifications` boolean;
|
||||||
|
`true` corresponded to `Always`, and `false` to `Never`.
|
||||||
schema:
|
schema:
|
||||||
type: boolean
|
type: integer
|
||||||
example: true
|
enum:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
- 3
|
||||||
|
example: 1
|
||||||
- name: presence_enabled
|
- name: presence_enabled
|
||||||
in: query
|
in: query
|
||||||
description: |
|
description: |
|
||||||
|
@ -11106,10 +11118,18 @@ paths:
|
||||||
- 1 - All unreads
|
- 1 - All unreads
|
||||||
- 2 - Private messages and mentions
|
- 2 - Private messages and mentions
|
||||||
- 3 - None
|
- 3 - None
|
||||||
realm_name_in_notifications:
|
realm_name_in_email_notifications_policy:
|
||||||
type: boolean
|
type: integer
|
||||||
description: |
|
description: |
|
||||||
Include organization name in subject of message notification emails.
|
Whether to [include organization name in subject of message notification emails](/help/email-notifications#include-organization-name-in-subject-line).
|
||||||
|
|
||||||
|
- 1 - Automatic
|
||||||
|
- 2 - Always
|
||||||
|
- 3 - Never
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 7.0 (feature level 168), replacing the
|
||||||
|
previous `realm_name_in_notifications` boolean;
|
||||||
|
`true` corresponded to `Always`, and `false` to `Never`.
|
||||||
presence_enabled:
|
presence_enabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: |
|
description: |
|
||||||
|
@ -11501,9 +11521,9 @@ paths:
|
||||||
**Changes**: Deprecated in Zulip 5.0 (feature level 89). Clients
|
**Changes**: Deprecated in Zulip 5.0 (feature level 89). Clients
|
||||||
connecting to newer servers should declare the `user_settings_object`
|
connecting to newer servers should declare the `user_settings_object`
|
||||||
client capability and access the `user_settings` object instead.
|
client capability and access the `user_settings` object instead.
|
||||||
realm_name_in_notifications:
|
realm_name_in_email_notifications_policy:
|
||||||
deprecated: true
|
deprecated: true
|
||||||
type: boolean
|
type: integer
|
||||||
description: |
|
description: |
|
||||||
Present if `update_global_notifications` is present in `fetch_event_types`
|
Present if `update_global_notifications` is present in `fetch_event_types`
|
||||||
and only for clients that did not include `user_settings_object` in their
|
and only for clients that did not include `user_settings_object` in their
|
||||||
|
@ -11513,8 +11533,12 @@ paths:
|
||||||
See [PATCH /settings](/api/update-settings) for details on
|
See [PATCH /settings](/api/update-settings) for details on
|
||||||
the meaning of this setting.
|
the meaning of this setting.
|
||||||
|
|
||||||
**Changes**: Deprecated in Zulip 5.0 (feature level 89). Clients
|
**Changes**: Deprecated `realm_name_in_notifications` in Zulip 5.0 (feature level 89).
|
||||||
connecting to newer servers should declare the `user_settings_object`
|
Replaced `realm_name_in_notifications` boolean with
|
||||||
|
`realm_name_in_email_notifications_policy` in Zulip 7.0 (feature level 168);
|
||||||
|
`true` corresponded to `Always`, and `false` to `Never`.
|
||||||
|
|
||||||
|
Clients connecting to newer servers should declare the `user_settings_object`
|
||||||
client capability and access the `user_settings` object instead.
|
client capability and access the `user_settings` object instead.
|
||||||
presence_enabled:
|
presence_enabled:
|
||||||
deprecated: true
|
deprecated: true
|
||||||
|
@ -13024,10 +13048,18 @@ paths:
|
||||||
- 1 - All unreads
|
- 1 - All unreads
|
||||||
- 2 - Private messages and mentions
|
- 2 - Private messages and mentions
|
||||||
- 3 - None
|
- 3 - None
|
||||||
realm_name_in_notifications:
|
realm_name_in_email_notifications_policy:
|
||||||
type: boolean
|
type: integer
|
||||||
description: |
|
description: |
|
||||||
Include organization name in subject of message notification emails.
|
Whether to [include organization name in subject of message notification emails](/help/email-notifications#include-organization-name-in-subject-line).
|
||||||
|
|
||||||
|
- 1 - Automatic
|
||||||
|
- 2 - Always
|
||||||
|
- 3 - Never
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 7.0 (feature level 168), replacing the
|
||||||
|
previous `realm_name_in_notifications` boolean;
|
||||||
|
`true` corresponded to `Always`, and `false` to `Never`.
|
||||||
presence_enabled:
|
presence_enabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: |
|
description: |
|
||||||
|
@ -14190,16 +14222,28 @@ paths:
|
||||||
- 2
|
- 2
|
||||||
- 3
|
- 3
|
||||||
example: 1
|
example: 1
|
||||||
- name: realm_name_in_notifications
|
- name: realm_name_in_email_notifications_policy
|
||||||
in: query
|
in: query
|
||||||
description: |
|
description: |
|
||||||
Include organization name in subject of message notification emails.
|
Whether to [include organization name in subject of message notification emails](/help/email-notifications#include-organization-name-in-subject-line).
|
||||||
|
|
||||||
**Changes**: Before Zulip 5.0 (feature level 80), this setting was managed by
|
- 1 - Automatic
|
||||||
the `PATCH /settings/notifications` endpoint.
|
- 2 - Always
|
||||||
|
- 3 - Never
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 7.0 (feature level 168), replacing the
|
||||||
|
previous `realm_name_in_notifications` boolean;
|
||||||
|
`true` corresponded to `Always`, and `false` to `Never`.
|
||||||
|
|
||||||
|
Before Zulip 5.0 (feature level 80), the previous `realm_name_in_notifications`
|
||||||
|
setting was managed by the `PATCH /settings/notifications` endpoint.
|
||||||
schema:
|
schema:
|
||||||
type: boolean
|
type: integer
|
||||||
example: true
|
enum:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
- 3
|
||||||
|
example: 1
|
||||||
- name: presence_enabled
|
- name: presence_enabled
|
||||||
in: query
|
in: query
|
||||||
description: |
|
description: |
|
||||||
|
|
|
@ -16,6 +16,7 @@ from django.test import override_settings
|
||||||
from django.utils.timezone import now as timezone_now
|
from django.utils.timezone import now as timezone_now
|
||||||
from django_auth_ldap.config import LDAPSearch
|
from django_auth_ldap.config import LDAPSearch
|
||||||
|
|
||||||
|
from zerver.actions.create_user import do_create_user
|
||||||
from zerver.actions.user_settings import do_change_user_setting
|
from zerver.actions.user_settings import do_change_user_setting
|
||||||
from zerver.actions.users import do_change_user_role
|
from zerver.actions.users import do_change_user_role
|
||||||
from zerver.lib.email_notifications import (
|
from zerver.lib.email_notifications import (
|
||||||
|
@ -24,6 +25,7 @@ from zerver.lib.email_notifications import (
|
||||||
fix_spoilers_in_html,
|
fix_spoilers_in_html,
|
||||||
followup_day2_email_delay,
|
followup_day2_email_delay,
|
||||||
handle_missedmessage_emails,
|
handle_missedmessage_emails,
|
||||||
|
include_realm_name_in_missedmessage_emails_subject,
|
||||||
relative_to_full_url,
|
relative_to_full_url,
|
||||||
)
|
)
|
||||||
from zerver.lib.send_email import FromAddress, deliver_scheduled_emails, send_custom_email
|
from zerver.lib.send_email import FromAddress, deliver_scheduled_emails, send_custom_email
|
||||||
|
@ -1001,18 +1003,80 @@ class TestMissedMessages(ZulipTestCase):
|
||||||
for text in expected_email_include:
|
for text in expected_email_include:
|
||||||
self.assertIn(text, self.normalize_string(mail.outbox[0].body))
|
self.assertIn(text, self.normalize_string(mail.outbox[0].body))
|
||||||
|
|
||||||
def test_realm_name_in_notifications(self) -> None:
|
def test_include_realm_name_in_missedmessage_emails_subject(self) -> None:
|
||||||
# Test with realm_name_in_notifications for hamlet disabled.
|
user = self.example_user("hamlet")
|
||||||
self._realm_name_in_missed_message_email_subject(False)
|
|
||||||
|
|
||||||
# Enable realm_name_in_notifications for hamlet and test again.
|
# Test with 'realm_name_in_notification_policy' set to 'Always'
|
||||||
|
do_change_user_setting(
|
||||||
|
user,
|
||||||
|
"realm_name_in_email_notifications_policy",
|
||||||
|
UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_ALWAYS,
|
||||||
|
acting_user=None,
|
||||||
|
)
|
||||||
|
self.assertTrue(include_realm_name_in_missedmessage_emails_subject(user))
|
||||||
|
|
||||||
|
# Test with 'realm_name_in_notification_policy' set to 'Never'
|
||||||
|
do_change_user_setting(
|
||||||
|
user,
|
||||||
|
"realm_name_in_email_notifications_policy",
|
||||||
|
UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_NEVER,
|
||||||
|
acting_user=None,
|
||||||
|
)
|
||||||
|
self.assertFalse(include_realm_name_in_missedmessage_emails_subject(user))
|
||||||
|
|
||||||
|
# Test with 'realm_name_in_notification_policy' set to 'Automatic'
|
||||||
|
do_change_user_setting(
|
||||||
|
user,
|
||||||
|
"realm_name_in_email_notifications_policy",
|
||||||
|
UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_AUTOMATIC,
|
||||||
|
acting_user=None,
|
||||||
|
)
|
||||||
|
# Case 1: if user is part of a single realm, then realm_name is not present in notifications.
|
||||||
|
self.assertFalse(include_realm_name_in_missedmessage_emails_subject(user))
|
||||||
|
|
||||||
|
# Case 2: if user is part of multiple realms, then realm_name should be present in notifications.
|
||||||
|
# Create and verify a cross realm user.
|
||||||
|
cross_realm_user = do_create_user(
|
||||||
|
user.delivery_email, None, get_realm("lear"), user.full_name, acting_user=None
|
||||||
|
)
|
||||||
|
self.assertEqual(cross_realm_user.delivery_email, user.delivery_email)
|
||||||
|
|
||||||
|
self.assertTrue(include_realm_name_in_missedmessage_emails_subject(cross_realm_user))
|
||||||
|
|
||||||
|
def test_realm_name_in_email_notifications_policy(self) -> None:
|
||||||
|
# Test with realm_name_in_email_notifications_policy set to Never.
|
||||||
hamlet = self.example_user("hamlet")
|
hamlet = self.example_user("hamlet")
|
||||||
hamlet.realm_name_in_notifications = True
|
hamlet.realm_name_in_email_notifications_policy = (
|
||||||
hamlet.save(update_fields=["realm_name_in_notifications"])
|
UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_NEVER
|
||||||
|
)
|
||||||
|
hamlet.save(update_fields=["realm_name_in_email_notifications_policy"])
|
||||||
|
with mock.patch(
|
||||||
|
"zerver.lib.email_notifications.include_realm_name_in_missedmessage_emails_subject",
|
||||||
|
return_value=False,
|
||||||
|
):
|
||||||
|
is_allowed = include_realm_name_in_missedmessage_emails_subject(hamlet)
|
||||||
|
self._realm_name_in_missed_message_email_subject(is_allowed)
|
||||||
|
|
||||||
# Empty the test outbox
|
# Test with realm_name_in_email_notifications_policy set to Always.
|
||||||
mail.outbox = []
|
|
||||||
self._realm_name_in_missed_message_email_subject(True)
|
# Note: We don't need to test separately for 'realm_name_in_email_notifications_policy'
|
||||||
|
# set to 'Automatic'.
|
||||||
|
# Here, we are concerned about the subject after the mocked function returns True/False.
|
||||||
|
# We already have separate test to check the appropriate behaviour of
|
||||||
|
# 'include_realm_name_in_missedmessage_emails_subject' for Automatic, Always, Never.
|
||||||
|
hamlet = self.example_user("hamlet")
|
||||||
|
hamlet.realm_name_in_email_notifications_policy = (
|
||||||
|
UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_ALWAYS
|
||||||
|
)
|
||||||
|
hamlet.save(update_fields=["realm_name_in_email_notifications_policy"])
|
||||||
|
with mock.patch(
|
||||||
|
"zerver.lib.email_notifications.include_realm_name_in_missedmessage_emails_subject",
|
||||||
|
return_value=True,
|
||||||
|
):
|
||||||
|
is_allowed = include_realm_name_in_missedmessage_emails_subject(hamlet)
|
||||||
|
# Empty the test outbox
|
||||||
|
mail.outbox = []
|
||||||
|
self._realm_name_in_missed_message_email_subject(is_allowed)
|
||||||
|
|
||||||
def test_message_content_disabled_in_missed_message_notifications(self) -> None:
|
def test_message_content_disabled_in_missed_message_notifications(self) -> None:
|
||||||
# Test when user disabled message content in email notifications.
|
# Test when user disabled message content in email notifications.
|
||||||
|
|
|
@ -1837,6 +1837,7 @@ class NormalActionsTest(BaseAction):
|
||||||
"notification_sound",
|
"notification_sound",
|
||||||
"desktop_icon_count_display",
|
"desktop_icon_count_display",
|
||||||
"presence_enabled",
|
"presence_enabled",
|
||||||
|
"realm_name_in_email_notifications_policy",
|
||||||
]:
|
]:
|
||||||
# These settings are tested in their own tests.
|
# These settings are tested in their own tests.
|
||||||
continue
|
continue
|
||||||
|
@ -1926,6 +1927,27 @@ class NormalActionsTest(BaseAction):
|
||||||
check_user_settings_update("events[0]", events[0])
|
check_user_settings_update("events[0]", events[0])
|
||||||
check_update_global_notifications("events[1]", events[1], 1)
|
check_update_global_notifications("events[1]", events[1], 1)
|
||||||
|
|
||||||
|
def test_change_realm_name_in_email_notifications_policy(self) -> None:
|
||||||
|
notification_setting = "realm_name_in_email_notifications_policy"
|
||||||
|
|
||||||
|
events = self.verify_action(
|
||||||
|
lambda: do_change_user_setting(
|
||||||
|
self.user_profile, notification_setting, 3, acting_user=self.user_profile
|
||||||
|
),
|
||||||
|
num_events=2,
|
||||||
|
)
|
||||||
|
check_user_settings_update("events[0]", events[0])
|
||||||
|
check_update_global_notifications("events[1]", events[1], 3)
|
||||||
|
|
||||||
|
events = self.verify_action(
|
||||||
|
lambda: do_change_user_setting(
|
||||||
|
self.user_profile, notification_setting, 2, acting_user=self.user_profile
|
||||||
|
),
|
||||||
|
num_events=2,
|
||||||
|
)
|
||||||
|
check_user_settings_update("events[0]", events[0])
|
||||||
|
check_update_global_notifications("events[1]", events[1], 2)
|
||||||
|
|
||||||
def test_realm_update_org_type(self) -> None:
|
def test_realm_update_org_type(self) -> None:
|
||||||
realm = self.user_profile.realm
|
realm = self.user_profile.realm
|
||||||
|
|
||||||
|
@ -2690,6 +2712,7 @@ class RealmPropertyActionTest(BaseAction):
|
||||||
notification_sound=["zulip", "ding"],
|
notification_sound=["zulip", "ding"],
|
||||||
email_notifications_batching_period_seconds=[120, 300],
|
email_notifications_batching_period_seconds=[120, 300],
|
||||||
email_address_visibility=UserProfile.EMAIL_ADDRESS_VISIBILITY_TYPES,
|
email_address_visibility=UserProfile.EMAIL_ADDRESS_VISIBILITY_TYPES,
|
||||||
|
realm_name_in_email_notifications_policy=UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_CHOICES,
|
||||||
)
|
)
|
||||||
|
|
||||||
vals = test_values.get(name)
|
vals = test_values.get(name)
|
||||||
|
|
|
@ -1244,6 +1244,7 @@ class RealmAPITest(ZulipTestCase):
|
||||||
notification_sound=["zulip", "ding"],
|
notification_sound=["zulip", "ding"],
|
||||||
email_notifications_batching_period_seconds=[120, 300],
|
email_notifications_batching_period_seconds=[120, 300],
|
||||||
email_address_visibility=UserProfile.EMAIL_ADDRESS_VISIBILITY_TYPES,
|
email_address_visibility=UserProfile.EMAIL_ADDRESS_VISIBILITY_TYPES,
|
||||||
|
realm_name_in_email_notifications_policy=UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_CHOICES,
|
||||||
)
|
)
|
||||||
|
|
||||||
vals = test_values.get(name)
|
vals = test_values.get(name)
|
||||||
|
|
|
@ -362,6 +362,7 @@ class ChangeSettingsTest(ZulipTestCase):
|
||||||
notification_sound="ding",
|
notification_sound="ding",
|
||||||
desktop_icon_count_display=2,
|
desktop_icon_count_display=2,
|
||||||
email_address_visibility=3,
|
email_address_visibility=3,
|
||||||
|
realm_name_in_email_notifications_policy=2,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.login("hamlet")
|
self.login("hamlet")
|
||||||
|
|
|
@ -453,7 +453,10 @@ def update_realm_user_settings_defaults(
|
||||||
desktop_icon_count_display: Optional[int] = REQ(
|
desktop_icon_count_display: Optional[int] = REQ(
|
||||||
json_validator=check_int_in(UserProfile.DESKTOP_ICON_COUNT_DISPLAY_CHOICES), default=None
|
json_validator=check_int_in(UserProfile.DESKTOP_ICON_COUNT_DISPLAY_CHOICES), default=None
|
||||||
),
|
),
|
||||||
realm_name_in_notifications: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
realm_name_in_email_notifications_policy: Optional[int] = REQ(
|
||||||
|
json_validator=check_int_in(UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_CHOICES),
|
||||||
|
default=None,
|
||||||
|
),
|
||||||
presence_enabled: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
presence_enabled: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||||
enter_sends: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
enter_sends: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||||
enable_drafts_synchronization: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
enable_drafts_synchronization: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||||
|
|
|
@ -211,7 +211,10 @@ def json_change_settings(
|
||||||
desktop_icon_count_display: Optional[int] = REQ(
|
desktop_icon_count_display: Optional[int] = REQ(
|
||||||
json_validator=check_int_in(UserProfile.DESKTOP_ICON_COUNT_DISPLAY_CHOICES), default=None
|
json_validator=check_int_in(UserProfile.DESKTOP_ICON_COUNT_DISPLAY_CHOICES), default=None
|
||||||
),
|
),
|
||||||
realm_name_in_notifications: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
realm_name_in_email_notifications_policy: Optional[int] = REQ(
|
||||||
|
json_validator=check_int_in(UserProfile.REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY_CHOICES),
|
||||||
|
default=None,
|
||||||
|
),
|
||||||
presence_enabled: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
presence_enabled: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||||
enter_sends: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
enter_sends: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||||
send_private_typing_notifications: Optional[bool] = REQ(
|
send_private_typing_notifications: Optional[bool] = REQ(
|
||||||
|
|
Loading…
Reference in New Issue