diff --git a/web/src/reactions.ts b/web/src/reactions.ts index a3beafb8f4..edc896d573 100644 --- a/web/src/reactions.ts +++ b/web/src/reactions.ts @@ -579,27 +579,35 @@ function make_clean_reaction({ emoji_details.reaction_type === "realm_emoji" || emoji_details.reaction_type === "zulip_extra_emoji"; - const count = user_ids.length; - const label = generate_title(emoji_name, user_ids); - - const reaction_class = user_ids.includes(current_user.user_id) - ? "message_reaction reacted" - : "message_reaction"; - - // The vote_text field set here is used directly in the Handlebars - // template for rendering (or rerendering!) a message. - const vote_text = get_vote_text(user_ids, should_display_reactors); - return { local_id, user_ids, ...emoji_details, emoji_alt_code, is_realm_emoji, - class: reaction_class, - count, - label, - vote_text, + ...build_reaction_data(user_ids, emoji_name, should_display_reactors), + }; +} + +function build_reaction_data( + user_ids: number[], + emoji_name: string, + should_display_reactors: boolean, +): { + count: number; + label: string; + class: string; + vote_text: string; +} { + return { + count: user_ids.length, + label: generate_title(emoji_name, user_ids), + class: user_ids.includes(current_user.user_id) + ? "message_reaction reacted" + : "message_reaction", + // The vote_text field set here is used directly in the Handlebars + // template for rendering (or rerendering!) a message. + vote_text: get_vote_text(user_ids, should_display_reactors), }; } @@ -611,30 +619,14 @@ export function update_user_fields( // who reacted on a message might have changed, including due to // upvote/downvotes on ANY reaction in the message, because those // can change the correct value of should_display_reactors to use. - clean_reaction_object.count = clean_reaction_object.user_ids.length; - clean_reaction_object.label = generate_title( - clean_reaction_object.emoji_name, - clean_reaction_object.user_ids, - ); - - if (clean_reaction_object.user_ids.includes(current_user.user_id)) { - clean_reaction_object.class = "message_reaction reacted"; - } else { - clean_reaction_object.class = "message_reaction"; - } - - clean_reaction_object.count = clean_reaction_object.user_ids.length; - clean_reaction_object.label = generate_title( - clean_reaction_object.emoji_name, - clean_reaction_object.user_ids, - ); - - // The vote_text field set here is used directly in the Handlebars - // template for rendering (or rerendering!) a message. - clean_reaction_object.vote_text = get_vote_text( - clean_reaction_object.user_ids, - should_display_reactors, - ); + Object.assign(clean_reaction_object, { + ...clean_reaction_object, + ...build_reaction_data( + clean_reaction_object.user_ids, + clean_reaction_object.emoji_name, + should_display_reactors, + ), + }); } type ReactionUserIdAndCount = { diff --git a/web/tests/reactions.test.js b/web/tests/reactions.test.js index 972c8568f3..d282273fe2 100644 --- a/web/tests/reactions.test.js +++ b/web/tests/reactions.test.js @@ -1177,6 +1177,22 @@ test("remove_reaction_from_view (last person)", () => { assert.ok(removed); }); +test("bogus_event", ({override}) => { + // We don't expect errors when we process events with + // bad message ids. + override(message_store, "get", noop); + + const bogus_event = { + message_id: 55, + reaction_type: "realm_emoji", + emoji_name: "realm_emoji", + emoji_code: "991", + user_id: 99, + }; + reactions.add_reaction(bogus_event); + reactions.remove_reaction(bogus_event); +}); + test("remove spurious user", ({override}) => { // get coverage for removing non-user (it should just // silently fail)