Skip to content

Commit 20f33d2

Browse files
rsashanksrdeotarse
andcommitted
model: Add toggle_topic_resolve_status function to (un)resolve topics.
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. Fixes zulip#1075. Co-authored-by: Shivam Deotarse <[email protected]>
1 parent 7116761 commit 20f33d2

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

tests/model/test_model.py

+124
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pytest_mock import MockerFixture
1010
from zulip import Client, ZulipError
1111

12+
from zulipterminal.api_types import RESOLVED_TOPIC_PREFIX
1213
from zulipterminal.config.symbols import STREAM_TOPIC_SEPARATOR
1314
from zulipterminal.helper import initial_index, powerset
1415
from zulipterminal.model import (
@@ -1360,6 +1361,129 @@ def test_can_user_edit_topic(
13601361
else:
13611362
report_error.assert_called_once_with(expected_response[user_type][0])
13621363

1364+
@pytest.mark.parametrize(
1365+
"topic_name, timestamp, server_feature_level, topic_editing_limit_seconds,"
1366+
" move_messages_within_stream_limit_seconds, expected_new_topic_name,"
1367+
" expected_footer_error,",
1368+
[
1369+
case(
1370+
"hi!",
1371+
11662271397,
1372+
12,
1373+
259200,
1374+
None,
1375+
RESOLVED_TOPIC_PREFIX + "hi!",
1376+
None,
1377+
id="topic_resolved:Zulip2.1+:ZFL12",
1378+
),
1379+
case(
1380+
"hi!",
1381+
0,
1382+
0,
1383+
None,
1384+
None,
1385+
RESOLVED_TOPIC_PREFIX + "hi!",
1386+
None,
1387+
id="no_time_limit:Zulip2.1+:ZFL0",
1388+
),
1389+
case(
1390+
RESOLVED_TOPIC_PREFIX + "hi!",
1391+
11662271397,
1392+
10,
1393+
86400,
1394+
None,
1395+
"hi!",
1396+
None,
1397+
id="topic_unresolved:Zulip2.1+:ZFL10",
1398+
),
1399+
case(
1400+
"hi!",
1401+
11662271397,
1402+
162,
1403+
None,
1404+
86400,
1405+
RESOLVED_TOPIC_PREFIX + "hi!",
1406+
None,
1407+
id="topic_resolved:Zulip7.0+:ZFL162",
1408+
),
1409+
case(
1410+
RESOLVED_TOPIC_PREFIX + "hi!",
1411+
11662271397,
1412+
162,
1413+
None,
1414+
259200,
1415+
"hi!",
1416+
None,
1417+
id="topic_unresolved:Zulip7.0+:ZFL162",
1418+
),
1419+
case(
1420+
"hi!",
1421+
0,
1422+
12,
1423+
86400,
1424+
None,
1425+
"hi!",
1426+
" Time limit for editing topic has been exceeded.",
1427+
id="time_limit_exceeded:Zulip2.1+:ZFL12",
1428+
),
1429+
case(
1430+
"hi!",
1431+
0,
1432+
162,
1433+
None,
1434+
259200,
1435+
"hi!",
1436+
" Time limit for editing topic has been exceeded.",
1437+
id="time_limit_exceeded:Zulip7.0+:ZFL162",
1438+
),
1439+
],
1440+
)
1441+
def test_toggle_topic_resolve_status(
1442+
self,
1443+
mocker,
1444+
model,
1445+
initial_data,
1446+
topic_name,
1447+
timestamp,
1448+
server_feature_level,
1449+
topic_editing_limit_seconds,
1450+
move_messages_within_stream_limit_seconds,
1451+
expected_new_topic_name,
1452+
expected_footer_error,
1453+
stream_id=1,
1454+
):
1455+
model.initial_data = initial_data
1456+
model.server_feature_level = server_feature_level
1457+
initial_data[
1458+
"realm_community_topic_editing_limit_seconds"
1459+
] = topic_editing_limit_seconds
1460+
initial_data[
1461+
"realm_move_messages_within_stream_limit_seconds"
1462+
] = move_messages_within_stream_limit_seconds
1463+
# If user can't edit topic, topic (un)resolve is disabled. Therefore,
1464+
# default return_value=True
1465+
model.can_user_edit_topic = mocker.Mock(return_value=True)
1466+
model.get_latest_message_in_topic = mocker.Mock(
1467+
return_value={
1468+
"subject": topic_name,
1469+
"timestamp": timestamp,
1470+
"id": 1,
1471+
}
1472+
)
1473+
model.update_stream_message = mocker.Mock(return_value={"result": "success"})
1474+
report_error = model.controller.report_error
1475+
1476+
model.toggle_topic_resolve_status(stream_id, topic_name)
1477+
1478+
if not expected_footer_error:
1479+
model.update_stream_message.assert_called_once_with(
1480+
message_id=1,
1481+
topic=expected_new_topic_name,
1482+
propagate_mode="change_all",
1483+
)
1484+
else:
1485+
report_error.assert_called_once_with(expected_footer_error)
1486+
13631487
# NOTE: This tests only getting next-unread, not a fixed anchor
13641488
def test_success_get_messages(
13651489
self,

zulipterminal/model.py

+39
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
MAX_TOPIC_NAME_LENGTH,
3737
PRESENCE_OFFLINE_THRESHOLD_SECS,
3838
PRESENCE_PING_INTERVAL_SECS,
39+
RESOLVED_TOPIC_PREFIX,
3940
TYPING_STARTED_EXPIRY_PERIOD,
4041
TYPING_STARTED_WAIT_PERIOD,
4142
TYPING_STOPPED_WAIT_PERIOD,
@@ -709,6 +710,44 @@ def can_user_edit_topic(self) -> bool:
709710
self.controller.report_error("User not found")
710711
return False
711712

713+
def toggle_topic_resolve_status(self, stream_id: int, topic_name: str) -> None:
714+
if self.can_user_edit_topic():
715+
latest_msg = self.get_latest_message_in_topic(stream_id, topic_name)
716+
if latest_msg:
717+
time_since_msg_sent = time.time() - latest_msg["timestamp"]
718+
# ZFL < 11, community_topic_editing_limit_seconds
719+
# was hardcoded as int value in secs eg. 86400s (1 day) or None
720+
if 11 <= self.server_feature_level < 162:
721+
edit_time_limit = self.initial_data.get(
722+
"realm_community_topic_editing_limit_seconds", None
723+
)
724+
# ZFL >= 162, realm_move_messages_within_stream_limit_seconds was
725+
# introduced in place of realm_community_topic_editing_limit_seconds
726+
elif self.server_feature_level >= 162:
727+
edit_time_limit = self.initial_data.get(
728+
"realm_move_messages_within_stream_limit_seconds", None
729+
)
730+
else:
731+
edit_time_limit = 86400
732+
# Don't allow editing topic if time-limit exceeded.
733+
if (
734+
edit_time_limit is not None
735+
and time_since_msg_sent >= edit_time_limit
736+
):
737+
self.controller.report_error(
738+
" Time limit for editing topic has been exceeded."
739+
)
740+
else:
741+
if topic_name.startswith(RESOLVED_TOPIC_PREFIX):
742+
topic_name = topic_name[2:]
743+
else:
744+
topic_name = RESOLVED_TOPIC_PREFIX + topic_name
745+
self.update_stream_message(
746+
message_id=latest_msg["id"],
747+
topic=topic_name,
748+
propagate_mode="change_all",
749+
)
750+
712751
def generate_all_emoji_data(
713752
self, custom_emoji: Dict[str, RealmEmojiData]
714753
) -> Tuple[NamedEmojiData, List[str]]:

0 commit comments

Comments
 (0)