Skip to content

Commit abc3836

Browse files
committed
model: Add toggle_topic_resolve_status function to (un)resolve topics.
Fixes zulip#1075 The function calls get_latest_message_in_topic to fetch recent message in topic to be (un)resolved. It verifies user and editing conditions using can_user_edit_topic function and finally add or remove RESOLVED_TOPIC_PREFIX from topic name.
1 parent a9dd83b commit abc3836

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

tests/model/test_model.py

+81
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pytest import param as case
88
from zulip import Client, ZulipError
99

10+
from zulipterminal.api_types import RESOLVED_TOPIC_PREFIX
1011
from zulipterminal.config.symbols import STREAM_TOPIC_SEPARATOR
1112
from zulipterminal.helper import initial_index, powerset
1213
from zulipterminal.model import (
@@ -1200,6 +1201,86 @@ def test_can_user_edit_topic(
12001201
else:
12011202
report_error.assert_called_once_with(expected_response[user_type][0])
12021203

1204+
@pytest.mark.parametrize(
1205+
"topic_name, msg_response, server_feature_level, topic_editing_limit_seconds, expected_new_topic_name, expected_footer_error",
1206+
[
1207+
case(
1208+
"hi!",
1209+
{
1210+
"subject": "hi!",
1211+
"timestamp": 11662271397,
1212+
"id": 1,
1213+
},
1214+
12,
1215+
259200,
1216+
RESOLVED_TOPIC_PREFIX + "hi!",
1217+
None,
1218+
id="topic_resolved:Zulip2.1+:ZFL12",
1219+
),
1220+
case(
1221+
"hi!",
1222+
{
1223+
"subject": "hi!",
1224+
"timestamp": 0,
1225+
"id": 1,
1226+
},
1227+
None,
1228+
None,
1229+
RESOLVED_TOPIC_PREFIX + "hi!",
1230+
None,
1231+
id="no_time_limit:Zulip2.1+:None",
1232+
),
1233+
case(
1234+
RESOLVED_TOPIC_PREFIX + "hi!",
1235+
{
1236+
"subject": RESOLVED_TOPIC_PREFIX + "hi!",
1237+
"timestamp": 11662271397,
1238+
"id": 1,
1239+
},
1240+
10,
1241+
86400,
1242+
"hi!",
1243+
None,
1244+
id="topic_unresolved:Zulip2.1+:ZFL10",
1245+
),
1246+
],
1247+
)
1248+
def test_toggle_topic_resolve_status(
1249+
self,
1250+
mocker,
1251+
model,
1252+
initial_data,
1253+
topic_name,
1254+
msg_response,
1255+
server_feature_level,
1256+
topic_editing_limit_seconds,
1257+
expected_new_topic_name,
1258+
expected_footer_error,
1259+
stream_id=1,
1260+
):
1261+
model.initial_data = initial_data
1262+
model.server_feature_level = server_feature_level
1263+
initial_data[
1264+
"realm_community_topic_editing_limit_seconds"
1265+
] = topic_editing_limit_seconds
1266+
# If user can't edit topic, topic (un)resolve is disabled. Therefore,
1267+
# default return_value=True
1268+
model.can_user_edit_topic = mocker.Mock(return_value=True)
1269+
model.get_latest_message_in_topic = mocker.Mock(return_value=msg_response)
1270+
model.update_stream_message = mocker.Mock(return_value={"result": "success"})
1271+
report_error = model.controller.report_error
1272+
1273+
model.toggle_topic_resolve_status(stream_id, topic_name)
1274+
1275+
if not expected_footer_error:
1276+
model.update_stream_message.assert_called_once_with(
1277+
message_id=msg_response["id"],
1278+
topic=expected_new_topic_name,
1279+
propagate_mode="change_all",
1280+
)
1281+
else:
1282+
report_error.assert_called_once_with(expected_footer_error)
1283+
12031284
# NOTE: This tests only getting next-unread, not a fixed anchor
12041285
def test_success_get_messages(
12051286
self,

zulipterminal/model.py

+33
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
from zulipterminal import unicode_emojis
3232
from zulipterminal.api_types import (
33+
RESOLVED_TOPIC_PREFIX,
3334
Composition,
3435
EditPropagateMode,
3536
Event,
@@ -696,6 +697,38 @@ def can_user_edit_topic(self) -> bool:
696697
self.controller.report_error("User not found")
697698
return False
698699

700+
def toggle_topic_resolve_status(self, stream_id: int, topic_name: str) -> None:
701+
if self.can_user_edit_topic():
702+
latest_msg = self.get_latest_message_in_topic(stream_id, topic_name)
703+
if latest_msg:
704+
time_since_msg_sent = time.time() - latest_msg["timestamp"]
705+
# ZFL < 11, community_topic_editing_limit_seconds
706+
# was hardcoded as int value in secs eg. 86400s (1 day) or None
707+
if self.server_feature_level is None or self.server_feature_level >= 11:
708+
edit_time_limit = self.initial_data.get(
709+
"realm_community_topic_editing_limit_seconds", None
710+
)
711+
else:
712+
edit_time_limit = 86400
713+
# Don't allow editing topic if time-limit exceeded.
714+
if (
715+
edit_time_limit is not None
716+
and time_since_msg_sent >= edit_time_limit
717+
):
718+
self.controller.report_error(
719+
" Time limit for editing topic has been exceeded."
720+
)
721+
else:
722+
if topic_name.startswith(RESOLVED_TOPIC_PREFIX):
723+
topic_name = topic_name[2:]
724+
else:
725+
topic_name = RESOLVED_TOPIC_PREFIX + topic_name
726+
self.update_stream_message(
727+
message_id=latest_msg["id"],
728+
topic=topic_name,
729+
propagate_mode="change_all",
730+
)
731+
699732
def generate_all_emoji_data(
700733
self, custom_emoji: Dict[str, RealmEmojiData]
701734
) -> Tuple[NamedEmojiData, List[str]]:

0 commit comments

Comments
 (0)