Skip to content

Commit 013f898

Browse files
kaustubh-nairneiljp
authored andcommitted
model: Handle read events for indexed messages.
This commit primarily adds handling of updates to the status flags on messages for 'read' events, in addition to the previously-present 'starred' events, in update_message_flag_status. We previously sent a message to the server indicating a particular message had been read locally, also marking it read and updating unread-counts locally. Now that we handle the 'read'-flag events, we can also handle remotely-read messages, from other clients. For now, the count updating is moved from the server-message method to update_message_flag_status. NOTE: One current limitation to updating remotely-read messages is that we only handle messages we have full content of in the index. Star-flag update tests amended. New tests added for updating the read-flag.
1 parent 3ff8a73 commit 013f898

File tree

2 files changed

+75
-5
lines changed

2 files changed

+75
-5
lines changed

tests/model/test_model.py

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,13 +1150,15 @@ def test_update_reaction_remove_reaction(self, mocker, model, response,
11501150

11511151
def test_update_star_status_no_index(self, mocker, model):
11521152
model.index = dict(messages={}) # Not indexed
1153-
event = dict(messages=[1], flag='starred', all=False)
1153+
event = dict(messages=[1], flag='starred', all=False, operation='add')
11541154
mocker.patch('zulipterminal.model.Model.update_rendered_view')
1155+
set_count = mocker.patch('zulipterminal.model.set_count')
11551156

11561157
model.update_message_flag_status(event)
11571158

11581159
assert model.index == dict(messages={})
11591160
model.update_rendered_view.assert_not_called()
1161+
set_count.assert_not_called()
11601162

11611163
def test_update_star_status_invalid_operation(self, mocker, model):
11621164
model.index = dict(messages={1: {'flags': None}}) # Minimal
@@ -1168,9 +1170,11 @@ def test_update_star_status_invalid_operation(self, mocker, model):
11681170
'all': False,
11691171
}
11701172
mocker.patch('zulipterminal.model.Model.update_rendered_view')
1173+
set_count = mocker.patch('zulipterminal.model.set_count')
11711174
with pytest.raises(RuntimeError):
11721175
model.update_message_flag_status(event)
11731176
model.update_rendered_view.assert_not_called()
1177+
set_count.assert_not_called()
11741178

11751179
@pytest.mark.parametrize('event_message_ids, indexed_ids', [
11761180
([1], [1]),
@@ -1204,19 +1208,80 @@ def test_update_star_status(self, mocker, model, event_op,
12041208
'all': False,
12051209
}
12061210
mocker.patch('zulipterminal.model.Model.update_rendered_view')
1211+
set_count = mocker.patch('zulipterminal.model.set_count')
12071212

12081213
model.update_message_flag_status(event)
12091214

12101215
changed_ids = set(indexed_ids) & set(event_message_ids)
12111216
for changed_id in changed_ids:
12121217
assert model.index['messages'][changed_id]['flags'] == flags_after
12131218
(model.update_rendered_view.
1214-
has_calls([mocker.call(changed_id) for changed_id in changed_ids]))
1219+
assert_has_calls([mocker.call(changed_id)
1220+
for changed_id in changed_ids]))
12151221

12161222
for unchanged_id in (set(indexed_ids) - set(event_message_ids)):
12171223
assert (model.index['messages'][unchanged_id]['flags'] ==
12181224
flags_before)
12191225

1226+
set_count.assert_not_called()
1227+
1228+
@pytest.mark.parametrize('event_message_ids, indexed_ids', [
1229+
([1], [1]),
1230+
([1, 2], [1]),
1231+
([1, 2], [1, 2]),
1232+
([1], [1, 2]),
1233+
([], [1, 2]),
1234+
([1, 2], []),
1235+
])
1236+
@pytest.mark.parametrize('event_op, flags_before, flags_after', [
1237+
('add', [], ['read']),
1238+
('add', ['read'], ['read']),
1239+
('add', ['starred'], ['starred', 'read']),
1240+
('add', ['read', 'starred'], ['read', 'starred']),
1241+
('remove', [], []),
1242+
('remove', ['read'], ['read']), # msg cannot be marked 'unread'
1243+
('remove', ['starred'], ['starred']),
1244+
('remove', ['starred', 'read'], ['starred', 'read']),
1245+
('remove', ['read', 'starred'], ['read', 'starred']),
1246+
])
1247+
def test_update_read_status(self, mocker, model, event_op,
1248+
event_message_ids, indexed_ids,
1249+
flags_before, flags_after):
1250+
model.index = dict(messages={msg_id: {'flags': flags_before}
1251+
for msg_id in indexed_ids})
1252+
event = {
1253+
'messages': event_message_ids,
1254+
'type': 'update_message_flags',
1255+
'flag': 'read',
1256+
'operation': event_op,
1257+
'all': False,
1258+
}
1259+
1260+
mocker.patch('zulipterminal.model.Model.update_rendered_view')
1261+
set_count = mocker.patch('zulipterminal.model.set_count')
1262+
1263+
model.update_message_flag_status(event)
1264+
1265+
changed_ids = set(indexed_ids) & set(event_message_ids)
1266+
for changed_id in changed_ids:
1267+
assert model.index['messages'][changed_id]['flags'] == flags_after
1268+
1269+
if event_op == 'add':
1270+
model.update_rendered_view.assert_has_calls(
1271+
[mocker.call(changed_id)])
1272+
elif event_op == 'remove':
1273+
model.update_rendered_view.assert_not_called()
1274+
1275+
for unchanged_id in (set(indexed_ids) - set(event_message_ids)):
1276+
assert (model.index['messages'][unchanged_id]['flags'] ==
1277+
flags_before)
1278+
1279+
if event_op == 'add':
1280+
set_count.assert_called_once_with(list(changed_ids),
1281+
self.controller, -1)
1282+
elif event_op == 'remove':
1283+
set_count.assert_not_called()
1284+
12201285
@pytest.mark.parametrize('narrow, event, called', [
12211286
# Not in PM Narrow
12221287
([], {}, False),

zulipterminal/model.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@ def mark_message_ids_as_read(self, id_list: List[int]) -> None:
289289
'flag': 'read',
290290
'op': 'add',
291291
})
292-
set_count(id_list, self.controller, -1) # FIXME Update?
293292

294293
def send_private_message(self, recipients: str,
295294
content: str) -> bool:
@@ -815,9 +814,11 @@ def update_message_flag_status(self, event: Event) -> None:
815814
if event['all']: # FIXME Should handle eventually
816815
return
817816

818-
# TODO: Expand from 'starred' to also support 'read' flag changes?
819817
flag_to_change = event['flag']
820-
if flag_to_change != 'starred':
818+
if flag_to_change not in {'starred', 'read'}:
819+
return
820+
821+
if flag_to_change == 'read' and event['operation'] == 'remove':
821822
return
822823

823824
indexed_message_ids = set(self.index['messages'])
@@ -837,6 +838,10 @@ def update_message_flag_status(self, event: Event) -> None:
837838
self.index['messages'][message_id] = msg
838839
self.update_rendered_view(message_id)
839840

841+
if event['operation'] == 'add' and flag_to_change == 'read':
842+
set_count(list(message_ids_to_mark & indexed_message_ids),
843+
self.controller, -1)
844+
840845
def update_rendered_view(self, msg_id: int) -> None:
841846
# Update new content in the rendered view
842847
for msg_w in self.msg_list.log:

0 commit comments

Comments
 (0)