Repository: zulip/zulip-terminal

Issue:
Display names of reacting users when few users have reacted in ZT
To display reacting users when few users have reacted, as shown below -

![image](https://user-images.githubusercontent.com/53873549/164523523-81acd3d8-cf29-4b7e-8cd1-3133705783ab.png)


Discussion:
srdeotarse: @zulipbot add "PR needs review".
srdeotarse: @zulipbot add "PR needs review".
zulipbot: **ERROR:** Label "PR needs review" already exists and was thus not added to this pull request.

srdeotarse: @zulipbot add "PR needs review".
srdeotarse: @zulipbot add "PR needs review".
zulipbot: Heads up @srdeotarse, we just merged some commits that conflict with the changes your made in this pull request! You can review this repository's [recent commits](https://github.com/zulip/zulip-terminal/commits/main) to see where the conflicts occur. Please rebase your feature branch against the `upstream/main` branch and [resolve](https://zulip.readthedocs.io/en/latest/git/troubleshooting.html#recover-from-a-git-rebase-failure) your pull request's merge conflicts accordingly.

<!-- mergeConflictWarning -->

neiljp: @srdeotarse I left some notes in the stream. This is essentially fine now, just a few minor points outstanding which we can discuss, though it'd be fairly easy to adjust slightly before merging. The code can be adjusted, but it has essentially the same behavior as before so we're mostly just tidying/optimizing at this point.
neiljp: @srdeotarse I'm going to merge the last two commits now, with a few minor changes, thanks! :tada:

I didn't expect you to strip the last commit back out, but the code did work before as far as i could tell, so as I said I'm happy to merge the previous state, particularly with the extracted constant added.

I slightly adjusted some commit text and test parameter names, and (re)moved a few lines between commits where the formatting fitted better. Please do check the difference using `git range-diff`. See the recent topic about that if you need to review the command. If you have questions, please do follow-up in the appropriate topic :)

Patch:
diff --git a/zulipterminal/ui_tools/boxes.py b/zulipterminal/ui_tools/boxes.py
index 990290e..12f8a53 100644
--- a/zulipterminal/ui_tools/boxes.py
+++ b/zulipterminal/ui_tools/boxes.py
@@ -1112,18 +1112,31 @@ class MessageBox(urwid.Pile):
         if not reactions:
             return ""
         try:
+            MAXIMUM_USERNAMES_VISIBLE = 3
+            my_user_id = self.model.user_id
             reaction_stats = defaultdict(list)
             for reaction in reactions:
                 user_id = int(reaction["user"].get("id", -1))
                 if user_id == -1:
                     user_id = int(reaction["user"]["user_id"])
-                reaction_stats[reaction["emoji_name"]].append(user_id)
+                user_name = reaction["user"]["full_name"]
+                if user_id == my_user_id:
+                    user_name = "You"
+                reaction_stats[reaction["emoji_name"]].append((user_id, user_name))
+
+            for reaction, ids in reaction_stats.items():
+                if (my_user_id, "You") in ids:
+                    ids.remove((my_user_id, "You"))
+                    ids.append((my_user_id, "You"))
 
-            my_user_id = self.model.user_id
             reaction_texts = [
                 (
-                    "reaction_mine" if my_user_id in ids else "reaction",
-                    f" :{reaction}: {len(ids)} ",
+                    "reaction_mine"
+                    if my_user_id in [id[0] for id in ids]
+                    else "reaction",
+                    f" :{reaction}: {len(ids)} "
+                    if len(reactions) > MAXIMUM_USERNAMES_VISIBLE
+                    else f" :{reaction}: {', '.join([id[1] for id in ids])} ",
                 )
                 for reaction, ids in reaction_stats.items()
             ]


Test patch:
diff --git a/tests/ui/test_ui_tools.py b/tests/ui/test_ui_tools.py
index 0eed60b..1555d92 100644
--- a/tests/ui/test_ui_tools.py
+++ b/tests/ui/test_ui_tools.py
@@ -2736,55 +2736,227 @@ class TestMessageBox:
 
     # FIXME This is the same parametrize as MsgInfoView:test_height_reactions
     @pytest.mark.parametrize(
-        "to_vary_in_each_message",
+        "to_vary_in_each_message, expected_text, expected_attributes",
         [
-            {
-                "reactions": [
-                    {
-                        "emoji_name": "thumbs_up",
-                        "emoji_code": "1f44d",
-                        "user": {
-                            "email": "iago@zulip.com",
-                            "full_name": "Iago",
-                            "id": 5,
+            case(
+                {
+                    "reactions": [
+                        {
+                            "emoji_name": "thumbs_up",
+                            "emoji_code": "1f44d",
+                            "user": {
+                                "email": "iago@zulip.com",
+                                "full_name": "Iago",
+                                "id": 5,
+                            },
+                            "reaction_type": "unicode_emoji",
                         },
-                        "reaction_type": "unicode_emoji",
-                    },
-                    {
-                        "emoji_name": "zulip",
-                        "emoji_code": "zulip",
-                        "user": {
-                            "email": "iago@zulip.com",
-                            "full_name": "Iago",
-                            "id": 5,
+                        {
+                            "emoji_name": "zulip",
+                            "emoji_code": "zulip",
+                            "user": {
+                                "email": "iago@zulip.com",
+                                "full_name": "Iago",
+                                "id": 5,
+                            },
+                            "reaction_type": "zulip_extra_emoji",
                         },
-                        "reaction_type": "zulip_extra_emoji",
-                    },
-                    {
-                        "emoji_name": "zulip",
-                        "emoji_code": "zulip",
-                        "user": {
-                            "email": "AARON@zulip.com",
-                            "full_name": "aaron",
-                            "id": 1,
+                        {
+                            "emoji_name": "zulip",
+                            "emoji_code": "zulip",
+                            "user": {
+                                "email": "AARON@zulip.com",
+                                "full_name": "aaron",
+                                "id": 1,
+                            },
+                            "reaction_type": "zulip_extra_emoji",
                         },
-                        "reaction_type": "zulip_extra_emoji",
-                    },
-                    {
-                        "emoji_name": "heart",
-                        "emoji_code": "2764",
-                        "user": {
-                            "email": "iago@zulip.com",
-                            "full_name": "Iago",
-                            "id": 5,
+                        {
+                            "emoji_name": "heart",
+                            "emoji_code": "2764",
+                            "user": {
+                                "email": "iago@zulip.com",
+                                "full_name": "Iago",
+                                "id": 5,
+                            },
+                            "reaction_type": "unicode_emoji",
                         },
-                        "reaction_type": "unicode_emoji",
-                    },
-                ]
-            }
+                    ],
+                },
+                " :thumbs_up: 1   :zulip: 2   :heart: 1  ",
+                [
+                    ("reaction", 15),
+                    (None, 1),
+                    ("reaction_mine", 11),
+                    (None, 1),
+                    ("reaction", 11),
+                ],
+            ),
+            case(
+                {
+                    "reactions": [
+                        {
+                            "emoji_name": "thumbs_up",
+                            "emoji_code": "1f44d",
+                            "user": {
+                                "email": "iago@zulip.com",
+                                "full_name": "Iago",
+                                "id": 5,
+                            },
+                            "reaction_type": "unicode_emoji",
+                        },
+                        {
+                            "emoji_name": "zulip",
+                            "emoji_code": "zulip",
+                            "user": {
+                                "email": "AARON@zulip.com",
+                                "full_name": "aaron",
+                                "id": 1,
+                            },
+                            "reaction_type": "zulip_extra_emoji",
+                        },
+                        {
+                            "emoji_name": "heart",
+                            "emoji_code": "2764",
+                            "user": {
+                                "email": "iago@zulip.com",
+                                "full_name": "Iago",
+                                "id": 5,
+                            },
+                            "reaction_type": "unicode_emoji",
+                        },
+                    ],
+                },
+                " :thumbs_up: Iago   :zulip: You   :heart: Iago  ",
+                [
+                    ("reaction", 18),
+                    (None, 1),
+                    ("reaction_mine", 13),
+                    (None, 1),
+                    ("reaction", 14),
+                ],
+            ),
+            case(
+                {
+                    "reactions": [
+                        {
+                            "emoji_name": "zulip",
+                            "emoji_code": "zulip",
+                            "user": {
+                                "email": "iago@zulip.com",
+                                "full_name": "Iago",
+                                "id": 5,
+                            },
+                            "reaction_type": "unicode_emoji",
+                        },
+                        {
+                            "emoji_name": "zulip",
+                            "emoji_code": "zulip",
+                            "user": {
+                                "email": "AARON@zulip.com",
+                                "full_name": "aaron",
+                                "id": 1,
+                            },
+                            "reaction_type": "zulip_extra_emoji",
+                        },
+                        {
+                            "emoji_name": "zulip",
+                            "emoji_code": "zulip",
+                            "user": {
+                                "email": "shivam@zulip.com",
+                                "full_name": "Shivam",
+                                "id": 6,
+                            },
+                            "reaction_type": "unicode_emoji",
+                        },
+                    ],
+                },
+                " :zulip: Iago, Shivam, You  ",
+                [
+                    ("reaction_mine", 27),
+                ],
+            ),
+            case(
+                {
+                    "reactions": [
+                        {
+                            "emoji_name": "heart",
+                            "emoji_code": "2764",
+                            "user": {
+                                "email": "iago@zulip.com",
+                                "full_name": "Iago",
+                                "id": 5,
+                            },
+                            "reaction_type": "unicode_emoji",
+                        },
+                        {
+                            "emoji_name": "zulip",
+                            "emoji_code": "zulip",
+                            "user": {
+                                "email": "AARON@zulip.com",
+                                "full_name": "aaron",
+                                "id": 1,
+                            },
+                            "reaction_type": "zulip_extra_emoji",
+                        },
+                        {
+                            "emoji_name": "zulip",
+                            "emoji_code": "zulip",
+                            "user": {
+                                "email": "shivam@zulip.com",
+                                "full_name": "Shivam",
+                                "id": 6,
+                            },
+                            "reaction_type": "unicode_emoji",
+                        },
+                    ],
+                },
+                " :heart: Iago   :zulip: Shivam, You  ",
+                [
+                    ("reaction", 14),
+                    (None, 1),
+                    ("reaction_mine", 21),
+                ],
+            ),
+            case(
+                {
+                    "reactions": [
+                        {
+                            "emoji_name": "zulip",
+                            "emoji_code": "zulip",
+                            "user": {
+                                "email": "AARON@zulip.com",
+                                "full_name": "aaron",
+                                "id": 1,
+                            },
+                            "reaction_type": "zulip_extra_emoji",
+                        },
+                        {
+                            "emoji_name": "zulip",
+                            "emoji_code": "zulip",
+                            "user": {
+                                "email": "shivam@zulip.com",
+                                "full_name": "Shivam",
+                                "id": 6,
+                            },
+                            "reaction_type": "unicode_emoji",
+                        },
+                    ],
+                },
+                " :zulip: Shivam, You  ",
+                [
+                    ("reaction_mine", 21),
+                ],
+            ),
         ],
     )
-    def test_reactions_view(self, message_fixture, to_vary_in_each_message):
+    def test_reactions_view(
+        self,
+        message_fixture,
+        to_vary_in_each_message,
+        expected_text,
+        expected_attributes,
+    ):
         self.model.user_id = 1
         varied_message = dict(message_fixture, **to_vary_in_each_message)
         msg_box = MessageBox(varied_message, self.model, None)
@@ -2792,16 +2964,8 @@ class TestMessageBox:
 
         reactions_view = msg_box.reactions_view(reactions)
 
-        assert reactions_view.original_widget.text == (
-            " :thumbs_up: 1   :zulip: 2   :heart: 1  "
-        )
-        assert reactions_view.original_widget.attrib == [
-            ("reaction", 15),
-            (None, 1),
-            ("reaction_mine", 11),
-            (None, 1),
-            ("reaction", 11),
-        ]
+        assert reactions_view.original_widget.text == expected_text
+        assert reactions_view.original_widget.attrib == expected_attributes
 
     @pytest.mark.parametrize(
         "message_links, expected_text, expected_attrib, expected_footlinks_width",