Skip to content

Commit 36d3cc3

Browse files
rsashankneiljp
authored andcommitted
model: Store & use any presence interval values from server.
Stores the presence interval values received from the register response in the model. If the feature level is lower, it defaults to the values defined in api_types. Test added. Fixes #1421.
1 parent bb1280f commit 36d3cc3

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

tests/model/test_model.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
MAX_MESSAGE_LENGTH,
1515
MAX_STREAM_NAME_LENGTH,
1616
MAX_TOPIC_NAME_LENGTH,
17+
PRESENCE_OFFLINE_THRESHOLD_SECS,
18+
PRESENCE_PING_INTERVAL_SECS,
1719
TYPING_STARTED_EXPIRY_PERIOD,
1820
TYPING_STARTED_WAIT_PERIOD,
1921
TYPING_STOPPED_WAIT_PERIOD,
@@ -1440,6 +1442,60 @@ def test__store_typing_duration_settings__with_values(
14401442
assert model.typing_stopped_wait_period == typing_stopped_wait
14411443
assert model.typing_started_expiry_period == typing_started_expiry
14421444

1445+
@pytest.mark.parametrize(
1446+
"feature_level, to_vary_in_initial_data, "
1447+
"expected_offline_threshold, expected_presence_ping_interval",
1448+
[
1449+
(0, {}, PRESENCE_OFFLINE_THRESHOLD_SECS, PRESENCE_PING_INTERVAL_SECS),
1450+
(157, {}, PRESENCE_OFFLINE_THRESHOLD_SECS, PRESENCE_PING_INTERVAL_SECS),
1451+
(
1452+
164,
1453+
{
1454+
"server_presence_offline_threshold_seconds": 200,
1455+
"server_presence_ping_interval_seconds": 100,
1456+
},
1457+
200,
1458+
100,
1459+
),
1460+
],
1461+
ids=[
1462+
"Zulip_2.1_ZFL_0_hard_coded",
1463+
"Zulip_6.2_ZFL_157_hard_coded",
1464+
"Zulip_7.0_ZFL_164_server_provided",
1465+
],
1466+
)
1467+
def test__store_server_presence_intervals(
1468+
self,
1469+
model,
1470+
initial_data,
1471+
feature_level,
1472+
to_vary_in_initial_data,
1473+
expected_offline_threshold,
1474+
expected_presence_ping_interval,
1475+
):
1476+
# Ensure inputs are not the defaults, to avoid the test accidentally passing
1477+
assert (
1478+
to_vary_in_initial_data.get("server_presence_offline_threshold_seconds")
1479+
!= PRESENCE_OFFLINE_THRESHOLD_SECS
1480+
)
1481+
assert (
1482+
to_vary_in_initial_data.get("server_presence_ping_interval_seconds")
1483+
!= PRESENCE_PING_INTERVAL_SECS
1484+
)
1485+
1486+
initial_data.update(to_vary_in_initial_data)
1487+
model.initial_data = initial_data
1488+
model.server_feature_level = feature_level
1489+
1490+
model._store_server_presence_intervals()
1491+
1492+
assert (
1493+
model.server_presence_offline_threshold_secs == expected_offline_threshold
1494+
)
1495+
assert (
1496+
model.server_presence_ping_interval_secs == expected_presence_ping_interval
1497+
)
1498+
14431499
def test_get_message_false_first_anchor(
14441500
self,
14451501
mocker,

zulipterminal/model.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ def __init__(self, controller: Any) -> None:
171171
self.server_version = self.initial_data["zulip_version"]
172172
self.server_feature_level: int = self.initial_data.get("zulip_feature_level", 0)
173173

174+
self._store_server_presence_intervals()
175+
174176
self.user_dict: Dict[str, MinimalUserData] = {}
175177
self.user_id_email_dict: Dict[int, str] = {}
176178
self._all_users_by_id: Dict[int, RealmUser] = {}
@@ -444,7 +446,7 @@ def _start_presence_updates(self) -> None:
444446
view = self.controller.view
445447
view.users_view.update_user_list(user_list=self.users)
446448
view.middle_column.update_message_list_status_markers()
447-
time.sleep(PRESENCE_PING_INTERVAL_SECS)
449+
time.sleep(self.server_presence_ping_interval_secs)
448450

449451
@asynch
450452
def toggle_message_reaction(
@@ -813,6 +815,18 @@ def _store_typing_duration_settings(self) -> None:
813815
TYPING_STARTED_EXPIRY_PERIOD,
814816
)
815817

818+
def _store_server_presence_intervals(self) -> None:
819+
"""
820+
In ZFL 164, these values were added to the register response.
821+
Uses default values if not received.
822+
"""
823+
self.server_presence_offline_threshold_secs = self.initial_data.get(
824+
"server_presence_offline_threshold_seconds", PRESENCE_OFFLINE_THRESHOLD_SECS
825+
)
826+
self.server_presence_ping_interval_secs = self.initial_data.get(
827+
"server_presence_ping_interval_seconds", PRESENCE_PING_INTERVAL_SECS
828+
)
829+
816830
@staticmethod
817831
def modernize_message_response(message: Message) -> Message:
818832
"""
@@ -1201,7 +1215,7 @@ def _update_users_data_from_initial_data(self) -> None:
12011215
*
12021216
* Out of the ClientPresence objects found in `presence`, we
12031217
* consider only those with a timestamp newer than
1204-
* PRESENCE_OFFLINE_THRESHOLD_SECS; then of
1218+
* self.server_presence_offline_threshold_secs; then of
12051219
* those, return the one that has the greatest UserStatus, where
12061220
* `active` > `idle` > `offline`.
12071221
*
@@ -1215,7 +1229,9 @@ def _update_users_data_from_initial_data(self) -> None:
12151229
timestamp = client[1]["timestamp"]
12161230
if client_name == "aggregated":
12171231
continue
1218-
elif (time.time() - timestamp) < PRESENCE_OFFLINE_THRESHOLD_SECS:
1232+
elif (
1233+
time.time() - timestamp
1234+
) < self.server_presence_offline_threshold_secs:
12191235
if status == "active":
12201236
aggregate_status = "active"
12211237
if status == "idle" and aggregate_status != "active":

0 commit comments

Comments
 (0)