diff --git a/frontend_tests/node_tests/message_fetch.js b/frontend_tests/node_tests/message_fetch.js index b119fc74f3..f34083bf38 100644 --- a/frontend_tests/node_tests/message_fetch.js +++ b/frontend_tests/node_tests/message_fetch.js @@ -12,6 +12,7 @@ zrequire('Filter', 'js/filter'); zrequire('MessageListData', 'js/message_list_data'); zrequire('message_list'); zrequire('util'); +zrequire('people'); set_global('page_params', { have_initial_messages: true, @@ -37,6 +38,13 @@ set_global('stream_list', { maybe_scroll_narrow_into_view: () => {}, }); +var alice = { + email: 'alice@example.com', + user_id: 7, + full_name: 'Alice', +}; +people.add(alice); + muting.is_topic_muted = function () { return false; }; resize.resize_bottom_whitespace = noop; server_events.home_view_loaded = noop; @@ -273,7 +281,7 @@ function simulate_narrow() { narrow_state.active = function () { return true; }; narrow_state.public_operators = function () { - return 'operators-stub'; + return [{ operator: 'pm-with', operand: alice.email }]; }; var msg_list = new message_list.MessageList({ @@ -321,7 +329,7 @@ run_test('loading_newer', () => { anchor: '444', num_before: 0, num_after: 100, - narrow: '"operators-stub"', + narrow: `[{"operator":"pm-with","operand":[${alice.user_id}]}]`, client_gravatar: true, }, resp: { diff --git a/frontend_tests/node_tests/people.js b/frontend_tests/node_tests/people.js index f931c2c8fd..304d170508 100644 --- a/frontend_tests/node_tests/people.js +++ b/frontend_tests/node_tests/people.js @@ -853,3 +853,29 @@ run_test('initialize', () => { assert.equal(global.page_params.cross_realm_bots, undefined); assert.equal(global.page_params.realm_non_active_users, undefined); }); + +run_test('emails_strings_to_user_ids_array', function () { + const steven = { + email: 'steven@example.com', + user_id: 7, + full_name: 'Steven', + }; + + const maria = { + email: 'maria@example.com', + user_id: 728, + full_name: 'Maria', + }; + + people.add(steven); + people.add(maria); + + let user_ids = people.emails_strings_to_user_ids_array(`${steven.email},${maria.email}`); + assert.deepEqual(user_ids, [steven.user_id, maria.user_id]); + + blueslip.set_test_data('warn', 'Unknown emails: dummyuser@example.com'); + user_ids = people.emails_strings_to_user_ids_array('dummyuser@example.com'); + assert.equal(user_ids, undefined); + assert.equal(blueslip.get_test_logs('warn').length, 1); + blueslip.clear_test_data(); +}); diff --git a/static/js/message_fetch.js b/static/js/message_fetch.js index bbcefcb51d..50f62ebd49 100644 --- a/static/js/message_fetch.js +++ b/static/js/message_fetch.js @@ -104,6 +104,29 @@ function get_messages_success(data, opts) { resize.resize_bottom_whitespace(); } +// This function modifies the data.narrow filters to use user IDs +// instead of emails string if it is supported. We currently don't set +// or convert the emails string to user IDs directly into the Filter code +// because doing so breaks the app in various modules that expect emails string. +function handle_user_ids_supported_operators(data) { + var user_ids_supported_operators = ['pm-with']; + + if (data.narrow === undefined) { + return data; + } + + data.narrow = JSON.parse(data.narrow); + data.narrow = _.map(data.narrow, function (filter) { + if (user_ids_supported_operators.indexOf(filter.operator) !== -1) { + filter.operand = people.emails_strings_to_user_ids_array(filter.operand); + } + + return filter; + }); + + data.narrow = JSON.stringify(data.narrow); + return data; +} exports.load_messages = function (opts) { var data = {anchor: opts.anchor, @@ -139,6 +162,7 @@ exports.load_messages = function (opts) { } data.client_gravatar = true; + data = handle_user_ids_supported_operators(data); channel.get({ url: '/json/messages', diff --git a/static/js/people.js b/static/js/people.js index b2c57e7448..748e1d4583 100644 --- a/static/js/people.js +++ b/static/js/people.js @@ -188,6 +188,16 @@ exports.user_ids_string_to_ids_array = function (user_ids_string) { return ids; }; +exports.emails_strings_to_user_ids_array = function (emails_string) { + var user_ids_string = exports.emails_strings_to_user_ids_string(emails_string); + if (user_ids_string === undefined) { + return; + } + + var user_ids_array = exports.user_ids_string_to_ids_array(user_ids_string); + return user_ids_array; +}; + exports.reply_to_to_user_ids_string = function (emails_string) { // This is basically emails_strings_to_user_ids_string // without blueslip warnings, since it can be called with diff --git a/zerver/views/messages.py b/zerver/views/messages.py index 6339aea809..b38e53f862 100644 --- a/zerver/views/messages.py +++ b/zerver/views/messages.py @@ -510,6 +510,10 @@ def narrow_parameter(json: str) -> Optional[List[Dict[str, Any]]]: return dict(operator=elem[0], operand=elem[1]) if isinstance(elem, dict): + # Make sure to sync this list to frontend also when adding a new operator. + # that supports user IDs. Relevant code is located in static/js/message_fetch.js + # in handle_user_ids_supported_operators function where you will need to update + # the user_ids_supported_operator. user_ids_supported_operators = ['pm-with'] if elem.get('operator', '') in user_ids_supported_operators: operand_validator = check_string_or_int_list