mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	narrow: Support string and integer encoding of "id" operator.
Expands support for the message ID operand for id" operator to be either a string or an integer. Previously, this operand was always validated as a string.
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							211934a9d9
						
					
				
				
					commit
					3255281a83
				
			@@ -20,6 +20,16 @@ format used by the Zulip server that they are interacting with.
 | 
			
		||||
 | 
			
		||||
## Changes in Zulip 8.0
 | 
			
		||||
 | 
			
		||||
**Feature level 194**
 | 
			
		||||
 | 
			
		||||
* [`GET /messages`](/api/get-messages),
 | 
			
		||||
  [`GET /messages/matches_narrow`](/api/check-messages-match-narrow),
 | 
			
		||||
  [`POST /message/flags/narrow`](/api/update-message-flags-for-narrow),
 | 
			
		||||
  [`POST /register`](/api/register-queue):
 | 
			
		||||
  For [search/narrow filters](/api/construct-narrow) with the `id`
 | 
			
		||||
  operator, added support for encoding the message ID operand as either
 | 
			
		||||
  a string or an integer. Previously, only string encoding was supported.
 | 
			
		||||
 | 
			
		||||
**Feature level 193**
 | 
			
		||||
 | 
			
		||||
* [`POST /messages/{message_id}/reactions`](/api/add-reaction),
 | 
			
		||||
 
 | 
			
		||||
@@ -65,12 +65,33 @@ filters did.
 | 
			
		||||
 | 
			
		||||
## Narrows that use IDs
 | 
			
		||||
 | 
			
		||||
### Message IDs
 | 
			
		||||
 | 
			
		||||
The `near` and `id` operators, documented in the help center, use message
 | 
			
		||||
IDs for their operands.
 | 
			
		||||
 | 
			
		||||
* `near:12345`: Search messages around the message with ID `12345`.
 | 
			
		||||
* `id:12345`: Search for only message with ID `12345`.
 | 
			
		||||
 | 
			
		||||
The message ID operand for the `id` operator may be encoded as either a
 | 
			
		||||
number or a string. The message ID operand for the `near` operator must
 | 
			
		||||
be encoded as a string.
 | 
			
		||||
 | 
			
		||||
**Changes**: Prior to Zulip 8.0 (feature level 194), the message ID
 | 
			
		||||
operand for the `id` operator needed to be encoded as a string.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```json
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "operator": "id",
 | 
			
		||||
        "operand": 12345
 | 
			
		||||
    }
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Stream and user IDs
 | 
			
		||||
 | 
			
		||||
There are a few additional narrow/search options (new in Zulip 2.1)
 | 
			
		||||
that use either stream IDs or user IDs that are not documented in the
 | 
			
		||||
help center because they are primarily useful to API clients:
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.9.3"
 | 
			
		||||
# Changes should be accompanied by documentation explaining what the
 | 
			
		||||
# new level means in api_docs/changelog.md, as well as "**Changes**"
 | 
			
		||||
# entries in the endpoint's documentation in `zulip.yaml`.
 | 
			
		||||
API_FEATURE_LEVEL = 193
 | 
			
		||||
API_FEATURE_LEVEL = 194
 | 
			
		||||
 | 
			
		||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
 | 
			
		||||
# only when going from an old version of the code to a newer version. Bump
 | 
			
		||||
 
 | 
			
		||||
@@ -140,13 +140,20 @@ function get_messages_success(data, opts) {
 | 
			
		||||
    process_result(data, opts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This function modifies the data.narrow filters to use user IDs
 | 
			
		||||
// instead of emails string if it is supported. We currently don't set
 | 
			
		||||
// or convert the emails string to user IDs directly into the Filter code
 | 
			
		||||
// because doing so breaks the app in various modules that expect emails string.
 | 
			
		||||
// This function modifies the data.narrow filters to use integer IDs
 | 
			
		||||
// instead of strings if it is supported. We currently don't set or
 | 
			
		||||
// convert user emails to user IDs directly in the Filter code
 | 
			
		||||
// because doing so breaks the app in various modules that expect a
 | 
			
		||||
// string of user emails.
 | 
			
		||||
function handle_operators_supporting_id_based_api(data) {
 | 
			
		||||
    const operators_supporting_ids = new Set(["dm", "pm-with"]);
 | 
			
		||||
    const operators_supporting_id = new Set(["sender", "group-pm-with", "stream", "dm-including"]);
 | 
			
		||||
    const operators_supporting_id = new Set([
 | 
			
		||||
        "id",
 | 
			
		||||
        "stream",
 | 
			
		||||
        "sender",
 | 
			
		||||
        "group-pm-with",
 | 
			
		||||
        "dm-including",
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    if (data.narrow === undefined) {
 | 
			
		||||
        return data;
 | 
			
		||||
@@ -159,6 +166,12 @@ function handle_operators_supporting_id_based_api(data) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (operators_supporting_id.has(filter.operator)) {
 | 
			
		||||
            if (filter.operator === "id") {
 | 
			
		||||
                // The message ID may not exist locally,
 | 
			
		||||
                // so send the filter to the server as is.
 | 
			
		||||
                return filter;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (filter.operator === "stream") {
 | 
			
		||||
                const stream_id = stream_data.get_stream_id(filter.operand);
 | 
			
		||||
                if (stream_id !== undefined) {
 | 
			
		||||
 
 | 
			
		||||
@@ -751,11 +751,17 @@ def narrow_parameter(var_name: str, json: str) -> OptionalNarrowListT:
 | 
			
		||||
            return dict(operator=elem[0], operand=elem[1])
 | 
			
		||||
 | 
			
		||||
        if isinstance(elem, dict):
 | 
			
		||||
            # Make sure to sync this list to frontend also when adding a new operator.
 | 
			
		||||
            # that supports user IDs. Relevant code is located in web/src/message_fetch.js
 | 
			
		||||
            # in handle_operators_supporting_id_based_api function where you will need to update
 | 
			
		||||
            # operators_supporting_id, or operators_supporting_ids array.
 | 
			
		||||
            operators_supporting_id = ["sender", "group-pm-with", "stream", "dm-including"]
 | 
			
		||||
            # Make sure to sync this list to frontend also when adding a new operator that
 | 
			
		||||
            # supports integer IDs. Relevant code is located in web/src/message_fetch.js
 | 
			
		||||
            # in handle_operators_supporting_id_based_api function where you will need to
 | 
			
		||||
            # update operators_supporting_id, or operators_supporting_ids array.
 | 
			
		||||
            operators_supporting_id = [
 | 
			
		||||
                "id",
 | 
			
		||||
                "stream",
 | 
			
		||||
                "sender",
 | 
			
		||||
                "group-pm-with",
 | 
			
		||||
                "dm-including",
 | 
			
		||||
            ]
 | 
			
		||||
            operators_supporting_ids = ["pm-with", "dm"]
 | 
			
		||||
            operators_non_empty_operand = {"search"}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -417,10 +417,14 @@ class NarrowBuilderTest(ZulipTestCase):
 | 
			
		||||
            "WHERE NOT (sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s OR sender_id = %(sender_id_2)s AND recipient_id = %(recipient_id_2)s OR recipient_id IN (__[POSTCOMPILE_recipient_id_3]))",
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_add_term_using_id_operator(self) -> None:
 | 
			
		||||
    def test_add_term_using_id_operator_integer(self) -> None:
 | 
			
		||||
        term = dict(operator="id", operand=555)
 | 
			
		||||
        self._do_add_term_test(term, "WHERE id = %(param_1)s")
 | 
			
		||||
 | 
			
		||||
    def test_add_term_using_id_operator_string(self) -> None:
 | 
			
		||||
        term = dict(operator="id", operand="555")
 | 
			
		||||
        self._do_add_term_test(term, "WHERE id = %(param_1)s")
 | 
			
		||||
 | 
			
		||||
    def test_add_term_using_id_operator_invalid(self) -> None:
 | 
			
		||||
        term = dict(operator="id", operand="")
 | 
			
		||||
        self.assertRaises(BadNarrowOperatorError, self._build_query, term)
 | 
			
		||||
@@ -3412,10 +3416,11 @@ class GetOldMessagesTest(ZulipTestCase):
 | 
			
		||||
    def test_invalid_narrow_operand_in_dict(self) -> None:
 | 
			
		||||
        self.login("hamlet")
 | 
			
		||||
 | 
			
		||||
        # str or int is required for "sender", "stream", "dm-including" and "group-pm-with" operators
 | 
			
		||||
        # str or int is required for "id", "sender", "stream", "dm-including" and "group-pm-with"
 | 
			
		||||
        # operators
 | 
			
		||||
        invalid_operands = [["1"], [2], None]
 | 
			
		||||
        error_msg = 'elem["operand"] is not a string or integer'
 | 
			
		||||
        for operand in ["sender", "group-pm-with", "stream", "dm-including"]:
 | 
			
		||||
        for operand in ["id", "sender", "stream", "dm-including", "group-pm-with"]:
 | 
			
		||||
            self.exercise_bad_narrow_operand_using_dict_api(operand, invalid_operands, error_msg)
 | 
			
		||||
 | 
			
		||||
        # str or int list is required for "dm" and "pm-with" operator
 | 
			
		||||
@@ -3432,7 +3437,7 @@ class GetOldMessagesTest(ZulipTestCase):
 | 
			
		||||
        # For others only str is acceptable
 | 
			
		||||
        invalid_operands = [2, None, [1]]
 | 
			
		||||
        error_msg = 'elem["operand"] is not a string'
 | 
			
		||||
        for operand in ["is", "near", "has", "id"]:
 | 
			
		||||
        for operand in ["is", "near", "has"]:
 | 
			
		||||
            self.exercise_bad_narrow_operand_using_dict_api(operand, invalid_operands, error_msg)
 | 
			
		||||
 | 
			
		||||
        # Disallow empty search terms
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user