anchor_value: Fix parsing of large anchor values.

This handles the conditions when anchor values are larger than
LARGER_THAN_MAX_MESSAGE_ID by clamping them down to it.  Also added
tests for the function parse_anchor_value.

Fixes #16768.
This commit is contained in:
Sundar Guntnur
2020-11-29 01:00:02 +05:30
committed by Alex Vandiver
parent 4911bc3c4d
commit cbb7fb8ac0
2 changed files with 86 additions and 0 deletions

View File

@@ -2668,6 +2668,90 @@ class GetOldMessagesTest(ZulipTestCase):
{unsub_message_id, muted_message_id, first_message_id, extra_message_id},
)
def test_parse_anchor_value(self) -> None:
hamlet = self.example_user('hamlet')
cordelia = self.example_user('cordelia')
# Send the first message to Hamlet
first_message_id = self.send_personal_message(cordelia, hamlet)
# Send another message
self.send_personal_message(cordelia, hamlet)
user_profile = hamlet
# Check if the anchor value in response is correct for different
# values of anchor parameter in request
# With anchor input as first_unread, see if response anchor
# value is same as the id of first unread message of Hamlet
query_params = dict(
anchor="first_unread",
num_before=10,
num_after=10,
narrow='[]',
)
request = POSTRequestMock(query_params, user_profile)
payload = get_messages_backend(request, user_profile)
result = orjson.loads(payload.content)
self.assertEqual(result['anchor'], first_message_id)
# With anchor input as oldest, see if response anchor value is 0
query_params = dict(
anchor="oldest",
num_before=10,
num_after=10,
narrow='[]',
)
request = POSTRequestMock(query_params, user_profile)
payload = get_messages_backend(request, user_profile)
result = orjson.loads(payload.content)
self.assertEqual(result['anchor'], 0)
# With anchor input as newest, see if response
# anchor value is LARGER_THAN_MAX_MESSAGE_ID
query_params = dict(
anchor="newest",
num_before=10,
num_after=10,
narrow='[]',
)
request = POSTRequestMock(query_params, user_profile)
payload = get_messages_backend(request, user_profile)
result = orjson.loads(payload.content)
self.assertEqual(result['anchor'], LARGER_THAN_MAX_MESSAGE_ID)
# With anchor input negative, see if
# response anchor value is clamped to 0
query_params = dict(
anchor="-1",
num_before=10,
num_after=10,
narrow='[]',
)
request = POSTRequestMock(query_params, user_profile)
payload = get_messages_backend(request, user_profile)
result = orjson.loads(payload.content)
self.assertEqual(result['anchor'], 0)
# With anchor input more than LARGER_THAN_MAX_MESSAGE_ID,
# see if response anchor value is clamped down to LARGER_THAN_MAX_MESSAGE_ID
query_params = dict(
anchor="10000000000000001",
num_before=10,
num_after=10,
narrow='[]',
)
request = POSTRequestMock(query_params, user_profile)
payload = get_messages_backend(request, user_profile)
result = orjson.loads(payload.content)
self.assertEqual(result['anchor'], LARGER_THAN_MAX_MESSAGE_ID)
def test_use_first_unread_anchor_with_some_unread_messages(self) -> None:
user_profile = self.example_user('hamlet')

View File

@@ -839,6 +839,8 @@ def parse_anchor_value(anchor_val: Optional[str],
anchor = int(anchor_val)
if anchor < 0:
return 0
elif anchor > LARGER_THAN_MAX_MESSAGE_ID:
return LARGER_THAN_MAX_MESSAGE_ID
return anchor
except ValueError:
raise JsonableError(_("Invalid anchor"))