From 55f80a25025c06f8a9741125773040b5746bc98a Mon Sep 17 00:00:00 2001 From: Aman Agrawal Date: Sun, 12 Jul 2020 20:15:42 +0530 Subject: [PATCH] recent_topics: Don't render topic of deactivatedstreams. Fixes error when trying to render topic of a deactivated stream in the Recent Topics widget. --- frontend_tests/node_tests/recent_topics.js | 39 +++++++++++++++------- static/js/recent_topics.js | 17 +++++++--- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/frontend_tests/node_tests/recent_topics.js b/frontend_tests/node_tests/recent_topics.js index 632554fc02..8a035130c0 100644 --- a/frontend_tests/node_tests/recent_topics.js +++ b/frontend_tests/node_tests/recent_topics.js @@ -7,18 +7,6 @@ set_global('$', global.make_zjquery({ set_global('hashchange', { exit_overlay: noop, }); -set_global('stream_data', { - get_sub_by_id: () => ({ - color: "", - invite_only: false, - is_web_public: true, - }), - is_muted: () => - // We only test via muted topics for now. - // TODO: Make muted streams and test them. - false - , -}); set_global('overlays', { open_overlay: (opts) => { overlays.close_callback = opts.on_close; @@ -89,6 +77,7 @@ const stream1 = 1; const stream2 = 2; const stream3 = 3; const stream4 = 4; +const stream5 = 5; // Deleted stream // Topics in the stream, all unread except topic1 & stream1. const topic1 = "topic-1"; // No Other sender & read. @@ -128,6 +117,25 @@ set_global('message_list', { set_global('message_store', { get: (msg_id) => messages[msg_id - 1], }); +set_global('stream_data', { + get_sub_by_id: (stream) => { + if (stream === stream5) { + // No data is available for deactivated streams + return; + } + + return { + color: "", + invite_only: false, + is_web_public: true, + }; + }, + is_muted: () => + // We only test via muted topics for now. + // TODO: Make muted streams and test them. + false + , +}); let id = 0; @@ -681,6 +689,13 @@ run_test('test_topic_edit', () => { assert.equal(all_topics.get(get_topic_key(stream2, topic1)), undefined); verify_topic_data(all_topics, stream3, topic9, messages[0].id, true); + + // Message was moveed to a deleted stream, hence hidden regardless of filter. + messages[0].stream_id = stream5; + messages[0].topic = topic8; + rt.process_topic_edit(stream3, topic9, topic8, stream5); + all_topics = rt.get(); + assert.equal(rt.filters_should_hide_topic(all_topics.get('5:topic-8')), true); }); run_test('test_search', () => { diff --git a/static/js/recent_topics.js b/static/js/recent_topics.js index 39c0cf732b..f0fb65f48a 100644 --- a/static/js/recent_topics.js +++ b/static/js/recent_topics.js @@ -154,6 +154,10 @@ function format_topic(topic_data) { const stream = last_msg.stream; const stream_id = last_msg.stream_id; const stream_info = stream_data.get_sub_by_id(stream_id); + if (stream_info === undefined) { + // stream was deleted + return {}; + } const topic = last_msg.topic; const time = new XDate(last_msg.timestamp * 1000); const last_msg_time = timerender.last_seen_status_from_date(time); @@ -232,9 +236,14 @@ exports.topic_in_search_results = function (keyword, stream, topic) { }); }; -function filters_should_hide_topic(topic_data) { +exports.filters_should_hide_topic = function (topic_data) { const msg = message_store.get(topic_data.last_msg_id); + if (stream_data.get_sub_by_id(msg.stream_id) === undefined) { + // Never try to process deactivated streams. + return true; + } + if (filters.has('unread')) { const unreadCount = unread.unread_topic_counter.get(msg.stream_id, msg.topic); if (unreadCount === 0) { @@ -260,7 +269,7 @@ function filters_should_hide_topic(topic_data) { } return false; -} +}; exports.inplace_rerender = function (topic_key) { if (!overlays.recent_topics_open()) { @@ -274,7 +283,7 @@ exports.inplace_rerender = function (topic_key) { topics_widget.render_item(topic_data); const topic_row = get_topic_row(topic_data); - if (filters_should_hide_topic(topic_data)) { + if (exports.filters_should_hide_topic(topic_data)) { topic_row.hide(); } else { topic_row.show(); @@ -402,7 +411,7 @@ exports.complete_rerender = function () { // We use update_filters_view & filters_should_hide_topic to do all the // filtering for us, which is called using click_handlers. predicate: function (topic_data) { - return !filters_should_hide_topic(topic_data); + return !exports.filters_should_hide_topic(topic_data); }, }, sort_fields: {