settings: Rename notifications_stream to new_stream_announce..._stream.

This commit renames the realm-level setting 'notifications_stream'
to 'new_stream_announcements_stream'.

The new name reflects better what the setting does.
This commit is contained in:
Prakhar Pratyush 2024-02-07 16:43:02 +05:30 committed by Tim Abbott
parent 0c83bca81e
commit ab453fbe20
40 changed files with 254 additions and 195 deletions

View File

@ -20,6 +20,12 @@ format used by the Zulip server that they are interacting with.
## Changes in Zulip 9.0 ## Changes in Zulip 9.0
**Feature level 241**
* [`POST /register`](/api/register-queue), [`POST /events`](/api/get-events),
`PATCH /realm`: Renamed the realm setting `notifications_stream`
to `new_stream_announcements_stream`.
**Feature level 240** **Feature level 240**
* [`GET /events`](/api/get-events): The `restart` event no longer contains an * [`GET /events`](/api/get-events): The `restart` event no longer contains an

View File

@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.9.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 = 240 API_FEATURE_LEVEL = 241
# 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

View File

@ -4,7 +4,7 @@ import type {Page} from "puppeteer";
import * as common from "./lib/common"; import * as common from "./lib/common";
async function submit_notifications_stream_settings(page: Page): Promise<void> { async function submit_announcements_stream_settings(page: Page): Promise<void> {
await page.waitForSelector('#org-notifications .save-button[data-status="unsaved"]', { await page.waitForSelector('#org-notifications .save-button[data-status="unsaved"]', {
visible: true, visible: true,
}); });
@ -29,8 +29,8 @@ async function submit_notifications_stream_settings(page: Page): Promise<void> {
await page.waitForSelector("#org-notifications .save-button", {hidden: true}); await page.waitForSelector("#org-notifications .save-button", {hidden: true});
} }
async function test_change_new_stream_notifications_setting(page: Page): Promise<void> { async function test_change_new_stream_announcements_stream(page: Page): Promise<void> {
await page.click("#realm_notifications_stream_id_widget.dropdown-widget-button"); await page.click("#realm_new_stream_announcements_stream_id_widget.dropdown-widget-button");
await page.waitForSelector(".dropdown-list-container", { await page.waitForSelector(".dropdown-list-container", {
visible: true, visible: true,
}); });
@ -44,7 +44,7 @@ async function test_change_new_stream_notifications_setting(page: Page): Promise
assert.ok(rome_in_dropdown); assert.ok(rome_in_dropdown);
await rome_in_dropdown.click(); await rome_in_dropdown.click();
await submit_notifications_stream_settings(page); await submit_announcements_stream_settings(page);
} }
async function test_change_signup_notifications_stream(page: Page): Promise<void> { async function test_change_signup_notifications_stream(page: Page): Promise<void> {
@ -57,7 +57,7 @@ async function test_change_signup_notifications_stream(page: Page): Promise<void
await page.waitForSelector(".dropdown-list .list-item", {visible: true}); await page.waitForSelector(".dropdown-list .list-item", {visible: true});
await page.keyboard.press("ArrowDown"); await page.keyboard.press("ArrowDown");
await page.keyboard.press("Enter"); await page.keyboard.press("Enter");
await submit_notifications_stream_settings(page); await submit_announcements_stream_settings(page);
} }
async function test_permissions_change_save_worked(page: Page): Promise<void> { async function test_permissions_change_save_worked(page: Page): Promise<void> {
@ -263,7 +263,7 @@ async function admin_test(page: Page): Promise<void> {
await common.log_in(page); await common.log_in(page);
await common.manage_organization(page); await common.manage_organization(page);
await test_change_new_stream_notifications_setting(page); await test_change_new_stream_announcements_stream(page);
await test_change_signup_notifications_stream(page); await test_change_signup_notifications_stream(page);
await test_organization_permissions(page); await test_organization_permissions(page);

View File

@ -30,7 +30,7 @@ const admin_settings_label = {
// Organization settings // Organization settings
realm_allow_edit_history: $t({defaultMessage: "Enable message edit history"}), realm_allow_edit_history: $t({defaultMessage: "Enable message edit history"}),
realm_mandatory_topics: $t({defaultMessage: "Require topics in stream messages"}), realm_mandatory_topics: $t({defaultMessage: "Require topics in stream messages"}),
realm_notifications_stream: $t({defaultMessage: "New stream announcements"}), realm_new_stream_announcements_stream: $t({defaultMessage: "New stream announcements"}),
realm_signup_notifications_stream: $t({defaultMessage: "New user announcements"}), realm_signup_notifications_stream: $t({defaultMessage: "New user announcements"}),
realm_inline_image_preview: $t({ realm_inline_image_preview: $t({
defaultMessage: "Show previews of uploaded and linked images and videos", defaultMessage: "Show previews of uploaded and linked images and videos",
@ -137,7 +137,7 @@ export function build_page() {
realm_default_language_name: get_language_name(realm.realm_default_language), realm_default_language_name: get_language_name(realm.realm_default_language),
realm_default_language_code: realm.realm_default_language, realm_default_language_code: realm.realm_default_language,
realm_waiting_period_threshold: realm.realm_waiting_period_threshold, realm_waiting_period_threshold: realm.realm_waiting_period_threshold,
realm_notifications_stream_id: realm.realm_notifications_stream_id, realm_new_stream_announcements_stream_id: realm.realm_new_stream_announcements_stream_id,
realm_signup_notifications_stream_id: realm.realm_signup_notifications_stream_id, realm_signup_notifications_stream_id: realm.realm_signup_notifications_stream_id,
is_admin: current_user.is_admin, is_admin: current_user.is_admin,
is_guest: current_user.is_guest, is_guest: current_user.is_guest,

View File

@ -318,7 +318,7 @@ function open_invite_user_modal(e: JQuery.ClickEvent<Document, undefined>): void
expires_in_options: settings_config.expires_in_values, expires_in_options: settings_config.expires_in_values,
time_choices: time_unit_choices, time_choices: time_unit_choices,
streams: get_invite_streams(), streams: get_invite_streams(),
notifications_stream: stream_data.get_notifications_stream(), new_stream_announcements_stream: stream_data.get_new_stream_announcements_stream(),
show_select_default_streams_option: stream_data.get_default_stream_ids().length !== 0, show_select_default_streams_option: stream_data.get_default_stream_ids().length !== 0,
user_has_email_set: !settings_data.user_email_not_configured(), user_has_email_set: !settings_data.user_email_not_configured(),
}); });

View File

@ -233,7 +233,7 @@ export function dispatch_normal_event(event) {
move_messages_between_streams_policy: noop, move_messages_between_streams_policy: noop,
name: narrow_title.redraw_title, name: narrow_title.redraw_title,
name_changes_disabled: settings_account.update_name_change_display, name_changes_disabled: settings_account.update_name_change_display,
notifications_stream_id: stream_ui_updates.update_announce_stream_option, new_stream_announcements_stream_id: stream_ui_updates.update_announce_stream_option,
org_type: noop, org_type: noop,
private_message_policy: compose_recipient.check_posting_policy_for_compose_box, private_message_policy: compose_recipient.check_posting_policy_for_compose_box,
push_notifications_enabled: noop, push_notifications_enabled: noop,
@ -560,9 +560,9 @@ export function dispatch_normal_event(event) {
} }
settings_streams.update_default_streams_table(); settings_streams.update_default_streams_table();
stream_data.remove_default_stream(stream.stream_id); stream_data.remove_default_stream(stream.stream_id);
if (realm.realm_notifications_stream_id === stream.stream_id) { if (realm.realm_new_stream_announcements_stream_id === stream.stream_id) {
realm.realm_notifications_stream_id = -1; realm.realm_new_stream_announcements_stream_id = -1;
settings_org.sync_realm_settings("notifications_stream_id"); settings_org.sync_realm_settings("new_stream_announcements_stream_id");
} }
if (realm.realm_signup_notifications_stream_id === stream.stream_id) { if (realm.realm_signup_notifications_stream_id === stream.stream_id) {
realm.realm_signup_notifications_stream_id = -1; realm.realm_signup_notifications_stream_id = -1;

View File

@ -239,7 +239,7 @@ export function sort_object_by_key(obj) {
} }
export let default_code_language_widget = null; export let default_code_language_widget = null;
export let notifications_stream_widget = null; export let new_stream_announcements_stream_widget = null;
export let signup_notifications_stream_widget = null; export let signup_notifications_stream_widget = null;
export let create_multiuse_invite_group_widget = null; export let create_multiuse_invite_group_widget = null;
export let can_remove_subscribers_group_widget = null; export let can_remove_subscribers_group_widget = null;
@ -249,8 +249,8 @@ export let new_group_can_mention_group_widget = null;
export function get_widget_for_dropdown_list_settings(property_name) { export function get_widget_for_dropdown_list_settings(property_name) {
switch (property_name) { switch (property_name) {
case "realm_notifications_stream_id": case "realm_new_stream_announcements_stream_id":
return notifications_stream_widget; return new_stream_announcements_stream_widget;
case "realm_signup_notifications_stream_id": case "realm_signup_notifications_stream_id":
return signup_notifications_stream_widget; return signup_notifications_stream_widget;
case "realm_default_code_block_language": case "realm_default_code_block_language":
@ -273,8 +273,8 @@ export function set_default_code_language_widget(widget) {
default_code_language_widget = widget; default_code_language_widget = widget;
} }
export function set_notifications_stream_widget(widget) { export function set_new_stream_announcements_stream_widget(widget) {
notifications_stream_widget = widget; new_stream_announcements_stream_widget = widget;
} }
export function set_signup_notifications_stream_widget(widget) { export function set_signup_notifications_stream_widget(widget) {
@ -504,7 +504,7 @@ export function check_property_changed(elem, for_realm_default_settings, sub, gr
proposed_val = get_auth_method_list_data(); proposed_val = get_auth_method_list_data();
proposed_val = JSON.stringify(proposed_val); proposed_val = JSON.stringify(proposed_val);
break; break;
case "realm_notifications_stream_id": case "realm_new_stream_announcements_stream_id":
case "realm_signup_notifications_stream_id": case "realm_signup_notifications_stream_id":
case "realm_default_code_block_language": case "realm_default_code_block_language":
case "can_remove_subscribers_group": case "can_remove_subscribers_group":

View File

@ -474,7 +474,7 @@ export function discard_property_element_changes(elem, for_realm_default_setting
case "realm_authentication_methods": case "realm_authentication_methods":
populate_auth_methods(property_value); populate_auth_methods(property_value);
break; break;
case "realm_notifications_stream_id": case "realm_new_stream_announcements_stream_id":
case "realm_signup_notifications_stream_id": case "realm_signup_notifications_stream_id":
case "realm_default_code_block_language": case "realm_default_code_block_language":
case "can_remove_subscribers_group": case "can_remove_subscribers_group":
@ -637,26 +637,28 @@ export function init_dropdown_widgets() {
return options; return options;
}; };
const notifications_stream_widget = new dropdown_widget.DropdownWidget({ const new_stream_announcements_stream_widget = new dropdown_widget.DropdownWidget({
widget_name: "realm_notifications_stream_id", widget_name: "realm_new_stream_announcements_stream_id",
get_options: notification_stream_options, get_options: notification_stream_options,
$events_container: $("#settings_overlay_container #organization-settings"), $events_container: $("#settings_overlay_container #organization-settings"),
item_click_callback(event, dropdown) { item_click_callback(event, dropdown) {
dropdown.hide(); dropdown.hide();
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
settings_components.notifications_stream_widget.render(); settings_components.new_stream_announcements_stream_widget.render();
settings_components.save_discard_widget_status_handler($("#org-notifications")); settings_components.save_discard_widget_status_handler($("#org-notifications"));
}, },
tippy_props: { tippy_props: {
placement: "bottom-start", placement: "bottom-start",
}, },
default_id: realm.realm_notifications_stream_id, default_id: realm.realm_new_stream_announcements_stream_id,
unique_id_type: dropdown_widget.DATA_TYPES.NUMBER, unique_id_type: dropdown_widget.DATA_TYPES.NUMBER,
text_if_current_value_not_in_options: $t({defaultMessage: "Cannot view stream"}), text_if_current_value_not_in_options: $t({defaultMessage: "Cannot view stream"}),
}); });
settings_components.set_notifications_stream_widget(notifications_stream_widget); settings_components.set_new_stream_announcements_stream_widget(
notifications_stream_widget.setup(); new_stream_announcements_stream_widget,
);
new_stream_announcements_stream_widget.setup();
const signup_notifications_stream_widget = new dropdown_widget.DropdownWidget({ const signup_notifications_stream_widget = new dropdown_widget.DropdownWidget({
widget_name: "realm_signup_notifications_stream_id", widget_name: "realm_signup_notifications_stream_id",

View File

@ -96,9 +96,9 @@ export const realm_schema = z.object({
realm_move_messages_between_streams_policy: z.number(), realm_move_messages_between_streams_policy: z.number(),
realm_name_changes_disabled: z.boolean(), realm_name_changes_disabled: z.boolean(),
realm_name: z.string(), realm_name: z.string(),
realm_new_stream_announcements_stream_id: z.number(),
realm_night_logo_source: z.string(), realm_night_logo_source: z.string(),
realm_night_logo_url: z.string(), realm_night_logo_url: z.string(),
realm_notifications_stream_id: z.number(),
realm_org_type: z.number(), realm_org_type: z.number(),
realm_plan_type: z.number(), realm_plan_type: z.number(),
realm_private_message_policy: z.number(), realm_private_message_policy: z.number(),

View File

@ -121,8 +121,8 @@ let stream_announce_previous_value;
// Within the new stream modal... // Within the new stream modal...
function update_announce_stream_state() { function update_announce_stream_state() {
// If there is no notifications_stream, we simply hide the widget. // If there is no new_stream_announcements_stream, we simply hide the widget.
if (stream_data.get_notifications_stream() === "") { if (stream_data.get_new_stream_announcements_stream() === "") {
$("#announce-new-stream").hide(); $("#announce-new-stream").hide();
return; return;
} }
@ -238,12 +238,12 @@ function create_stream() {
data.message_retention_days = JSON.stringify(message_retention_selection); data.message_retention_days = JSON.stringify(message_retention_selection);
let announce = let announce =
stream_data.get_notifications_stream() !== "" && stream_data.get_new_stream_announcements_stream() !== "" &&
$("#announce-new-stream input").prop("checked"); $("#announce-new-stream input").prop("checked");
if ( if (
stream_data.get_notifications_stream() === "" && stream_data.get_new_stream_announcements_stream() === "" &&
stream_data.realm_has_notifications_stream() && stream_data.realm_has_new_stream_announcements_stream() &&
!invite_only !invite_only
) { ) {
announce = true; announce = true;
@ -449,7 +449,8 @@ export function set_up_handlers() {
content: () => content: () =>
parse_html( parse_html(
render_announce_stream_docs({ render_announce_stream_docs({
notifications_stream: stream_data.get_notifications_stream(), new_stream_announcements_stream:
stream_data.get_new_stream_announcements_stream(),
}), }),
), ),
}); });

View File

@ -483,8 +483,8 @@ export function is_stream_muted_by_name(stream_name: string): boolean {
return sub.is_muted; return sub.is_muted;
} }
export function is_notifications_stream_muted(): boolean { export function is_new_stream_announcements_stream_muted(): boolean {
return is_muted(realm.realm_notifications_stream_id); return is_muted(realm.realm_new_stream_announcements_stream_id);
} }
export function can_toggle_subscription(sub: StreamSubscription): boolean { export function can_toggle_subscription(sub: StreamSubscription): boolean {
@ -808,12 +808,12 @@ export function get_streams_for_admin(): StreamSubscription[] {
is the authoritative source of this data, and it will be updated by is the authoritative source of this data, and it will be updated by
server_events_dispatch in case of changes. server_events_dispatch in case of changes.
*/ */
export function realm_has_notifications_stream(): boolean { export function realm_has_new_stream_announcements_stream(): boolean {
return realm.realm_notifications_stream_id !== -1; return realm.realm_new_stream_announcements_stream_id !== -1;
} }
export function get_notifications_stream(): string { export function get_new_stream_announcements_stream(): string {
const stream_id = realm.realm_notifications_stream_id; const stream_id = realm.realm_new_stream_announcements_stream_id;
if (stream_id !== -1) { if (stream_id !== -1) {
const stream_obj = sub_store.get(stream_id); const stream_obj = sub_store.get(stream_id);
if (stream_obj) { if (stream_obj) {

View File

@ -606,17 +606,18 @@ export function initialize() {
const stream_name_with_privacy_symbol_html = render_inline_decorated_stream_name({stream}); const stream_name_with_privacy_symbol_html = render_inline_decorated_stream_name({stream});
const is_new_stream_notification_stream = stream_id === realm.realm_notifications_stream_id; const is_new_stream_announcements_stream =
stream_id === realm.realm_new_stream_announcements_stream_id;
const is_signup_notification_stream = const is_signup_notification_stream =
stream_id === realm.realm_signup_notifications_stream_id; stream_id === realm.realm_signup_notifications_stream_id;
const is_notification_stream = const is_announcement_stream =
is_new_stream_notification_stream || is_signup_notification_stream; is_new_stream_announcements_stream || is_signup_notification_stream;
const html_body = render_settings_deactivation_stream_modal({ const html_body = render_settings_deactivation_stream_modal({
stream_name_with_privacy_symbol_html, stream_name_with_privacy_symbol_html,
is_new_stream_notification_stream, is_new_stream_announcements_stream,
is_signup_notification_stream, is_signup_notification_stream,
is_notification_stream, is_announcement_stream,
}); });
confirm_dialog.launch({ confirm_dialog.launch({

View File

@ -596,11 +596,13 @@ export function setup_page(callback) {
// TODO: Ideally we'd indicate in some way what stream types // TODO: Ideally we'd indicate in some way what stream types
// the user can create, by showing other options as disabled. // the user can create, by showing other options as disabled.
const stream_privacy_policy = settings_config.stream_privacy_policy_values.public.code; const stream_privacy_policy = settings_config.stream_privacy_policy_values.public.code;
const notifications_stream = stream_data.get_notifications_stream(); const new_stream_announcements_stream = stream_data.get_new_stream_announcements_stream();
const notifications_stream_sub = stream_data.get_sub_by_name(notifications_stream); const new_stream_announcements_stream_sub = stream_data.get_sub_by_name(
new_stream_announcements_stream,
);
const template_data = { const template_data = {
notifications_stream_sub, new_stream_announcements_stream_sub,
ask_to_announce_stream: true, ask_to_announce_stream: true,
can_create_streams: can_create_streams:
settings_data.user_can_create_private_streams() || settings_data.user_can_create_private_streams() ||

View File

@ -283,16 +283,18 @@ export function update_announce_stream_option() {
if (!hash_parser.is_create_new_stream_narrow()) { if (!hash_parser.is_create_new_stream_narrow()) {
return; return;
} }
if (stream_data.get_notifications_stream() === "") { if (stream_data.get_new_stream_announcements_stream() === "") {
$("#announce-new-stream").hide(); $("#announce-new-stream").hide();
return; return;
} }
$("#announce-new-stream").show(); $("#announce-new-stream").show();
const notifications_stream = stream_data.get_notifications_stream(); const new_stream_announcements_stream = stream_data.get_new_stream_announcements_stream();
const notifications_stream_sub = stream_data.get_sub_by_name(notifications_stream); const new_stream_announcements_stream_sub = stream_data.get_sub_by_name(
new_stream_announcements_stream,
);
const rendered_announce_stream = render_announce_stream_checkbox({ const rendered_announce_stream = render_announce_stream_checkbox({
notifications_stream_sub, new_stream_announcements_stream_sub,
}); });
$("#announce-new-stream").expectOne().html(rendered_announce_stream); $("#announce-new-stream").expectOne().html(rendered_announce_stream);
} }

View File

@ -585,9 +585,9 @@ export function initialize_everything(state_data) {
"realm_move_messages_within_stream_limit_seconds", "realm_move_messages_within_stream_limit_seconds",
"realm_name", "realm_name",
"realm_name_changes_disabled", "realm_name_changes_disabled",
"realm_new_stream_announcements_stream_id",
"realm_night_logo_source", "realm_night_logo_source",
"realm_night_logo_url", "realm_night_logo_url",
"realm_notifications_stream_id",
"realm_org_type", "realm_org_type",
"realm_password_auth_enabled", "realm_password_auth_enabled",
"realm_plan_type", "realm_plan_type",

View File

@ -2,7 +2,7 @@
<div> <div>
{{#tr}} {{#tr}}
<p>Stream will be announced in <b>#{notifications_stream}</b>.</p> <p>Stream will be announced in <b>#{new_stream_announcements_stream}</b>.</p>
{{/tr}} {{/tr}}
<p>{{t 'Organization administrators can change the announcement stream in the organization settings.' }}</p> <p>{{t 'Organization administrators can change the announcement stream in the organization settings.' }}</p>

View File

@ -4,10 +4,10 @@
{{#*inline "z-stream"}}<strong>{{{stream_name_with_privacy_symbol_html}}}</strong>{{/inline}} {{#*inline "z-stream"}}<strong>{{{stream_name_with_privacy_symbol_html}}}</strong>{{/inline}}
{{/tr}} {{/tr}}
</p> </p>
{{#if is_notification_stream}} {{#if is_announcement_stream}}
<p class="notification_stream_archive_warning">{{#tr}}Archiving this stream will also disable settings that were configured to use this stream:{{/tr}}</p> <p class="notification_stream_archive_warning">{{#tr}}Archiving this stream will also disable settings that were configured to use this stream:{{/tr}}</p>
<ul> <ul>
{{#if is_new_stream_notification_stream}} {{#if is_new_stream_announcements_stream}}
<li>{{#tr}}New stream notifications{{/tr}}</li> <li>{{#tr}}New stream notifications{{/tr}}</li>
{{/if}} {{/if}}
{{#if is_signup_notification_stream}} {{#if is_signup_notification_stream}}

View File

@ -94,7 +94,7 @@
{{else}} {{else}}
#{{name}} #{{name}}
{{/if}} {{/if}}
{{#if (eq name ../notifications_stream)}} {{#if (eq name ../new_stream_announcements_stream)}}
<i>({{t 'Receives new stream announcements' }})</i> <i>({{t 'Receives new stream announcements' }})</i>
{{/if}} {{/if}}
</label> </label>

View File

@ -17,8 +17,8 @@
</div> </div>
{{> ../dropdown_widget_with_label {{> ../dropdown_widget_with_label
widget_name="realm_notifications_stream_id" widget_name="realm_new_stream_announcements_stream_id"
label=admin_settings_label.realm_notifications_stream label=admin_settings_label.realm_new_stream_announcements_stream
value_type="number"}} value_type="number"}}
{{> ../dropdown_widget_with_label {{> ../dropdown_widget_with_label

View File

@ -2,10 +2,10 @@
<input type="checkbox" name="announce" value="announce" checked /> <input type="checkbox" name="announce" value="announce" checked />
<span></span> <span></span>
{{t "Announce new stream in"}} {{t "Announce new stream in"}}
{{#if notifications_stream_sub}} {{#if new_stream_announcements_stream_sub}}
<strong> <strong>
{{> ../inline_decorated_stream_name {{> ../inline_decorated_stream_name
stream=notifications_stream_sub stream=new_stream_announcements_stream_sub
}} }}
</strong> </strong>
{{/if}} {{/if}}

View File

@ -527,10 +527,10 @@ run_test("realm settings", ({override}) => {
event = event_fixtures.realm__update__disallow_disposable_email_addresses; event = event_fixtures.realm__update__disallow_disposable_email_addresses;
test_realm_boolean(event, "realm_disallow_disposable_email_addresses"); test_realm_boolean(event, "realm_disallow_disposable_email_addresses");
event = event_fixtures.realm__update__notifications_stream_id; event = event_fixtures.realm__update__new_stream_announcements_stream_id;
dispatch(event); dispatch(event);
assert_same(realm.realm_notifications_stream_id, 42); assert_same(realm.realm_new_stream_announcements_stream_id, 42);
realm.realm_notifications_stream_id = -1; // make sure to reset for future tests realm.realm_new_stream_announcements_stream_id = -1; // make sure to reset for future tests
event = event_fixtures.realm__update__signup_notifications_stream_id; event = event_fixtures.realm__update__signup_notifications_stream_id;
dispatch(event); dispatch(event);

View File

@ -241,7 +241,7 @@ test("stream delete (special streams)", ({override}) => {
// sanity check data // sanity check data
assert.equal(event.streams.length, 2); assert.equal(event.streams.length, 2);
realm.realm_notifications_stream_id = event.streams[0].stream_id; realm.realm_new_stream_announcements_stream_id = event.streams[0].stream_id;
realm.realm_signup_notifications_stream_id = event.streams[1].stream_id; realm.realm_signup_notifications_stream_id = event.streams[1].stream_id;
override(stream_settings_ui, "remove_stream", noop); override(stream_settings_ui, "remove_stream", noop);
@ -253,7 +253,7 @@ test("stream delete (special streams)", ({override}) => {
dispatch(event); dispatch(event);
assert.equal(realm.realm_notifications_stream_id, -1); assert.equal(realm.realm_new_stream_announcements_stream_id, -1);
assert.equal(realm.realm_signup_notifications_stream_id, -1); assert.equal(realm.realm_signup_notifications_stream_id, -1);
}); });

View File

@ -344,10 +344,10 @@ exports.fixtures = {
value: "new_realm_name", value: "new_realm_name",
}, },
realm__update__notifications_stream_id: { realm__update__new_stream_announcements_stream_id: {
type: "realm", type: "realm",
op: "update", op: "update",
property: "notifications_stream_id", property: "new_stream_announcements_stream_id",
value: 42, value: 42,
}, },

View File

@ -689,15 +689,15 @@ test("is_muted", () => {
assert.ok(stream_data.is_stream_muted_by_name("EEXISTS")); assert.ok(stream_data.is_stream_muted_by_name("EEXISTS"));
}); });
test("is_notifications_stream_muted", () => { test("is_new_stream_announcements_stream_muted", () => {
stream_data.add_sub(tony); stream_data.add_sub(tony);
stream_data.add_sub(jazy); stream_data.add_sub(jazy);
realm.realm_notifications_stream_id = tony.stream_id; realm.realm_new_stream_announcements_stream_id = tony.stream_id;
assert.ok(!stream_data.is_notifications_stream_muted()); assert.ok(!stream_data.is_new_stream_announcements_stream_muted());
realm.realm_notifications_stream_id = jazy.stream_id; realm.realm_new_stream_announcements_stream_id = jazy.stream_id;
assert.ok(stream_data.is_notifications_stream_muted()); assert.ok(stream_data.is_new_stream_announcements_stream_muted());
}); });
test("muted_stream_ids", () => { test("muted_stream_ids", () => {
@ -746,11 +746,11 @@ test("muted_stream_ids", () => {
assert.deepEqual(stream_data.muted_stream_ids(), [1, 3]); assert.deepEqual(stream_data.muted_stream_ids(), [1, 3]);
}); });
test("realm_has_notifications_stream", () => { test("realm_has_new_stream_announcements_stream", () => {
realm.realm_notifications_stream_id = 10; realm.realm_new_stream_announcements_stream_id = 10;
assert.ok(stream_data.realm_has_notifications_stream()); assert.ok(stream_data.realm_has_new_stream_announcements_stream());
realm.realm_notifications_stream_id = -1; realm.realm_new_stream_announcements_stream_id = -1;
assert.ok(!stream_data.realm_has_notifications_stream()); assert.ok(!stream_data.realm_has_new_stream_announcements_stream());
}); });
test("remove_default_stream", () => { test("remove_default_stream", () => {
@ -843,7 +843,7 @@ test("initialize", () => {
stream_data.initialize(get_params()); stream_data.initialize(get_params());
} }
realm.realm_notifications_stream_id = -1; realm.realm_new_stream_announcements_stream_id = -1;
initialize(); initialize();
@ -851,12 +851,12 @@ test("initialize", () => {
assert.ok(stream_names.has("subscriptions")); assert.ok(stream_names.has("subscriptions"));
assert.ok(stream_names.has("unsubscribed")); assert.ok(stream_names.has("unsubscribed"));
assert.ok(stream_names.has("never_subscribed")); assert.ok(stream_names.has("never_subscribed"));
assert.equal(stream_data.get_notifications_stream(), ""); assert.equal(stream_data.get_new_stream_announcements_stream(), "");
// Simulate a private stream the user isn't subscribed to // Simulate a private stream the user isn't subscribed to
realm.realm_notifications_stream_id = 89; realm.realm_new_stream_announcements_stream_id = 89;
initialize(); initialize();
assert.equal(stream_data.get_notifications_stream(), ""); assert.equal(stream_data.get_new_stream_announcements_stream(), "");
// Now actually subscribe the user to the stream // Now actually subscribe the user to the stream
initialize(); initialize();
@ -867,7 +867,7 @@ test("initialize", () => {
stream_data.add_sub(foo); stream_data.add_sub(foo);
initialize(); initialize();
assert.equal(stream_data.get_notifications_stream(), "foo"); assert.equal(stream_data.get_new_stream_announcements_stream(), "foo");
}); });
test("edge_cases", () => { test("edge_cases", () => {

View File

@ -272,17 +272,17 @@ def do_create_realm(
maybe_enqueue_audit_log_upload(realm) maybe_enqueue_audit_log_upload(realm)
# Create stream once Realm object has been saved # Create stream once Realm object has been saved
notifications_stream = ensure_stream( new_stream_announcements_stream = ensure_stream(
realm, realm,
Realm.DEFAULT_NOTIFICATION_STREAM_NAME, Realm.DEFAULT_NOTIFICATION_STREAM_NAME,
stream_description="Everyone is added to this stream by default. Welcome! :octopus:", stream_description="Everyone is added to this stream by default. Welcome! :octopus:",
acting_user=None, acting_user=None,
) )
realm.notifications_stream = notifications_stream realm.new_stream_announcements_stream = new_stream_announcements_stream
# With the current initial streams situation, the only public # With the current initial streams situation, the only public
# stream is the notifications_stream. # stream is the new_stream_announcements_stream.
DefaultStream.objects.create(stream=notifications_stream, realm=realm) DefaultStream.objects.create(stream=new_stream_announcements_stream, realm=realm)
signup_notifications_stream = ensure_stream( signup_notifications_stream = ensure_stream(
realm, realm,
@ -293,7 +293,7 @@ def do_create_realm(
) )
realm.signup_notifications_stream = signup_notifications_stream realm.signup_notifications_stream = signup_notifications_stream
realm.save(update_fields=["notifications_stream", "signup_notifications_stream"]) realm.save(update_fields=["new_stream_announcements_stream", "signup_notifications_stream"])
if plan_type is None and settings.BILLING_ENABLED: if plan_type is None and settings.BILLING_ENABLED:
# We use acting_user=None for setting the initial plan type. # We use acting_user=None for setting the initial plan type.

View File

@ -260,7 +260,7 @@ def do_set_realm_authentication_methods(
def do_set_realm_stream( def do_set_realm_stream(
realm: Realm, realm: Realm,
field: Literal["notifications_stream", "signup_notifications_stream"], field: Literal["new_stream_announcements_stream", "signup_notifications_stream"],
stream: Optional[Stream], stream: Optional[Stream],
stream_id: int, stream_id: int,
*, *,
@ -268,10 +268,10 @@ def do_set_realm_stream(
) -> None: ) -> None:
# We could calculate more of these variables from `field`, but # We could calculate more of these variables from `field`, but
# it's probably more readable to not do so. # it's probably more readable to not do so.
if field == "notifications_stream": if field == "new_stream_announcements_stream":
old_value = realm.notifications_stream_id old_value = realm.new_stream_announcements_stream_id
realm.notifications_stream = stream realm.new_stream_announcements_stream = stream
property = "notifications_stream_id" property = "new_stream_announcements_stream_id"
elif field == "signup_notifications_stream": elif field == "signup_notifications_stream":
old_value = realm.signup_notifications_stream_id old_value = realm.signup_notifications_stream_id
realm.signup_notifications_stream = stream realm.signup_notifications_stream = stream
@ -304,10 +304,12 @@ def do_set_realm_stream(
send_event(realm, event, active_user_ids(realm.id)) send_event(realm, event, active_user_ids(realm.id))
def do_set_realm_notifications_stream( def do_set_realm_new_stream_announcements_stream(
realm: Realm, stream: Optional[Stream], stream_id: int, *, acting_user: Optional[UserProfile] realm: Realm, stream: Optional[Stream], stream_id: int, *, acting_user: Optional[UserProfile]
) -> None: ) -> None:
do_set_realm_stream(realm, "notifications_stream", stream, stream_id, acting_user=acting_user) do_set_realm_stream(
realm, "new_stream_announcements_stream", stream, stream_id, acting_user=acting_user
)
def do_set_realm_signup_notifications_stream( def do_set_realm_signup_notifications_stream(

View File

@ -918,7 +918,7 @@ def check_realm_update(
assert "extra_data" not in event assert "extra_data" not in event
if prop in ["notifications_stream_id", "signup_notifications_stream_id", "org_type"]: if prop in ["new_stream_announcements_stream_id", "signup_notifications_stream_id", "org_type"]:
assert isinstance(value, int) assert isinstance(value, int)
return return

View File

@ -362,11 +362,11 @@ def fetch_initial_state_data(
else server_default_jitsi_server_url else server_default_jitsi_server_url
) )
notifications_stream = realm.get_notifications_stream() new_stream_announcements_stream = realm.get_new_stream_announcements_stream()
if notifications_stream: if new_stream_announcements_stream:
state["realm_notifications_stream_id"] = notifications_stream.id state["realm_new_stream_announcements_stream_id"] = new_stream_announcements_stream.id
else: else:
state["realm_notifications_stream_id"] = -1 state["realm_new_stream_announcements_stream_id"] = -1
signup_notifications_stream = realm.get_signup_notifications_stream() signup_notifications_stream = realm.get_signup_notifications_stream()
if signup_notifications_stream: if signup_notifications_stream:

View File

@ -906,10 +906,10 @@ def import_uploads(
# have to import the dependencies first.) # have to import the dependencies first.)
# #
# * Client [no deps] # * Client [no deps]
# * Realm [-notifications_stream,-group_permissions] # * Realm [-announcements_streams,-group_permissions]
# * UserGroup # * UserGroup
# * Stream [only depends on realm] # * Stream [only depends on realm]
# * Realm's notifications_stream and group_permissions # * Realm's announcements_streams and group_permissions
# * UserProfile, in order by ID to avoid bot loop issues # * UserProfile, in order by ID to avoid bot loop issues
# * Now can do all realm_tables # * Now can do all realm_tables
# * Huddle # * Huddle
@ -951,9 +951,11 @@ def do_import_realm(import_dir: Path, subdomain: str, processes: int = 1) -> Rea
# We don't import the Stream and UserGroup models yet, since # We don't import the Stream and UserGroup models yet, since
# they depend on Realm, which isn't imported yet. # they depend on Realm, which isn't imported yet.
# But we need the Stream and UserGroup model IDs for # But we need the Stream and UserGroup model IDs for
# notifications_stream and group permissions, respectively # announcements streams and group permissions, respectively
update_model_ids(Stream, data, "stream") update_model_ids(Stream, data, "stream")
re_map_foreign_keys(data, "zerver_realm", "notifications_stream", related_table="stream") re_map_foreign_keys(
data, "zerver_realm", "new_stream_announcements_stream", related_table="stream"
)
re_map_foreign_keys(data, "zerver_realm", "signup_notifications_stream", related_table="stream") re_map_foreign_keys(data, "zerver_realm", "signup_notifications_stream", related_table="stream")
if "zerver_usergroup" in data: if "zerver_usergroup" in data:
update_model_ids(UserGroup, data, "usergroup") update_model_ids(UserGroup, data, "usergroup")

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.9 on 2024-02-07 11:09
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("zerver", "0496_alter_scheduledmessage_read_by_sender"),
]
operations = [
migrations.RenameField(
model_name="realm",
old_name="notifications_stream",
new_name="new_stream_announcements_stream",
),
]

View File

@ -335,7 +335,7 @@ class Realm(models.Model): # type: ignore[django-manager-missing] # django-stub
DEFAULT_NOTIFICATION_STREAM_NAME = "general" DEFAULT_NOTIFICATION_STREAM_NAME = "general"
INITIAL_PRIVATE_STREAM_NAME = "core team" INITIAL_PRIVATE_STREAM_NAME = "core team"
STREAM_EVENTS_NOTIFICATION_TOPIC_NAME = gettext_lazy("stream events") STREAM_EVENTS_NOTIFICATION_TOPIC_NAME = gettext_lazy("stream events")
notifications_stream = models.ForeignKey( new_stream_announcements_stream = models.ForeignKey(
"Stream", "Stream",
related_name="+", related_name="+",
null=True, null=True,
@ -784,9 +784,12 @@ class Realm(models.Model): # type: ignore[django-manager-missing] # django-stub
def get_bot_domain(self) -> str: def get_bot_domain(self) -> str:
return get_fake_email_domain(self.host) return get_fake_email_domain(self.host)
def get_notifications_stream(self) -> Optional["Stream"]: def get_new_stream_announcements_stream(self) -> Optional["Stream"]:
if self.notifications_stream is not None and not self.notifications_stream.deactivated: if (
return self.notifications_stream self.new_stream_announcements_stream is not None
and not self.new_stream_announcements_stream.deactivated
):
return self.new_stream_announcements_stream
return None return None
def get_signup_notifications_stream(self) -> Optional["Stream"]: def get_signup_notifications_stream(self) -> Optional["Stream"]:

View File

@ -4474,7 +4474,7 @@ paths:
description: | description: |
The URL of the organization's dark theme wide-format logo configured in the The URL of the organization's dark theme wide-format logo configured in the
[organization profile](/help/create-your-organization-profile). [organization profile](/help/create-your-organization-profile).
notifications_stream_id: new_stream_announcements_stream_id:
type: integer type: integer
description: | description: |
The ID of the stream to which automated messages announcing the The ID of the stream to which automated messages announcing the
@ -4486,6 +4486,9 @@ paths:
primarily relevant to clients containing UI for changing it. primarily relevant to clients containing UI for changing it.
[new-stream-announce]: /help/configure-notification-bot#new-stream-announcements [new-stream-announce]: /help/configure-notification-bot#new-stream-announcements
**Changes**: In Zulip 9.0 (feature level 241), renamed 'notifications_stream_id'
to `new_stream_announcements_stream_id`.
org_type: org_type:
type: integer type: integer
description: | description: |
@ -15114,7 +15117,7 @@ paths:
**Changes**: New in Zulip 5.0 (feature level 74). Previously, **Changes**: New in Zulip 5.0 (feature level 74). Previously,
this was hardcoded to 90 seconds, and clients should use that as a fallback this was hardcoded to 90 seconds, and clients should use that as a fallback
value when interacting with servers where this field is not present. value when interacting with servers where this field is not present.
realm_notifications_stream_id: realm_new_stream_announcements_stream_id:
type: integer type: integer
description: | description: |
Present if `realm` is present in `fetch_event_types`. Present if `realm` is present in `fetch_event_types`.
@ -15128,6 +15131,9 @@ paths:
primarily relevant to clients containing UI for changing it. primarily relevant to clients containing UI for changing it.
[new-stream-announce]: /help/configure-notification-bot#new-stream-announcements [new-stream-announce]: /help/configure-notification-bot#new-stream-announcements
**Changes**: In Zulip 9.0 (feature level 241), renamed 'realm_notifications_stream_id'
to `realm_new_stream_announcements_stream_id`.
realm_signup_notifications_stream_id: realm_signup_notifications_stream_id:
type: integer type: integer
description: | description: |

View File

@ -34,7 +34,7 @@ from zerver.actions.realm_settings import (
do_deactivate_realm, do_deactivate_realm,
do_reactivate_realm, do_reactivate_realm,
do_set_realm_authentication_methods, do_set_realm_authentication_methods,
do_set_realm_notifications_stream, do_set_realm_new_stream_announcements_stream,
do_set_realm_property, do_set_realm_property,
do_set_realm_signup_notifications_stream, do_set_realm_signup_notifications_stream,
) )
@ -556,15 +556,15 @@ class TestRealmAuditLog(ZulipTestCase):
1, 1,
) )
def test_set_realm_notifications_stream(self) -> None: def test_set_realm_new_stream_announcements_stream(self) -> None:
now = timezone_now() now = timezone_now()
realm = get_realm("zulip") realm = get_realm("zulip")
user = self.example_user("hamlet") user = self.example_user("hamlet")
old_value = realm.notifications_stream_id old_value = realm.new_stream_announcements_stream_id
stream_name = "test" stream_name = "test"
stream = self.make_stream(stream_name, realm) stream = self.make_stream(stream_name, realm)
do_set_realm_notifications_stream(realm, stream, stream.id, acting_user=user) do_set_realm_new_stream_announcements_stream(realm, stream, stream.id, acting_user=user)
self.assertEqual( self.assertEqual(
RealmAuditLog.objects.filter( RealmAuditLog.objects.filter(
realm=realm, realm=realm,
@ -574,7 +574,7 @@ class TestRealmAuditLog(ZulipTestCase):
extra_data={ extra_data={
RealmAuditLog.OLD_VALUE: old_value, RealmAuditLog.OLD_VALUE: old_value,
RealmAuditLog.NEW_VALUE: stream.id, RealmAuditLog.NEW_VALUE: stream.id,
"property": "notifications_stream", "property": "new_stream_announcements_stream",
}, },
).count(), ).count(),
1, 1,

View File

@ -78,7 +78,7 @@ from zerver.actions.realm_settings import (
do_deactivate_realm, do_deactivate_realm,
do_set_push_notifications_enabled_end_timestamp, do_set_push_notifications_enabled_end_timestamp,
do_set_realm_authentication_methods, do_set_realm_authentication_methods,
do_set_realm_notifications_stream, do_set_realm_new_stream_announcements_stream,
do_set_realm_property, do_set_realm_property,
do_set_realm_signup_notifications_stream, do_set_realm_signup_notifications_stream,
do_set_realm_user_default_setting, do_set_realm_user_default_setting,
@ -2289,20 +2289,23 @@ class NormalActionsTest(BaseAction):
value=value, value=value,
) )
def test_change_realm_notifications_stream(self) -> None: def test_change_realm_new_stream_announcements_stream(self) -> None:
stream = get_stream("Rome", self.user_profile.realm) stream = get_stream("Rome", self.user_profile.realm)
for notifications_stream, notifications_stream_id in ((stream, stream.id), (None, -1)): for new_stream_announcements_stream, new_stream_announcements_stream_id in (
(stream, stream.id),
(None, -1),
):
events = self.verify_action( events = self.verify_action(
partial( partial(
do_set_realm_notifications_stream, do_set_realm_new_stream_announcements_stream,
self.user_profile.realm, self.user_profile.realm,
notifications_stream, new_stream_announcements_stream,
notifications_stream_id, new_stream_announcements_stream_id,
acting_user=None, acting_user=None,
) )
) )
check_realm_update("events[0]", events[0], "notifications_stream_id") check_realm_update("events[0]", events[0], "new_stream_announcements_stream_id")
def test_change_realm_signup_notifications_stream(self) -> None: def test_change_realm_signup_notifications_stream(self) -> None:
stream = get_stream("Rome", self.user_profile.realm) stream = get_stream("Rome", self.user_profile.realm)

View File

@ -175,10 +175,10 @@ class HomeTest(ZulipTestCase):
"realm_move_messages_within_stream_limit_seconds", "realm_move_messages_within_stream_limit_seconds",
"realm_name", "realm_name",
"realm_name_changes_disabled", "realm_name_changes_disabled",
"realm_new_stream_announcements_stream_id",
"realm_night_logo_source", "realm_night_logo_source",
"realm_night_logo_url", "realm_night_logo_url",
"realm_non_active_users", "realm_non_active_users",
"realm_notifications_stream_id",
"realm_org_type", "realm_org_type",
"realm_password_auth_enabled", "realm_password_auth_enabled",
"realm_plan_type", "realm_plan_type",
@ -626,15 +626,15 @@ class HomeTest(ZulipTestCase):
set(result["Cache-Control"].split(", ")), {"must-revalidate", "no-store", "no-cache"} set(result["Cache-Control"].split(", ")), {"must-revalidate", "no-store", "no-cache"}
) )
def test_notifications_stream(self) -> None: def test_new_stream_announcements_stream(self) -> None:
realm = get_realm("zulip") realm = get_realm("zulip")
realm.notifications_stream_id = get_stream("Denmark", realm).id realm.new_stream_announcements_stream_id = get_stream("Denmark", realm).id
realm.save() realm.save()
self.login("hamlet") self.login("hamlet")
result = self._get_home_page() result = self._get_home_page()
page_params = self._get_page_params(result) page_params = self._get_page_params(result)
self.assertEqual( self.assertEqual(
page_params["state_data"]["realm_notifications_stream_id"], page_params["state_data"]["realm_new_stream_announcements_stream_id"],
get_stream("Denmark", realm).id, get_stream("Denmark", realm).id,
) )

View File

@ -480,58 +480,62 @@ class RealmTest(ZulipTestCase):
"The organization reactivation link has expired or is not valid.", response "The organization reactivation link has expired or is not valid.", response
) )
def test_change_notifications_stream(self) -> None: def test_change_new_stream_announcements_stream(self) -> None:
# We need an admin user. # We need an admin user.
self.login("iago") self.login("iago")
disabled_notif_stream_id = -1 disabled_notif_stream_id = -1
req = dict(notifications_stream_id=orjson.dumps(disabled_notif_stream_id).decode()) req = dict(
new_stream_announcements_stream_id=orjson.dumps(disabled_notif_stream_id).decode()
)
result = self.client_patch("/json/realm", req) result = self.client_patch("/json/realm", req)
self.assert_json_success(result) self.assert_json_success(result)
realm = get_realm("zulip") realm = get_realm("zulip")
self.assertEqual(realm.notifications_stream, None) self.assertEqual(realm.new_stream_announcements_stream, None)
new_notif_stream_id = Stream.objects.get(name="Denmark").id new_notif_stream_id = Stream.objects.get(name="Denmark").id
req = dict(notifications_stream_id=orjson.dumps(new_notif_stream_id).decode()) req = dict(new_stream_announcements_stream_id=orjson.dumps(new_notif_stream_id).decode())
result = self.client_patch("/json/realm", req) result = self.client_patch("/json/realm", req)
self.assert_json_success(result) self.assert_json_success(result)
realm = get_realm("zulip") realm = get_realm("zulip")
assert realm.notifications_stream is not None assert realm.new_stream_announcements_stream is not None
self.assertEqual(realm.notifications_stream.id, new_notif_stream_id) self.assertEqual(realm.new_stream_announcements_stream.id, new_notif_stream_id)
# Test that admin can set the setting to an unsubscribed private stream as well. # Test that admin can set the setting to an unsubscribed private stream as well.
new_notif_stream_id = self.make_stream("private_stream", invite_only=True).id new_notif_stream_id = self.make_stream("private_stream", invite_only=True).id
req = dict(notifications_stream_id=orjson.dumps(new_notif_stream_id).decode()) req = dict(new_stream_announcements_stream_id=orjson.dumps(new_notif_stream_id).decode())
result = self.client_patch("/json/realm", req) result = self.client_patch("/json/realm", req)
self.assert_json_success(result) self.assert_json_success(result)
realm = get_realm("zulip") realm = get_realm("zulip")
assert realm.notifications_stream is not None assert realm.new_stream_announcements_stream is not None
self.assertEqual(realm.notifications_stream.id, new_notif_stream_id) self.assertEqual(realm.new_stream_announcements_stream.id, new_notif_stream_id)
invalid_notif_stream_id = 1234 invalid_notif_stream_id = 1234
req = dict(notifications_stream_id=orjson.dumps(invalid_notif_stream_id).decode()) req = dict(
new_stream_announcements_stream_id=orjson.dumps(invalid_notif_stream_id).decode()
)
result = self.client_patch("/json/realm", req) result = self.client_patch("/json/realm", req)
self.assert_json_error(result, "Invalid stream ID") self.assert_json_error(result, "Invalid stream ID")
realm = get_realm("zulip") realm = get_realm("zulip")
assert realm.notifications_stream is not None assert realm.new_stream_announcements_stream is not None
self.assertNotEqual(realm.notifications_stream.id, invalid_notif_stream_id) self.assertNotEqual(realm.new_stream_announcements_stream.id, invalid_notif_stream_id)
def test_get_default_notifications_stream(self) -> None: def test_get_default_new_stream_announcements_stream(self) -> None:
realm = get_realm("zulip") realm = get_realm("zulip")
verona = get_stream("verona", realm) verona = get_stream("verona", realm)
notifications_stream = realm.get_notifications_stream() new_stream_announcements_stream = realm.get_new_stream_announcements_stream()
assert notifications_stream is not None assert new_stream_announcements_stream is not None
self.assertEqual(notifications_stream.id, verona.id) self.assertEqual(new_stream_announcements_stream.id, verona.id)
do_deactivate_stream(notifications_stream, acting_user=None) do_deactivate_stream(new_stream_announcements_stream, acting_user=None)
self.assertIsNone(realm.get_notifications_stream()) self.assertIsNone(realm.get_new_stream_announcements_stream())
def test_merge_streams(self) -> None: def test_merge_streams(self) -> None:
realm = get_realm("zulip") realm = get_realm("zulip")
denmark = get_stream("Denmark", realm) denmark = get_stream("Denmark", realm)
cordelia = self.example_user("cordelia") cordelia = self.example_user("cordelia")
notifications_stream = realm.get_notifications_stream() new_stream_announcements_stream = realm.get_new_stream_announcements_stream()
assert notifications_stream is not None assert new_stream_announcements_stream is not None
create_stream_if_needed(realm, "Atlantis") create_stream_if_needed(realm, "Atlantis")
self.subscribe(cordelia, "Atlantis") self.subscribe(cordelia, "Atlantis")
@ -547,9 +551,9 @@ class RealmTest(ZulipTestCase):
with self.assertRaises(Stream.DoesNotExist): with self.assertRaises(Stream.DoesNotExist):
get_stream("Atlantis", realm) get_stream("Atlantis", realm)
stats = merge_streams(realm, denmark, notifications_stream) stats = merge_streams(realm, denmark, new_stream_announcements_stream)
self.assertEqual(stats, (2, 1, 10)) self.assertEqual(stats, (2, 1, 10))
self.assertIsNone(realm.get_notifications_stream()) self.assertIsNone(realm.get_new_stream_announcements_stream())
def test_change_signup_notifications_stream(self) -> None: def test_change_signup_notifications_stream(self) -> None:
# We need an admin user. # We need an admin user.
@ -965,9 +969,9 @@ class RealmTest(ZulipTestCase):
).exists() ).exists()
) )
assert realm.notifications_stream is not None assert realm.new_stream_announcements_stream is not None
self.assertEqual(realm.notifications_stream.name, "general") self.assertEqual(realm.new_stream_announcements_stream.name, "general")
self.assertEqual(realm.notifications_stream.realm, realm) self.assertEqual(realm.new_stream_announcements_stream.realm, realm)
assert realm.signup_notifications_stream is not None assert realm.signup_notifications_stream is not None
self.assertEqual(realm.signup_notifications_stream.name, "core team") self.assertEqual(realm.signup_notifications_stream.name, "core team")
@ -1012,9 +1016,9 @@ class RealmTest(ZulipTestCase):
).exists() ).exists()
) )
assert realm.notifications_stream is not None assert realm.new_stream_announcements_stream is not None
self.assertEqual(realm.notifications_stream.name, "general") self.assertEqual(realm.new_stream_announcements_stream.name, "general")
self.assertEqual(realm.notifications_stream.realm, realm) self.assertEqual(realm.new_stream_announcements_stream.realm, realm)
assert realm.signup_notifications_stream is not None assert realm.signup_notifications_stream is not None
self.assertEqual(realm.signup_notifications_stream.name, "core team") self.assertEqual(realm.signup_notifications_stream.name, "core team")

View File

@ -453,8 +453,8 @@ class TestCreateStreams(ZulipTestCase):
announce_stream = ensure_stream( announce_stream = ensure_stream(
realm, "announce", False, "announcements here.", acting_user=None realm, "announce", False, "announcements here.", acting_user=None
) )
realm.notifications_stream_id = announce_stream.id realm.new_stream_announcements_stream_id = announce_stream.id
realm.save(update_fields=["notifications_stream_id"]) realm.save(update_fields=["new_stream_announcements_stream_id"])
self.subscribe(iago, announce_stream.name) self.subscribe(iago, announce_stream.name)
self.subscribe(hamlet, announce_stream.name) self.subscribe(hamlet, announce_stream.name)
@ -4138,8 +4138,8 @@ class SubscriptionAPITest(ZulipTestCase):
other_params = { other_params = {
"announce": "true", "announce": "true",
} }
notifications_stream = get_stream(self.streams[0], self.test_realm) new_stream_announcements_stream = get_stream(self.streams[0], self.test_realm)
self.test_realm.notifications_stream_id = notifications_stream.id self.test_realm.new_stream_announcements_stream_id = new_stream_announcements_stream.id
self.test_realm.save() self.test_realm.save()
with self.capture_send_event_calls(expected_num_events=7) as events: with self.capture_send_event_calls(expected_num_events=7) as events:
@ -4187,8 +4187,8 @@ class SubscriptionAPITest(ZulipTestCase):
current_stream = self.get_streams(invitee)[0] current_stream = self.get_streams(invitee)[0]
invite_streams = self.make_random_stream_names([current_stream])[:1] invite_streams = self.make_random_stream_names([current_stream])[:1]
notifications_stream = get_stream(current_stream, self.test_realm) new_stream_announcements_stream = get_stream(current_stream, self.test_realm)
self.test_realm.notifications_stream_id = notifications_stream.id self.test_realm.new_stream_announcements_stream_id = new_stream_announcements_stream.id
self.test_realm.save() self.test_realm.save()
self.common_subscribe_to_streams( self.common_subscribe_to_streams(
@ -4203,7 +4203,7 @@ class SubscriptionAPITest(ZulipTestCase):
msg = self.get_second_to_last_message() msg = self.get_second_to_last_message()
self.assertEqual(msg.recipient.type, Recipient.STREAM) self.assertEqual(msg.recipient.type, Recipient.STREAM)
self.assertEqual(msg.recipient.type_id, notifications_stream.id) self.assertEqual(msg.recipient.type_id, new_stream_announcements_stream.id)
self.assertEqual(msg.sender_id, self.notification_bot(self.test_realm).id) self.assertEqual(msg.sender_id, self.notification_bot(self.test_realm).id)
expected_msg = ( expected_msg = (
f"@_**{invitee_full_name}|{invitee.id}** created a new stream #**{invite_streams[0]}**." f"@_**{invitee_full_name}|{invitee.id}** created a new stream #**{invite_streams[0]}**."
@ -4227,8 +4227,8 @@ class SubscriptionAPITest(ZulipTestCase):
""" """
realm = do_create_realm("testrealm", "Test Realm") realm = do_create_realm("testrealm", "Test Realm")
notifications_stream = Stream.objects.get(name="general", realm=realm) new_stream_announcements_stream = Stream.objects.get(name="general", realm=realm)
realm.notifications_stream = notifications_stream realm.new_stream_announcements_stream = new_stream_announcements_stream
realm.save() realm.save()
invite_streams = ["cross_stream"] invite_streams = ["cross_stream"]
@ -4248,7 +4248,7 @@ class SubscriptionAPITest(ZulipTestCase):
msg = self.get_second_to_last_message() msg = self.get_second_to_last_message()
self.assertEqual(msg.recipient.type, Recipient.STREAM) self.assertEqual(msg.recipient.type, Recipient.STREAM)
self.assertEqual(msg.recipient.type_id, notifications_stream.id) self.assertEqual(msg.recipient.type_id, new_stream_announcements_stream.id)
self.assertEqual(msg.sender_id, self.notification_bot(realm).id) self.assertEqual(msg.sender_id, self.notification_bot(realm).id)
stream_id = Stream.objects.latest("id").id stream_id = Stream.objects.latest("id").id
expected_rendered_msg = f'<p><span class="user-mention silent" data-user-id="{user.id}">{user.full_name}</span> created a new stream <a class="stream" data-stream-id="{stream_id}" href="/#narrow/stream/{stream_id}-{invite_streams[0]}">#{invite_streams[0]}</a>.</p>' expected_rendered_msg = f'<p><span class="user-mention silent" data-user-id="{user.id}">{user.full_name}</span> created a new stream <a class="stream" data-stream-id="{stream_id}" href="/#narrow/stream/{stream_id}-{invite_streams[0]}">#{invite_streams[0]}</a>.</p>'
@ -4262,8 +4262,8 @@ class SubscriptionAPITest(ZulipTestCase):
invitee = self.example_user("iago") invitee = self.example_user("iago")
current_stream = self.get_streams(invitee)[0] current_stream = self.get_streams(invitee)[0]
notifications_stream = get_stream(current_stream, self.test_realm) new_stream_announcements_stream = get_stream(current_stream, self.test_realm)
self.test_realm.notifications_stream_id = notifications_stream.id self.test_realm.new_stream_announcements_stream_id = new_stream_announcements_stream.id
self.test_realm.save() self.test_realm.save()
invite_streams = ["strange ) \\ test"] invite_streams = ["strange ) \\ test"]
@ -4277,7 +4277,9 @@ class SubscriptionAPITest(ZulipTestCase):
) )
msg = self.get_second_to_last_message() msg = self.get_second_to_last_message()
self.assertEqual(msg.sender_id, self.notification_bot(notifications_stream.realm).id) self.assertEqual(
msg.sender_id, self.notification_bot(new_stream_announcements_stream.realm).id
)
expected_msg = ( expected_msg = (
f"@_**{invitee_full_name}|{invitee.id}** created a new stream #**{invite_streams[0]}**." f"@_**{invitee_full_name}|{invitee.id}** created a new stream #**{invite_streams[0]}**."
) )
@ -5538,9 +5540,9 @@ class SubscriptionAPITest(ZulipTestCase):
invite_only=True, invite_only=True,
) )
# Test creating a public stream with announce when realm has a notification stream. # Test creating a public stream with announce when realm has a new_stream_announcements_stream.
notifications_stream = get_stream(self.streams[0], self.test_realm) new_stream_announcements_stream = get_stream(self.streams[0], self.test_realm)
self.test_realm.notifications_stream_id = notifications_stream.id self.test_realm.new_stream_announcements_stream_id = new_stream_announcements_stream.id
self.test_realm.save() self.test_realm.save()
with self.assert_database_query_count(47): with self.assert_database_query_count(47):
self.common_subscribe_to_streams( self.common_subscribe_to_streams(

View File

@ -14,7 +14,7 @@ from zerver.actions.realm_settings import (
do_deactivate_realm, do_deactivate_realm,
do_reactivate_realm, do_reactivate_realm,
do_set_realm_authentication_methods, do_set_realm_authentication_methods,
do_set_realm_notifications_stream, do_set_realm_new_stream_announcements_stream,
do_set_realm_property, do_set_realm_property,
do_set_realm_signup_notifications_stream, do_set_realm_signup_notifications_stream,
do_set_realm_user_default_setting, do_set_realm_user_default_setting,
@ -110,7 +110,7 @@ def update_realm(
), ),
# Note: push_notifications_enabled and push_notifications_enabled_end_timestamp # Note: push_notifications_enabled and push_notifications_enabled_end_timestamp
# are not offered here as it is maintained by the server, not via the API. # are not offered here as it is maintained by the server, not via the API.
notifications_stream_id: Optional[int] = REQ(json_validator=check_int, default=None), new_stream_announcements_stream_id: Optional[int] = REQ(json_validator=check_int, default=None),
signup_notifications_stream_id: Optional[int] = REQ(json_validator=check_int, default=None), signup_notifications_stream_id: Optional[int] = REQ(json_validator=check_int, default=None),
message_retention_days_raw: Optional[Union[int, str]] = REQ( message_retention_days_raw: Optional[Union[int, str]] = REQ(
"message_retention_days", json_validator=check_string_or_int, default=None "message_retention_days", json_validator=check_string_or_int, default=None
@ -389,21 +389,24 @@ def update_realm(
do_set_realm_authentication_methods(realm, authentication_methods, acting_user=user_profile) do_set_realm_authentication_methods(realm, authentication_methods, acting_user=user_profile)
data["authentication_methods"] = authentication_methods data["authentication_methods"] = authentication_methods
# Realm.notifications_stream and Realm.signup_notifications_stream are not boolean, # Realm.new_stream_announcements_stream and Realm.signup_notifications_stream are not boolean,
# str or integer field, and thus doesn't fit into the do_set_realm_property framework. # str or integer field, and thus doesn't fit into the do_set_realm_property framework.
if notifications_stream_id is not None and ( if new_stream_announcements_stream_id is not None and (
realm.notifications_stream is None realm.new_stream_announcements_stream is None
or (realm.notifications_stream.id != notifications_stream_id) or (realm.new_stream_announcements_stream.id != new_stream_announcements_stream_id)
): ):
new_notifications_stream = None new_stream_announcements_stream_new = None
if notifications_stream_id >= 0: if new_stream_announcements_stream_id >= 0:
(new_notifications_stream, sub) = access_stream_by_id( (new_stream_announcements_stream_new, sub) = access_stream_by_id(
user_profile, notifications_stream_id, allow_realm_admin=True user_profile, new_stream_announcements_stream_id, allow_realm_admin=True
) )
do_set_realm_notifications_stream( do_set_realm_new_stream_announcements_stream(
realm, new_notifications_stream, notifications_stream_id, acting_user=user_profile realm,
new_stream_announcements_stream_new,
new_stream_announcements_stream_id,
acting_user=user_profile,
) )
data["notifications_stream_id"] = notifications_stream_id data["new_stream_announcements_stream_id"] = new_stream_announcements_stream_id
if signup_notifications_stream_id is not None and ( if signup_notifications_stream_id is not None and (
realm.signup_notifications_stream is None realm.signup_notifications_stream is None

View File

@ -767,9 +767,9 @@ def send_messages_for_new_subscribers(
) )
if announce and len(created_streams) > 0: if announce and len(created_streams) > 0:
notifications_stream = user_profile.realm.get_notifications_stream() new_stream_announcements_stream = user_profile.realm.get_new_stream_announcements_stream()
if notifications_stream is not None: if new_stream_announcements_stream is not None:
with override_language(notifications_stream.realm.default_language): with override_language(new_stream_announcements_stream.realm.default_language):
if len(created_streams) > 1: if len(created_streams) > 1:
content = _("{user_name} created the following streams: {stream_str}.") content = _("{user_name} created the following streams: {stream_str}.")
else: else:
@ -781,12 +781,14 @@ def send_messages_for_new_subscribers(
stream_str=", ".join(f"#**{s.name}**" for s in created_streams), stream_str=", ".join(f"#**{s.name}**" for s in created_streams),
) )
sender = get_system_bot(settings.NOTIFICATION_BOT, notifications_stream.realm_id) sender = get_system_bot(
settings.NOTIFICATION_BOT, new_stream_announcements_stream.realm_id
)
notifications.append( notifications.append(
internal_prep_stream_message( internal_prep_stream_message(
sender=sender, sender=sender,
stream=notifications_stream, stream=new_stream_announcements_stream,
topic_name=topic_name, topic_name=topic_name,
content=content, content=content,
), ),

View File

@ -339,10 +339,10 @@ class Command(BaseCommand):
enable_spectator_access=True, enable_spectator_access=True,
) )
RealmDomain.objects.create(realm=zulip_realm, domain="zulip.com") RealmDomain.objects.create(realm=zulip_realm, domain="zulip.com")
assert zulip_realm.notifications_stream is not None assert zulip_realm.new_stream_announcements_stream is not None
zulip_realm.notifications_stream.name = "Verona" zulip_realm.new_stream_announcements_stream.name = "Verona"
zulip_realm.notifications_stream.description = "A city in Italy" zulip_realm.new_stream_announcements_stream.description = "A city in Italy"
zulip_realm.notifications_stream.save(update_fields=["name", "description"]) zulip_realm.new_stream_announcements_stream.save(update_fields=["name", "description"])
realm_user_default = RealmUserDefault.objects.get(realm=zulip_realm) realm_user_default = RealmUserDefault.objects.get(realm=zulip_realm)
realm_user_default.enter_sends = True realm_user_default.enter_sends = True
@ -1027,9 +1027,9 @@ class Command(BaseCommand):
} }
bulk_create_streams(zulip_realm, zulip_stream_dict) bulk_create_streams(zulip_realm, zulip_stream_dict)
# Now that we've created the notifications stream, configure it properly. # Now that we've created the new_stream_announcements_stream, configure it properly.
zulip_realm.notifications_stream = get_stream("announce", zulip_realm) zulip_realm.new_stream_announcements_stream = get_stream("announce", zulip_realm)
zulip_realm.save(update_fields=["notifications_stream"]) zulip_realm.save(update_fields=["new_stream_announcements_stream"])
# Add a few default streams # Add a few default streams
for default_stream_name in ["design", "devel", "social", "support"]: for default_stream_name in ["design", "devel", "social", "support"]: