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 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
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(
"submessage, expected_poll_question, expected_options",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: plural, as in other PR.

[
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="poll_widget_with_votes",
),
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="poll_widget_with_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="poll_widget_with_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="poll_widget_with_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="poll_widget_with_empty_options",
),
case(
[
{
"id": 12112,
"message_id": 1957722,
"sender_id": 27294,
"msg_type": "widget",
"content": (
'{"widget_type": "poll", "extra_data": {"question": "",'
' "options": []}}'
),
}
],
"",
{},
id="poll_widget_with_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="poll_widget_with_multiple_voters",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: This test is known to be a poll_widget already, as with other PR.

),
],
)
def test_process_poll_widget(
submessage: List[Submessage],
expected_poll_question: str,
expected_options: Dict[str, Dict[str, Union[str, List[str]]]],
) -> None:
poll_question, options = process_poll_widget(submessage)

assert poll_question == expected_poll_question
assert options == expected_options
42 changes: 42 additions & 0 deletions zulipterminal/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,45 @@ def process_todo_widget(
title = widget["title"]

return title, tasks


def process_poll_widget(
poll_content: List[Submessage],
) -> Tuple[str, Dict[str, Dict[str, Union[str, List[str]]]]]:
poll_question = ""
options = {}

for entry in poll_content:
content = entry["content"]
sender_id = entry["sender_id"]
msg_type = entry["msg_type"]

if msg_type == "widget" and isinstance(content, str):
widget = json.loads(content)

if widget.get("widget_type") == "poll":
poll_question = widget["extra_data"]["question"]
for i, option in enumerate(widget["extra_data"]["options"]):
option_id = f"canned,{i}"
options[option_id] = {"option": option, "votes": []}

elif widget.get("type") == "question":
poll_question = widget["question"]

elif widget.get("type") == "vote":
option_id = widget["key"]
vote_type = widget["vote"]

if option_id in options:
if vote_type == 1 and sender_id not in options[option_id]["votes"]:
options[option_id]["votes"].append(sender_id)
elif vote_type == -1 and sender_id in options[option_id]["votes"]:
options[option_id]["votes"].remove(sender_id)

elif widget.get("type") == "new_option":
idx = widget["idx"]
new_option = widget["option"]
option_id = f"{sender_id},{idx}"
options[option_id] = {"option": new_option, "votes": []}

return poll_question, options