Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Polls Widget on ZT. #1551

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/hotkeys.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,5 @@
|View current message in browser|<kbd>v</kbd>|
|Show/hide full rendered message|<kbd>f</kbd>|
|Show/hide full raw message|<kbd>r</kbd>|
|Show/hide poll voter list|<kbd>w</kbd>|

322 changes: 321 additions & 1 deletion tests/widget/test_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
import pytest
from pytest import param as case

from zulipterminal.widget import Submessage, find_widget_type, process_todo_widget
from zulipterminal.widget import (
Submessage,
find_widget_type,
process_poll_widget,
process_todo_widget,
)


@pytest.mark.parametrize(
Expand Down Expand Up @@ -343,3 +348,318 @@ def test_process_todo_widget(

assert title == expected_title
assert tasks == expected_tasks


@pytest.mark.parametrize(
"submessages, expected_poll_question, expected_options",
[
case(
[
{
"id": 12082,
"message_id": 1957499,
"sender_id": 27294,
"msg_type": "widget",
"content": (
'{"widget_type": "poll", "extra_data": {'
'"question": "Do polls work on ZT?", "options": ["Yes", "No"]}}'
),
},
{
"id": 12083,
"message_id": 1957499,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,0","vote":1}',
},
{
"id": 12084,
"message_id": 1957499,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,0","vote":-1}',
},
{
"id": 12085,
"message_id": 1957499,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,1","vote":1}',
},
{
"id": 12086,
"message_id": 1957499,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,0","vote":1}',
},
{
"id": 12087,
"message_id": 1957499,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,1","vote":-1}',
},
],
"Do polls work on ZT?",
{
"canned,0": {"option": "Yes", "votes": [27294]},
"canned,1": {"option": "No", "votes": []},
},
id="multiple_vote_events",
),
case(
[
{
"id": 12089,
"message_id": 1957662,
"sender_id": 27294,
"msg_type": "widget",
"content": (
'{"widget_type": "poll", "extra_data": {"question": "Is '
'this a poll with options added later?", '
'"options": ["Yes", "No"]}}'
),
},
{
"id": 12090,
"message_id": 1957662,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"new_option","idx":1,"option":"Maybe"}',
},
{
"id": 12091,
"message_id": 1957662,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,1","vote":1}',
},
{
"id": 12092,
"message_id": 1957662,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,1","vote":-1}',
},
{
"id": 12093,
"message_id": 1957662,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"27294,1","vote":1}',
},
{
"id": 12094,
"message_id": 1957662,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,0","vote":1}',
},
],
"Is this a poll with options added later?",
{
"canned,0": {"option": "Yes", "votes": [27294]},
"canned,1": {"option": "No", "votes": []},
"27294,1": {"option": "Maybe", "votes": [27294]},
},
id="new_option_and_votes",
),
case(
[
{
"id": 12095,
"message_id": 1957682,
"sender_id": 27294,
"msg_type": "widget",
"content": (
'{"widget_type": "poll", "extra_data": {"question": '
'"Let\'s change this question later?", "options": ["Yes"]}}'
),
},
{
"id": 12096,
"message_id": 1957682,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,0","vote":1}',
},
{
"id": 12097,
"message_id": 1957682,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"new_option","idx":1,"option":"No"}',
},
{
"id": 12098,
"message_id": 1957682,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,0","vote":-1}',
},
{
"id": 12099,
"message_id": 1957682,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"question",'
'"question":"Has this question stayed the same?"}',
},
{
"id": 12100,
"message_id": 1957682,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"27294,1","vote":1}',
},
],
"Has this question stayed the same?",
{
"canned,0": {"option": "Yes", "votes": []},
"27294,1": {"option": "No", "votes": [27294]},
},
id="new_question_and_votes",
),
case(
[
{
"id": 12101,
"message_id": 1957693,
"sender_id": 27294,
"msg_type": "widget",
"content": (
'{"widget_type": "poll", "extra_data": {"question": "",'
' "options": ["Yes", "No"]}}'
),
}
],
"",
{
"canned,0": {"option": "Yes", "votes": []},
"canned,1": {"option": "No", "votes": []},
},
id="empty_question",
),
case(
[
{
"id": 12102,
"message_id": 1957700,
"sender_id": 27294,
"msg_type": "widget",
"content": (
'{"widget_type": "poll", "extra_data": {'
'"question": "Does this poll have options?", "options": []}}'
),
}
],
"Does this poll have options?",
{},
id="empty_options",
),
case(
[
{
"id": 12112,
"message_id": 1957722,
"sender_id": 27294,
"msg_type": "widget",
"content": (
'{"widget_type": "poll", "extra_data": {"question": "",'
' "options": []}}'
),
}
],
"",
{},
id="empty_question_and_options",
),
case(
[
{
"id": 12103,
"message_id": 1957719,
"sender_id": 27294,
"msg_type": "widget",
"content": (
'{"widget_type": "poll", "extra_data": {"question": "Does'
' this poll have multiple voters?", "options": ["Yes", "No"]}}'
),
},
{
"id": 12104,
"message_id": 1957719,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,0","vote":1}',
},
{
"id": 12105,
"message_id": 1957719,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,1","vote":1}',
},
{
"id": 12106,
"message_id": 1957719,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,0","vote":-1}',
},
{
"id": 12107,
"message_id": 1957719,
"sender_id": 32159,
"msg_type": "widget",
"content": '{"type":"new_option","idx":1,"option":"Maybe"}',
},
{
"id": 12108,
"message_id": 1957719,
"sender_id": 32159,
"msg_type": "widget",
"content": '{"type":"vote","key":"32159,1","vote":1}',
},
{
"id": 12109,
"message_id": 1957719,
"sender_id": 32159,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,0","vote":1}',
},
{
"id": 12110,
"message_id": 1957719,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,1","vote":-1}',
},
{
"id": 12111,
"message_id": 1957719,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"vote","key":"canned,0","vote":1}',
},
],
"Does this poll have multiple voters?",
{
"canned,0": {"option": "Yes", "votes": [32159, 27294]},
"canned,1": {"option": "No", "votes": []},
"32159,1": {"option": "Maybe", "votes": [32159]},
},
id="multiple_voters",
),
],
)
def test_process_poll_widget(
submessages: List[Submessage],
expected_poll_question: str,
expected_options: Dict[str, Dict[str, Union[str, List[str]]]],
) -> None:
poll_question, options = process_poll_widget(submessages)

assert poll_question == expected_poll_question
assert options == expected_options
5 changes: 5 additions & 0 deletions zulipterminal/config/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,11 @@ class KeyBinding(TypedDict):
'help_text': 'Show/hide full raw message',
'key_category': 'msg_info',
},
'SHOW_POLL_VOTES': {
'keys': ['w'],
'help_text': 'Show/hide poll voter list',
'key_category': 'msg_info',
},
'NEW_HINT': {
'keys': ['tab'],
'help_text': 'New footer hotkey hint',
Expand Down
29 changes: 29 additions & 0 deletions zulipterminal/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
MarkdownHelpView,
MsgInfoView,
NoticeView,
PollResultsView,
PopUpConfirmationView,
StreamInfoView,
StreamMembersView,
Expand Down Expand Up @@ -281,6 +282,34 @@ def show_msg_info(
)
self.show_pop_up(msg_info_view, "area:msg")

def show_poll_vote(
self,
poll_question: str,
options: Dict[str, Dict[str, Any]],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming this is poll_options, this type is different again?

) -> None:
options_with_names = {}
for option_key, option_data in options.items():
option_text = option_data["option"]
voter_ids = option_data["votes"]

voter_names = []
for voter_id in voter_ids:
voter_names.append(self.model.user_name_from_id(voter_id))

options_with_names[option_key] = {
"option": option_text,
"votes": voter_names if voter_names else [],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Is this conditional necessary?

}

self.show_pop_up(
PollResultsView(
self,
poll_question,
options_with_names,
),
"area:msg",
)

def show_emoji_picker(self, message: Message) -> None:
all_emoji_units = [
(emoji_name, emoji["code"], emoji["aliases"])
Expand Down
Loading
Loading