Skip to content

Commit aa7c147

Browse files
committed
model: Support updated subscription op=peer_* events for ZFL35+.
Previously these events contained single stream and user ids, but now instead contain lists of each to reduce the numbers of events required for cases where users join or leave large numbers of streams. Note that the server API was changed while the feature level was set to 34, prior to being locked in at ZFL 35, so ZFL 34 can in principle contain both API styles. Consequently tests at ZFL 34 are handled more fully than in other ZFL-dependent cases. Tests added & updated.
1 parent a8ddc7d commit aa7c147

File tree

2 files changed

+108
-13
lines changed

2 files changed

+108
-13
lines changed

tests/model/test_model.py

Lines changed: 97 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,42 +1633,128 @@ def set_from_list_of_dict(data):
16331633
update_left_panel.assert_called_once_with()
16341634
model.controller.update_screen.assert_called_once_with()
16351635

1636-
@pytest.mark.parametrize('event, expected_subscribers', [
1637-
({'op': 'peer_add', 'stream_id': 99, 'user_id': 12}, [1001, 11, 12]),
1638-
({'op': 'peer_remove', 'stream_id': 2, 'user_id': 12}, [1001, 11]),
1636+
@pytest.mark.parametrize(['event', 'feature_level',
1637+
'stream_id', 'expected_subscribers'], [
1638+
({'op': 'peer_add', 'stream_id': 99, 'user_id': 12}, None,
1639+
99, [1001, 11, 12]),
1640+
({'op': 'peer_add', 'stream_id': 99, 'user_id': 12}, 34,
1641+
99, [1001, 11, 12]),
1642+
({'op': 'peer_add', 'stream_ids': [99], 'user_ids': [12]}, 34,
1643+
99, [1001, 11, 12]),
1644+
({'op': 'peer_add', 'stream_ids': [99], 'user_ids': [12]}, 35,
1645+
99, [1001, 11, 12]),
1646+
({'op': 'peer_remove', 'stream_id': 2, 'user_id': 12}, None,
1647+
2, [1001, 11]),
1648+
({'op': 'peer_remove', 'stream_id': 2, 'user_id': 12}, 34,
1649+
2, [1001, 11]),
1650+
({'op': 'peer_remove', 'stream_ids': [2], 'user_ids': [12]}, 34,
1651+
2, [1001, 11]),
1652+
({'op': 'peer_remove', 'stream_ids': [2], 'user_ids': [12]}, 35,
1653+
2, [1001, 11]),
16391654
], ids=[
1640-
'user_subscribed_to_stream',
1641-
'user_unsubscribed_from_stream',
1655+
'user_subscribed_to_stream:ZFLNone',
1656+
'user_subscribed_to_stream:ZFL34',
1657+
'user_subscribed_to_stream:ZFL34shouldbe35',
1658+
'user_subscribed_to_stream:ZFL35',
1659+
'user_unsubscribed_from_stream:ZFLNone',
1660+
'user_unsubscribed_from_stream:ZFL34',
1661+
'user_unsubscribed_from_stream:ZFL34shouldbe35',
1662+
'user_unsubscribed_from_stream:ZFL35',
16421663
])
16431664
def test__handle_subscription_event_subscribers(self, model, mocker,
1644-
stream_dict, event,
1665+
stream_dict,
1666+
event, feature_level,
1667+
stream_id,
16451668
expected_subscribers):
16461669
event['type'] = 'subscription'
16471670

16481671
model.stream_dict = stream_dict
1672+
model.server_feature_level = feature_level
16491673

16501674
model._handle_subscription_event(event)
16511675

1652-
new_subscribers = model.stream_dict[event['stream_id']]['subscribers']
1676+
new_subscribers = model.stream_dict[stream_id]['subscribers']
16531677
assert new_subscribers == expected_subscribers
16541678

1655-
@pytest.mark.parametrize('event', [
1656-
({'op': 'peer_add', 'stream_id': 462, 'user_id': 12}),
1657-
({'op': 'peer_remove', 'stream_id': 462, 'user_id': 12}),
1679+
@pytest.mark.parametrize('event, feature_level', [
1680+
({'op': 'peer_add', 'stream_id': 462, 'user_id': 12}, 34),
1681+
({'op': 'peer_add', 'stream_ids': [462], 'user_ids': [12]}, 35),
1682+
({'op': 'peer_remove', 'stream_id': 462, 'user_id': 12}, 34),
1683+
({'op': 'peer_remove', 'stream_ids': [462], 'user_ids': [12]}, 35),
16581684
], ids=[
16591685
'peer_subscribed_to_stream_that_user_is_unsubscribed_to',
1686+
'peer_subscribed_to_stream_that_user_is_unsubscribed_to:ZFL35+',
16601687
'peer_unsubscribed_from_stream_that_user_is_unsubscribed_to',
1688+
'peer_unsubscribed_from_stream_that_user_is_unsubscribed_to:ZFL35+',
16611689
])
16621690
def test__handle_subscription_event_subscribers_to_unsubscribed_streams(
1663-
self, model, mocker, stream_dict, event):
1691+
self, model, mocker, stream_dict, event, feature_level):
16641692
event['type'] = 'subscription'
16651693

16661694
model.stream_dict = deepcopy(stream_dict)
1695+
model.server_feature_level = feature_level
16671696

16681697
model._handle_subscription_event(event)
16691698

16701699
assert model.stream_dict == stream_dict
16711700

1701+
# NOTE: This only applies to feature level 34/35+
1702+
@pytest.mark.parametrize(['event', 'feature_level',
1703+
'expected_subscribers'], [
1704+
({'op': 'peer_add', 'user_ids': [13, 14]}, 34, [1001, 11, 12, 13, 14]),
1705+
({'op': 'peer_add', 'user_ids': [13, 14]}, 35, [1001, 11, 12, 13, 14]),
1706+
({'op': 'peer_remove', 'user_ids': [12, 11]}, 34, [1001]),
1707+
({'op': 'peer_remove', 'user_ids': [12, 11]}, 35, [1001]),
1708+
], ids=[
1709+
'users_subscribed_to_stream:ZFL34shouldbe35',
1710+
'users_subscribed_to_stream:ZFL35',
1711+
'users_unsubscribed_from_stream:ZFL34shouldbe35',
1712+
'users_unsubscribed_from_stream:ZFL35',
1713+
])
1714+
def test__handle_subscription_event_subscribers_multiple_users_one_stream(
1715+
self, model, mocker, stream_dict, event, feature_level,
1716+
expected_subscribers
1717+
):
1718+
event['type'] = 'subscription'
1719+
event['stream_ids'] = stream_ids = [2]
1720+
1721+
model.stream_dict = stream_dict
1722+
model.server_feature_level = feature_level
1723+
1724+
model._handle_subscription_event(event)
1725+
1726+
new_subscribers = model.stream_dict[stream_ids[0]]['subscribers']
1727+
assert new_subscribers == expected_subscribers
1728+
1729+
# NOTE: This only applies to feature level 34/35+
1730+
@pytest.mark.parametrize(['event', 'feature_level',
1731+
'expected_subscribers'], [
1732+
({'op': 'peer_add', 'user_ids': [13]}, 34, [1001, 11, 12, 13]),
1733+
({'op': 'peer_add', 'user_ids': [13]}, 35, [1001, 11, 12, 13]),
1734+
({'op': 'peer_remove', 'user_ids': [12]}, 34, [1001, 11]),
1735+
({'op': 'peer_remove', 'user_ids': [12]}, 35, [1001, 11]),
1736+
], ids=[
1737+
'user_subscribed_to_streams:ZFL34shouldbe35',
1738+
'user_subscribed_to_streams:ZFL35',
1739+
'user_unsubscribed_from_streams:ZFL34shouldbe35',
1740+
'user_unsubscribed_from_streams:ZFL35',
1741+
])
1742+
def test__handle_subscription_event_subscribers_one_user_multiple_streams(
1743+
self, model, mocker, stream_dict, event, feature_level,
1744+
expected_subscribers
1745+
):
1746+
event['type'] = 'subscription'
1747+
event['stream_ids'] = stream_ids = [1, 2]
1748+
1749+
model.stream_dict = stream_dict
1750+
model.server_feature_level = feature_level
1751+
1752+
model._handle_subscription_event(event)
1753+
1754+
for stream_id in stream_ids:
1755+
new_subscribers = model.stream_dict[stream_id]['subscribers']
1756+
assert new_subscribers == expected_subscribers
1757+
16721758
@pytest.mark.parametrize('muted_streams, stream_id, is_muted', [
16731759
({1}, 1, True),
16741760
({1}, 2, False),

zulipterminal/model.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@
4949
# subscription:
5050
'property': str,
5151
'user_id': int, # Present when a streams subscribers are updated.
52+
'user_ids': List[int], # NOTE: replaces 'user_id' in ZFL 35
5253
'stream_id': int,
54+
'stream_ids': List[int], # NOTE: replaces 'stream_id' in ZFL 35 for peer*
5355
'value': bool,
5456
'message_ids': List[int] # Present when subject of msg(s) is updated
5557
}, total=False) # Each Event will only have a subset of these
@@ -784,8 +786,15 @@ def get_stream_by_id(streams: List[StreamData], stream_id: int
784786
self.controller.view.left_panel.update_stream_view()
785787
self.controller.update_screen()
786788
elif event['op'] in ('peer_add', 'peer_remove'):
787-
stream_ids = [event['stream_id']]
788-
user_ids = [event['user_id']]
789+
# NOTE: ZFL 35 commit was not atomic with API change
790+
# (ZFL >=35 can use new plural style)
791+
if 'stream_ids' not in event or 'user_ids' not in event:
792+
stream_ids = [event['stream_id']]
793+
user_ids = [event['user_id']]
794+
else:
795+
stream_ids = event['stream_ids']
796+
user_ids = event['user_ids']
797+
789798
for stream_id in stream_ids:
790799
if self.is_user_subscribed_to_stream(stream_id):
791800
subscribers = self.stream_dict[stream_id]['subscribers']

0 commit comments

Comments
 (0)