Skip to content

Commit

Permalink
widget: Add process_todo_widget function.
Browse files Browse the repository at this point in the history
Added process_todo_widget function to process submessages
containing a todo widget. Returns the title of the widget
along with tasks and their state (completed/uncompleted)
as a dict.

Tests added.
  • Loading branch information
rsashank committed Oct 4, 2024
1 parent 5feb1de commit 8f6ccbc
Show file tree
Hide file tree
Showing 2 changed files with 258 additions and 2 deletions.
212 changes: 211 additions & 1 deletion tests/widget/test_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest
from pytest import param as case

from zulipterminal.widget import find_widget_type
from zulipterminal.widget import find_widget_type, process_todo_widget


@pytest.mark.parametrize(
Expand Down Expand Up @@ -58,3 +58,213 @@ def test_find_widget_type(submessage: Any, expected_widget_type: str) -> None:
widget_type = find_widget_type(submessage)

assert widget_type == expected_widget_type


@pytest.mark.parametrize(
"submessage, expected_title, expected_tasks",
[
case(
[
{
"id": 11899,
"message_id": 1954463,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"widget_type": "todo", "extra_data": '
'{"task_list_title": "Today\'s Tasks", "tasks": [{"task": '
'"Write code", "desc": ""}, {"task": "Sleep", "desc": ""}]}}',
},
{
"id": 11900,
"message_id": 1954463,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"new_task","key":2,"task":"Eat","desc":"",'
'"completed":false}',
},
],
"Today's Tasks",
{
"0,canned": {"task": "Write code", "desc": "", "completed": False},
"1,canned": {"task": "Sleep", "desc": "", "completed": False},
"2,27294": {"task": "Eat", "desc": "", "completed": False},
},
id="todo_with_title_and_unfinished_tasks",
),
case(
[
{
"id": 11912,
"message_id": 1954626,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"widget_type": "todo", "extra_data": '
'{"task_list_title": "", "tasks": [{"task": "Hey", "desc": ""}, '
'{"task": "Hi", "desc": ""}]}}',
}
],
"Task list",
{
"0,canned": {"task": "Hey", "desc": "", "completed": False},
"1,canned": {"task": "Hi", "desc": "", "completed": False},
},
id="todo_without_title_and_unfinished_tasks",
),
case(
[
{
"id": 11919,
"message_id": 1954843,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"widget_type": "todo", "extra_data": '
'{"task_list_title": "", "tasks": []}}',
}
],
"Task list",
{},
id="todo_without_title_or_tasks",
),
case(
[
{
"id": 11932,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"widget_type": "todo", "extra_data": '
'{"task_list_title": "", "tasks": []}}',
},
{
"id": 11933,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"new_task","key":2,"task":"Write code",'
'"desc":"Make the todo ZT PR!","completed":false}',
},
{
"id": 11934,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"new_task","key":4,"task":"Sleep",'
'"desc":"at least 8 hours a day","completed":false}',
},
{
"id": 11935,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"new_task","key":6,"task":"Eat",'
'"desc":"3 meals a day","completed":false}',
},
{
"id": 11936,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"new_task","key":8,"task":"Exercise",'
'"desc":"an hour a day","completed":false}',
},
{
"id": 11937,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"strike","key":"2,27294"}',
},
{
"id": 11938,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"strike","key":"2,27294"}',
},
{
"id": 11939,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"strike","key":"4,27294"}',
},
{
"id": 11940,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"strike","key":"6,27294"}',
},
{
"id": 11941,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"strike","key":"8,27294"}',
},
{
"id": 11942,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"strike","key":"2,27294"}',
},
{
"id": 11943,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"strike","key":"4,27294"}',
},
{
"id": 11944,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"strike","key":"6,27294"}',
},
{
"id": 11945,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"strike","key":"4,27294"}',
},
{
"id": 11946,
"message_id": 1954847,
"sender_id": 27294,
"msg_type": "widget",
"content": '{"type":"strike","key":"8,27294"}',
},
],
"Task list",
{
"2,27294": {
"task": "Write code",
"desc": "Make the todo ZT PR!",
"completed": True,
},
"4,27294": {
"task": "Sleep",
"desc": "at least 8 hours a day",
"completed": True,
},
"6,27294": {"task": "Eat", "desc": "3 meals a day", "completed": False},
"8,27294": {
"task": "Exercise",
"desc": "an hour a day",
"completed": False,
},
},
id="todo_with_title_and_description_and_some_tasks_completed",
),
],
)
def test_process_todo_widget(
submessage: Any, expected_title: str, expected_tasks: dict
) -> None:
title, tasks = process_todo_widget(submessage)

assert title == expected_title
assert tasks == expected_tasks
48 changes: 47 additions & 1 deletion zulipterminal/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""

import json
from typing import Any
from typing import Any, Dict, Tuple


def find_widget_type(submessage: Any) -> str:
Expand All @@ -15,3 +15,49 @@ def find_widget_type(submessage: Any) -> str:
return "unknown"
else:
return "unknown"


def process_todo_widget(todo_list: Any) -> Tuple[str, Dict[str, Dict[str, Any]]]:
title = ""
tasks = {}

for entry in todo_list:
content = entry.get("content")
sender_id = entry.get("sender_id")
msg_type = entry.get("msg_type")

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

if widget.get("widget_type") == "todo":
if "extra_data" in widget and widget["extra_data"] is not None:
title = widget["extra_data"].get("task_list_title", "")
if title == "":
# Webapp uses "Task list" as default title
title = "Task list"
# Process initial tasks
for i, task in enumerate(widget["extra_data"].get("tasks", [])):
# Initial tasks get ID as "index,canned"
task_id = f"{i},canned"
tasks[task_id] = {
"task": task["task"],
"desc": task.get("desc", ""),
"completed": False,
}

elif widget.get("type") == "new_task":
# New tasks get ID as "key,sender_id"
task_id = f"{widget['key']},{sender_id}"
tasks[task_id] = {
"task": widget["task"],
"desc": widget.get("desc", ""),
"completed": False,
}

elif widget.get("type") == "strike":
# Strike event - toggle task completion state
task_id = widget["key"]
if task_id in tasks:
tasks[task_id]["completed"] = not tasks[task_id]["completed"]

return title, tasks

0 comments on commit 8f6ccbc

Please sign in to comment.