From 46b57e66052fdb1115816c40e54b385a194f7238 Mon Sep 17 00:00:00 2001 From: Aditya Kumar Kasaudhan <74228301+Aditya8840@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:38:57 +0530 Subject: [PATCH] web: Add is:watched alias for search operator. This commit replaces `is:alerted` with `is:watched` as part of the migration from alert words to watched phrases. --- web/src/alert_words.ts | 4 +-- web/src/echo.ts | 4 +-- web/src/filter.ts | 12 ++++---- web/src/message_edit.ts | 6 ++-- web/src/message_events.js | 6 ++-- web/src/message_notifications.ts | 2 +- web/src/message_store.ts | 6 ++-- web/src/search_suggestion.ts | 4 +-- web/templates/search_description.hbs | 6 +++- web/templates/search_operators.hbs | 2 +- web/tests/alert_words.test.cjs | 24 +++++++-------- web/tests/example2.test.cjs | 4 +-- web/tests/filter.test.cjs | 28 ++++++++--------- web/tests/message_events.test.cjs | 2 +- web/tests/message_store.test.cjs | 18 +++++------ web/tests/narrow_local.test.cjs | 8 ++--- web/tests/search_suggestion.test.cjs | 46 +++++++++++++--------------- zerver/lib/narrow.py | 2 +- zerver/lib/narrow_predicate.py | 2 +- zerver/tests/test_message_fetch.py | 42 ++++++++++++++++++++++++- 20 files changed, 135 insertions(+), 93 deletions(-) diff --git a/web/src/alert_words.ts b/web/src/alert_words.ts index 3dac8df4f0..74c039e0ec 100644 --- a/web/src/alert_words.ts +++ b/web/src/alert_words.ts @@ -43,7 +43,7 @@ const alert_regex_replacements = new Map([ export function process_message(message: Message): void { // Parsing for alert words is expensive, so we rely on the host // to tell us there any alert words to even look for. - if (!message.alerted) { + if (!message.watched) { return; } @@ -89,7 +89,7 @@ export function notifies(message: Message): boolean { // alert words into a message, just because that can be annoying for // certain types of workflows where everybody on your team, including // yourself, sets up an alert word to effectively mention the team. - return !people.is_current_user(message.sender_email) && message.alerted; + return !people.is_current_user(message.sender_email) && message.watched; } export const initialize = (params: StateData["alert_words"]): void => { diff --git a/web/src/echo.ts b/web/src/echo.ts index aa1165a4a6..2dab414b10 100644 --- a/web/src/echo.ts +++ b/web/src/echo.ts @@ -73,7 +73,7 @@ type LocalEditRequest = Partial<{ starred: boolean; historical: boolean; collapsed: boolean; - alerted: boolean; + watched: boolean; mentioned: boolean; mentioned_me_directly: boolean; }>; @@ -403,7 +403,7 @@ export function edit_locally(message: Message, request: LocalEditRequest): Messa message.content = request.content; message.mentioned = request.mentioned ?? false; message.mentioned_me_directly = request.mentioned_me_directly ?? false; - message.alerted = request.alerted ?? false; + message.watched = request.watched ?? false; } else { // Otherwise, we Markdown-render the message; this resets // all flags, so we need to restore those flags that are diff --git a/web/src/filter.ts b/web/src/filter.ts index b407c29af9..16b7abfd46 100644 --- a/web/src/filter.ts +++ b/web/src/filter.ts @@ -167,8 +167,8 @@ function message_matches_search_term(message: Message, operator: string, operand return message.starred; case "mentioned": return message.mentioned; - case "alerted": - return message.alerted; + case "watched": + return message.watched; case "unread": return message.unread; case "resolved": @@ -553,7 +553,7 @@ export class Filter { "private", "starred", "mentioned", - "alerted", + "watched", "unread", "resolved", "followed", @@ -646,7 +646,7 @@ export class Filter { "sender", "near", "id", - "is-alerted", + "is-watched", "is-mentioned", "is-dm", "is-starred", @@ -1412,8 +1412,8 @@ export class Filter { // These cases return false for is_common_narrow, and therefore are not // formatted in the message view header. They are used in narrow.js to // update the browser title. - case "is-alerted": - return $t({defaultMessage: "Alerted messages"}); + case "is-watched": + return $t({defaultMessage: "Messages with watched phrases"}); case "is-unread": return $t({defaultMessage: "Unread messages"}); } diff --git a/web/src/message_edit.ts b/web/src/message_edit.ts index 78c8fe006b..0ccc88c1ff 100644 --- a/web/src/message_edit.ts +++ b/web/src/message_edit.ts @@ -81,7 +81,7 @@ type EchoedMessageData = { // These flags are rendering artifacts we'll want if the // edit fails and we need to revert to the original // rendering of the message. - alerted: boolean; + watched: boolean; mentioned: boolean; mentioned_me_directly: boolean; }; @@ -1135,7 +1135,7 @@ export function save_message_row_edit($row: JQuery): void { starred: message.starred, historical: message.historical, collapsed: message.collapsed, - alerted: message.alerted, + watched: message.watched, mentioned: message.mentioned, mentioned_me_directly: message.mentioned, }); @@ -1194,7 +1194,7 @@ export function save_message_row_edit($row: JQuery): void { raw_content: echo_data.orig_raw_content, mentioned: echo_data.mentioned, mentioned_me_directly: echo_data.mentioned_me_directly, - alerted: echo_data.alerted, + watched: echo_data.watched, }); $row = message_lists.current.get_row(message_id); diff --git a/web/src/message_events.js b/web/src/message_events.js index 0b60e2463b..8b82ae1a26 100644 --- a/web/src/message_events.js +++ b/web/src/message_events.js @@ -124,7 +124,7 @@ export let update_views_filtered_on_message_property = ( "is-starred", "is-unread", "is-mentioned", - "is-alerted", + "is-watched", ]; if (message_ids.length === 0 || !supported_term_types.includes(property_term_type)) { @@ -777,8 +777,8 @@ export function update_messages(events) { "is-mentioned", is_mentioned, ); - const is_alerted = event.flags.includes("has_alert_word"); - update_views_filtered_on_message_property([event.message_id], "is-alerted", is_alerted); + const is_watched = event.flags.includes("has_alert_word"); + update_views_filtered_on_message_property([event.message_id], "is-watched", is_watched); } } diff --git a/web/src/message_notifications.ts b/web/src/message_notifications.ts index 52cfd1cfd8..e9c5004bf8 100644 --- a/web/src/message_notifications.ts +++ b/web/src/message_notifications.ts @@ -79,7 +79,7 @@ function debug_notification_source_value(message: Message | TestNotificationMess notification_source = "pm"; } else if (message.mentioned) { notification_source = "mention"; - } else if (message.alerted) { + } else if (message.watched) { notification_source = "alert"; } else { notification_source = "stream"; diff --git a/web/src/message_store.ts b/web/src/message_store.ts index fa93c329b3..ef4481c22a 100644 --- a/web/src/message_store.ts +++ b/web/src/message_store.ts @@ -120,7 +120,7 @@ export type MessageWithBooleans = ( topic_wildcard_mentioned: boolean; collapsed: boolean; condensed?: boolean; - alerted: boolean; + watched: boolean; }; export type MessageCleanReaction = { @@ -258,7 +258,7 @@ export function convert_raw_message_to_message_with_booleans( stream_wildcard_mentioned: convert_flag("stream_wildcard_mentioned"), topic_wildcard_mentioned: convert_flag("topic_wildcard_mentioned"), collapsed: convert_flag("collapsed"), - alerted: convert_flag("has_alert_word"), + watched: convert_flag("has_alert_word"), }; // Once we have set boolean flags here, the `flags` attribute is @@ -294,7 +294,7 @@ export function update_booleans(message: Message, flags: string[]): void { message.mentioned_me_directly = convert_flag("mentioned"); message.stream_wildcard_mentioned = convert_flag("stream_wildcard_mentioned"); message.topic_wildcard_mentioned = convert_flag("topic_wildcard_mentioned"); - message.alerted = convert_flag("has_alert_word"); + message.watched = convert_flag("has_alert_word"); } export function update_sender_full_name(user_id: number, new_name: string): void { diff --git a/web/src/search_suggestion.ts b/web/src/search_suggestion.ts index 4083e2debf..4968176322 100644 --- a/web/src/search_suggestion.ts +++ b/web/src/search_suggestion.ts @@ -688,10 +688,10 @@ function get_is_filter_suggestions(last: NarrowTerm, terms: NarrowTerm[]): Sugge ], }, { - search_string: "is:alerted", + search_string: "is:watched", description_html: "messages with watched phrases", is_people: false, - incompatible_patterns: [{operator: "is", operand: "alerted"}], + incompatible_patterns: [{operator: "is", operand: "watched"}], }, { search_string: "is:unread", diff --git a/web/templates/search_description.hbs b/web/templates/search_description.hbs index 81bdefeef9..e63057b36c 100644 --- a/web/templates/search_description.hbs +++ b/web/templates/search_description.hbs @@ -30,7 +30,11 @@ {{~!-- squash whitespace --~}} {{this.verb}}@-mentions {{~!-- squash whitespace --~}} - {{else if (or (eq this.operand "starred") (eq this.operand "alerted") (eq this.operand "unread"))}} + {{else if (eq this.operand "watched")}} + {{~!-- squash whitespace --~}} + {{this.verb}}Messages with watched phrases + {{~!-- squash whitespace --~}} + {{else if (or (eq this.operand "starred") (eq this.operand "unread"))}} {{~!-- squash whitespace --~}} {{this.verb}}{{this.operand}} messages {{~!-- squash whitespace --~}} diff --git a/web/templates/search_operators.hbs b/web/templates/search_operators.hbs index 7fe33a7780..23fcba3956 100644 --- a/web/templates/search_operators.hbs +++ b/web/templates/search_operators.hbs @@ -110,7 +110,7 @@ - is:alerted + is:watched {{t 'Narrow to messages with watched phrases.'}} diff --git a/web/tests/alert_words.test.cjs b/web/tests/alert_words.test.cjs index 0d788ec8ec..30113fdeed 100644 --- a/web/tests/alert_words.test.cjs +++ b/web/tests/alert_words.test.cjs @@ -44,62 +44,62 @@ const regular_message = { const own_message = { sender_email: "tester@zulip.com", content: "

hey this message alertone

", - alerted: true, + watched: true, }; const other_message = { sender_email: "another@zulip.com", content: "

another alertone message

", - alerted: true, + watched: true, }; const caps_message = { sender_email: "another@zulip.com", content: "

another ALERTtwo message

", - alerted: true, + watched: true, }; const alertwordboundary_message = { sender_email: "another@zulip.com", content: "

another alertthreemessage

", - alerted: false, + watched: false, }; const multialert_message = { sender_email: "another@zulip.com", content: "

another emoji alertone and then alerttwo

", - alerted: true, + watched: true, }; const unsafe_word_message = { sender_email: "another@zulip.com", content: "

gotta al*rt.*s all

", - alerted: true, + watched: true, }; const alert_in_url_message = { sender_email: "another@zulip.com", content: "

http://www.google.com/alertone/me

", - alerted: true, + watched: true, }; const question_word_message = { sender_email: "another@zulip.com", content: "

still alertone? me

", - alerted: true, + watched: true, }; const typo_word_message = { sender_email: "another@zulip.com", content: "

alertones alerttwo alerttwo alertthreez

", - alerted: true, + watched: true, }; const alert_domain_message = { sender_email: "another@zulip.com", content: '

now with link www.alerttwo.us/foo/bar

', - alerted: true, + watched: true, }; // This test ensure we are not mucking up rendered HTML content. const message_with_emoji = { sender_email: "another@zulip.com", content: '

I :heart: emoji!

', - alerted: true, + watched: true, }; run_test("notifications", () => { @@ -188,7 +188,7 @@ run_test("munging", () => { { sender_email: "another@zulip.com", content: `

FD&C <3 >8 5'11" 5'11"

`, - alerted: true, + watched: true, }, `

FD&C <3 >8 5'11" 5'11"

`, ); diff --git a/web/tests/example2.test.cjs b/web/tests/example2.test.cjs index aae5b4365e..0f9faa2994 100644 --- a/web/tests/example2.test.cjs +++ b/web/tests/example2.test.cjs @@ -68,14 +68,14 @@ run_test("message_store", () => { const in_message = {...messages.isaac_to_denmark_stream}; - assert.equal(in_message.alerted, undefined); + assert.equal(in_message.watched, undefined); // Let's add a message into our message_store via // message_helper.process_new_message. assert.equal(message_store.get(in_message.id), undefined); message_helper.process_new_message(in_message); const message = message_store.get(in_message.id); - assert.equal(message.alerted, true); + assert.equal(message.watched, true); // There are more side effects. const topic_names = stream_topic_history.get_recent_topic_names(denmark_stream.stream_id); diff --git a/web/tests/filter.test.cjs b/web/tests/filter.test.cjs index 5dbc0cfe04..eda39e6b90 100644 --- a/web/tests/filter.test.cjs +++ b/web/tests/filter.test.cjs @@ -537,11 +537,11 @@ function assert_not_mark_read_with_is_operands(additional_terms_to_test) { filter = new Filter([...additional_terms_to_test, ...is_operator]); assert.ok(!filter.can_mark_messages_read()); - is_operator = [{operator: "is", operand: "alerted"}]; + is_operator = [{operator: "is", operand: "watched"}]; filter = new Filter([...additional_terms_to_test, ...is_operator]); assert.ok(!filter.can_mark_messages_read()); - is_operator = [{operator: "is", operand: "alerted", negated: true}]; + is_operator = [{operator: "is", operand: "watched", negated: true}]; filter = new Filter([...additional_terms_to_test, ...is_operator]); assert.ok(!filter.can_mark_messages_read()); @@ -970,9 +970,9 @@ test("predicate_basics", ({override}) => { assert.ok(predicate({unread: true})); assert.ok(!predicate({unread: false})); - predicate = get_predicate([["is", "alerted"]]); - assert.ok(predicate({alerted: true})); - assert.ok(!predicate({alerted: false})); + predicate = get_predicate([["is", "watched"]]); + assert.ok(predicate({watched: true})); + assert.ok(!predicate({watched: false})); assert.ok(!predicate({})); predicate = get_predicate([["is", "mentioned"]]); @@ -1537,8 +1537,8 @@ test("describe", ({mock_template}) => { string = "@-mentions"; assert.equal(Filter.search_description_as_html(narrow), string); - narrow = [{operator: "is", operand: "alerted"}]; - string = "alerted messages"; + narrow = [{operator: "is", operand: "watched"}]; + string = "Messages with watched phrases"; assert.equal(Filter.search_description_as_html(narrow), string); narrow = [{operator: "is", operand: "resolved"}]; @@ -1779,16 +1779,16 @@ test("term_type", () => { }); test("first_valid_id_from", ({override}) => { - const terms = [{operator: "is", operand: "alerted"}]; + const terms = [{operator: "is", operand: "watched"}]; const filter = new Filter(terms); const messages = { - 5: {id: 5, alerted: true}, + 5: {id: 5, watched: true}, 10: {id: 10}, - 20: {id: 20, alerted: true}, + 20: {id: 20, watched: true}, 30: {id: 30, type: stream_message}, - 40: {id: 40, alerted: false}, + 40: {id: 40, watched: false}, }; const msg_ids = [10, 20, 30, 40]; @@ -2130,7 +2130,7 @@ test("navbar_helpers", ({override}) => { {operator: "dm", operand: "joe@example.com,STEVE@foo.com,sally@doesnotexist.com"}, ]; // not common narrows, but used for browser title updates - const is_alerted = [{operator: "is", operand: "alerted"}]; + const is_watched = [{operator: "is", operand: "watched"}]; const is_unread = [{operator: "is", operand: "unread"}]; const channel_topic_near = [ {operator: "channel", operand: foo_stream_id.toString()}, @@ -2317,10 +2317,10 @@ test("navbar_helpers", ({override}) => { link: "/help/emoji-reactions", }, { - terms: is_alerted, + terms: is_watched, is_common_narrow: false, icon: undefined, - title: "translated: Alerted messages", + title: "translated: Messages with watched phrases", redirect_url_with_search: "#", }, { diff --git a/web/tests/message_events.test.cjs b/web/tests/message_events.test.cjs index cab4aac724..70e3549d54 100644 --- a/web/tests/message_events.test.cjs +++ b/web/tests/message_events.test.cjs @@ -134,7 +134,7 @@ run_test("update_messages", ({override}) => { assert.deepEqual(rendered_mgs, [ { display_reply_to: undefined, - alerted: false, + watched: false, clean_reactions: new Map(), collapsed: false, content: "new content", diff --git a/web/tests/message_store.test.cjs b/web/tests/message_store.test.cjs index 3eb77ae311..a8cdc733cb 100644 --- a/web/tests/message_store.test.cjs +++ b/web/tests/message_store.test.cjs @@ -118,7 +118,7 @@ test("process_new_message", () => { assert.equal(message.reply_to, "bob@example.com,cindy@example.com"); assert.equal(message.to_user_ids, "103,104"); assert.equal(message.display_reply_to, "Bob, Cindy"); - assert.equal(message.alerted, true); + assert.equal(message.watched, true); assert.equal(message.is_me_message, false); const retrieved_message = message_store.get(2067); @@ -151,7 +151,7 @@ test("process_new_message", () => { message = message_helper.process_new_message(message); assert.equal(message.reply_to, "denise@example.com"); assert.deepEqual(message.flags, undefined); - assert.equal(message.alerted, false); + assert.equal(message.watched, false); assert.deepEqual(message_user_ids.user_ids().sort(), [ me.user_id, @@ -187,7 +187,7 @@ test("message_booleans_parity", () => { mentioned_me_directly: false, stream_wildcard_mentioned: true, topic_wildcard_mentioned: false, - alerted: false, + watched: false, }); assert_bool_match(["topic_wildcard_mentioned"], { @@ -195,7 +195,7 @@ test("message_booleans_parity", () => { mentioned_me_directly: false, stream_wildcard_mentioned: false, topic_wildcard_mentioned: true, - alerted: false, + watched: false, }); assert_bool_match(["mentioned"], { @@ -203,7 +203,7 @@ test("message_booleans_parity", () => { mentioned_me_directly: true, stream_wildcard_mentioned: false, topic_wildcard_mentioned: false, - alerted: false, + watched: false, }); assert_bool_match(["has_alert_word"], { @@ -211,7 +211,7 @@ test("message_booleans_parity", () => { mentioned_me_directly: false, stream_wildcard_mentioned: false, topic_wildcard_mentioned: false, - alerted: true, + watched: true, }); }); @@ -269,7 +269,7 @@ test("update_booleans", () => { message.mentioned_me_directly = false; message.stream_wildcard_mentioned = false; message.topic_wildcard_mentioned = false; - message.alerted = false; + message.watched = false; let flags = ["mentioned", "has_alert_word", "read"]; message_store.update_booleans(message, flags); @@ -277,7 +277,7 @@ test("update_booleans", () => { assert.equal(message.mentioned_me_directly, true); assert.equal(message.stream_wildcard_mentioned, false); assert.equal(message.topic_wildcard_mentioned, false); - assert.equal(message.alerted, true); + assert.equal(message.watched, true); flags = ["stream_wildcard_mentioned", "unread"]; message_store.update_booleans(message, flags); @@ -297,7 +297,7 @@ test("update_booleans", () => { message_store.update_booleans(message, flags); assert.equal(message.mentioned, false); assert.equal(message.mentioned_me_directly, false); - assert.equal(message.alerted, false); + assert.equal(message.watched, false); assert.equal(message.stream_wildcard_mentioned, false); assert.equal(message.topic_wildcard_mentioned, false); diff --git a/web/tests/narrow_local.test.cjs b/web/tests/narrow_local.test.cjs index c4d6bd2883..bcb86eadc3 100644 --- a/web/tests/narrow_local.test.cjs +++ b/web/tests/narrow_local.test.cjs @@ -285,16 +285,16 @@ run_test("is:mentioned with no unreads and no matches", () => { test_with(fixture); }); -run_test("is:alerted with no unreads and one match", () => { +run_test("is:watched with no unreads and one match", () => { const fixture = { - filter_terms: [{operator: "is", operand: "alerted"}], + filter_terms: [{operator: "is", operand: "watched"}], unread_info: { flavor: "not_found", }, has_found_newest: true, all_messages: [ - {id: 55, topic: "whatever", alerted: true}, - {id: 57, topic: "whatever", alerted: false}, + {id: 55, topic: "whatever", watched: true}, + {id: 57, topic: "whatever", watched: false}, ], expected_id_info: { target_id: undefined, diff --git a/web/tests/search_suggestion.test.cjs b/web/tests/search_suggestion.test.cjs index 8b442e110c..8bbef84e88 100644 --- a/web/tests/search_suggestion.test.cjs +++ b/web/tests/search_suggestion.test.cjs @@ -164,7 +164,6 @@ test("dm_suggestions", ({override, mock_template}) => { suggestions = get_suggestions(query); expected = [ "is:dm al", - "is:dm is:alerted", "is:dm dm:alice@zulip.com", "is:dm sender:alice@zulip.com", "is:dm dm-including:alice@zulip.com", @@ -238,16 +237,15 @@ test("dm_suggestions", ({override, mock_template}) => { assert.deepEqual(suggestions.strings, expected); // Make sure suggestions still work if preceding tokens - query = "is:alerted sender:ted@zulip.com"; + query = "is:watched sender:ted@zulip.com"; suggestions = get_suggestions(query); - expected = ["is:alerted sender:ted@zulip.com", "is:alerted"]; + expected = ["is:watched sender:ted@zulip.com", "is:watched"]; assert.deepEqual(suggestions.strings, expected); query = "is:starred has:link is:dm al"; suggestions = get_suggestions(query); expected = [ "is:starred has:link is:dm al", - "is:starred has:link is:dm is:alerted", "is:starred has:link is:dm dm:alice@zulip.com", "is:starred has:link is:dm sender:alice@zulip.com", "is:starred has:link is:dm dm-including:alice@zulip.com", @@ -374,7 +372,7 @@ test("empty_query_suggestions", () => { "is:starred", "is:mentioned", "is:followed", - "is:alerted", + "is:watched", "is:unread", "is:resolved", "sender:myself@zulip.com", @@ -394,7 +392,7 @@ test("empty_query_suggestions", () => { assert.equal(describe("is:dm"), "Direct messages"); assert.equal(describe("is:starred"), "Starred messages"); assert.equal(describe("is:mentioned"), "@-mentions"); - assert.equal(describe("is:alerted"), "Messages with watched phrases"); + assert.equal(describe("is:watched"), "Messages with watched phrases"); assert.equal(describe("is:unread"), "Unread messages"); assert.equal(describe("is:resolved"), "Topics marked as resolved"); assert.equal(describe("is:followed"), "Followed topics"); @@ -457,9 +455,9 @@ test("has_suggestions", ({override, mock_template}) => { assert.deepEqual(suggestions.strings, expected); // 66 is misc channel id. - query = "channel:66 is:alerted has:lin"; + query = "channel:66 is:watched has:lin"; suggestions = get_suggestions(query); - expected = ["channel:66 is:alerted has:link", "channel:66 is:alerted", "channel:66"]; + expected = ["channel:66 is:watched has:link", "channel:66 is:watched", "channel:66"]; assert.deepEqual(suggestions.strings, expected); }); @@ -477,7 +475,7 @@ test("check_is_suggestions", ({override, mock_template}) => { "is:starred", "is:mentioned", "is:followed", - "is:alerted", + "is:watched", "is:unread", "is:resolved", "dm:alice@zulip.com", @@ -494,7 +492,7 @@ test("check_is_suggestions", ({override, mock_template}) => { assert.equal(describe("is:dm"), "Direct messages"); assert.equal(describe("is:starred"), "Starred messages"); assert.equal(describe("is:mentioned"), "@-mentions"); - assert.equal(describe("is:alerted"), "Messages with watched phrases"); + assert.equal(describe("is:watched"), "Messages with watched phrases"); assert.equal(describe("is:unread"), "Unread messages"); assert.equal(describe("is:resolved"), "Topics marked as resolved"); assert.equal(describe("is:followed"), "Followed topics"); @@ -507,7 +505,7 @@ test("check_is_suggestions", ({override, mock_template}) => { "-is:starred", "-is:mentioned", "-is:followed", - "-is:alerted", + "-is:watched", "-is:unread", "-is:resolved", ]; @@ -516,7 +514,7 @@ test("check_is_suggestions", ({override, mock_template}) => { assert.equal(describe("-is:dm"), "Exclude direct messages"); assert.equal(describe("-is:starred"), "Exclude starred messages"); assert.equal(describe("-is:mentioned"), "Exclude @-mentions"); - assert.equal(describe("-is:alerted"), "Exclude messages with watched phrases"); + assert.equal(describe("-is:watched"), "Exclude messages with watched phrases"); assert.equal(describe("-is:unread"), "Exclude unread messages"); assert.equal(describe("-is:resolved"), "Exclude topics marked as resolved"); assert.equal(describe("-is:followed"), "Exclude followed topics"); @@ -530,7 +528,7 @@ test("check_is_suggestions", ({override, mock_template}) => { "is:starred", "is:mentioned", "is:followed", - "is:alerted", + "is:watched", "is:unread", "is:resolved", ]; @@ -707,13 +705,13 @@ test("topic_suggestions", ({override, mock_template}) => { ]; assert.deepEqual(suggestions.strings, expected); - suggestions = get_suggestions(`is:alerted channel:${devel_id} is:starred topic:`); + suggestions = get_suggestions(`is:watched channel:${devel_id} is:starred topic:`); expected = [ - `is:alerted channel:${devel_id} is:starred topic:`, - `is:alerted channel:${devel_id} is:starred topic:REXX`, - `is:alerted channel:${devel_id} is:starred`, - `is:alerted channel:${devel_id}`, - "is:alerted", + `is:watched channel:${devel_id} is:starred topic:`, + `is:watched channel:${devel_id} is:starred topic:REXX`, + `is:watched channel:${devel_id} is:starred`, + `is:watched channel:${devel_id}`, + "is:watched", ]; assert.deepEqual(suggestions.strings, expected); @@ -1008,13 +1006,13 @@ test("operator_suggestions", ({override, mock_template}) => { assert.deepEqual(suggestions.strings, expected); // 66 is a misc channel id. - query = "channel:66 is:alerted -f"; + query = "channel:66 is:watched -f"; suggestions = get_suggestions(query); expected = [ - "channel:66 is:alerted -f", - "channel:66 is:alerted -sender:myself@zulip.com", - "channel:66 is:alerted -sender:", - "channel:66 is:alerted", + "channel:66 is:watched -f", + "channel:66 is:watched -sender:myself@zulip.com", + "channel:66 is:watched -sender:", + "channel:66 is:watched", "channel:66", ]; assert.deepEqual(suggestions.strings, expected); diff --git a/zerver/lib/narrow.py b/zerver/lib/narrow.py index fe6ca5879a..4177d0b93a 100644 --- a/zerver/lib/narrow.py +++ b/zerver/lib/narrow.py @@ -403,7 +403,7 @@ class NarrowBuilder: ) cond = column("flags", Integer).op("&")(mention_flags_mask) != 0 return query.where(maybe_negate(cond)) - elif operand == "alerted": + elif operand in ["alerted", "watched"]: cond = column("flags", Integer).op("&")(UserMessage.flags.has_alert_word.mask) != 0 return query.where(maybe_negate(cond)) elif operand == "resolved": diff --git a/zerver/lib/narrow_predicate.py b/zerver/lib/narrow_predicate.py index 954f578916..d3fa771b60 100644 --- a/zerver/lib/narrow_predicate.py +++ b/zerver/lib/narrow_predicate.py @@ -63,7 +63,7 @@ def build_narrow_predicate( elif operator == "is" and operand == "unread": if "read" in flags: return False - elif operator == "is" and operand in ["alerted", "mentioned"]: + elif operator == "is" and operand in ["alerted", "mentioned", "watched"]: if "mentioned" not in flags: return False elif operator == "is" and operand == "resolved": diff --git a/zerver/tests/test_message_fetch.py b/zerver/tests/test_message_fetch.py index 6c59a8faaa..d701dbfac0 100644 --- a/zerver/tests/test_message_fetch.py +++ b/zerver/tests/test_message_fetch.py @@ -228,7 +228,7 @@ class NarrowBuilderTest(ZulipTestCase): self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) = %(param_1)s") def test_add_term_using_is_operator_and_non_dm_operand(self) -> None: - for operand in ["starred", "mentioned", "alerted"]: + for operand in ["starred", "mentioned", "alerted", "watched"]: term = NarrowParameter(operator="is", operand=operand) self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s") @@ -257,6 +257,16 @@ class NarrowBuilderTest(ZulipTestCase): ) self._do_add_term_test(term, where_clause, params) + self._do_add_term_test(term, where_clause, params) + + term = NarrowParameter(operator="is", operand="watched", negated=True) + where_clause = "WHERE (flags & %(flags_1)s) = %(param_1)s" + params = dict( + flags_1=UserMessage.flags.has_alert_word.mask, + param_1=0, + ) + self._do_add_term_test(term, where_clause, params) + term = NarrowParameter(operator="is", operand="mentioned", negated=True) where_clause = "WHERE (flags & %(flags_1)s) = %(param_1)s" mention_flags_mask = ( @@ -897,6 +907,13 @@ class NarrowLibraryTest(ZulipTestCase): ) ) + self.assertFalse( + narrow_predicate( + message={}, + flags=["watched"], + ) + ) + ### narrow_predicate = build_narrow_predicate([NarrowTerm(operator="is", operand="alerted")]) @@ -917,6 +934,24 @@ class NarrowLibraryTest(ZulipTestCase): ### + narrow_predicate = build_narrow_predicate([NarrowTerm(operator="is", operand="watched")]) + + self.assertTrue( + narrow_predicate( + message={}, + flags=["mentioned"], + ) + ) + + self.assertFalse( + narrow_predicate( + message={}, + flags=["starred"], + ) + ) + + ### + narrow_predicate = build_narrow_predicate([NarrowTerm(operator="is", operand="mentioned")]) self.assertTrue( @@ -1155,6 +1190,11 @@ class IncludeHistoryTest(ZulipTestCase): NarrowParameter(operator="is", operand="alerted"), ] self.assertFalse(ok_to_include_history(narrow, user_profile, False)) + narrow = [ + NarrowParameter(operator="channels", operand="public"), + NarrowParameter(operator="is", operand="watched"), + ] + self.assertFalse(ok_to_include_history(narrow, user_profile, False)) narrow = [ NarrowParameter(operator="channels", operand="public"), NarrowParameter(operator="is", operand="resolved"),