mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 15:03:34 +00:00
narrow: Use NarrowParameter instead of dictionary.
Earlier we were using the type `OptionalNarrowListT` for all functions that required "narrow" as a parameter. This commit changes all the functions accepting a "narrow" to use a list of the new `NarrowParameter` instead of `OptionalNarrowListT` which is a list of dicts.
This commit is contained in:
committed by
Tim Abbott
parent
4e05381897
commit
15accfc983
@@ -150,7 +150,7 @@ class NarrowParameter(BaseModel):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def is_spectator_compatible(narrow: Iterable[Dict[str, Any]]) -> bool:
|
def is_spectator_compatible(narrow: Iterable[NarrowParameter]) -> bool:
|
||||||
# This implementation should agree with is_spectator_compatible in hash_parser.ts.
|
# This implementation should agree with is_spectator_compatible in hash_parser.ts.
|
||||||
supported_operators = [
|
supported_operators = [
|
||||||
*channel_operators,
|
*channel_operators,
|
||||||
@@ -163,15 +163,13 @@ def is_spectator_compatible(narrow: Iterable[Dict[str, Any]]) -> bool:
|
|||||||
"id",
|
"id",
|
||||||
]
|
]
|
||||||
for element in narrow:
|
for element in narrow:
|
||||||
operator = element["operator"]
|
operator = element.operator
|
||||||
if "operand" not in element:
|
|
||||||
return False
|
|
||||||
if operator not in supported_operators:
|
if operator not in supported_operators:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def is_web_public_narrow(narrow: Optional[Iterable[Dict[str, Any]]]) -> bool:
|
def is_web_public_narrow(narrow: Optional[Iterable[NarrowParameter]]) -> bool:
|
||||||
if narrow is None:
|
if narrow is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -179,9 +177,9 @@ def is_web_public_narrow(narrow: Optional[Iterable[Dict[str, Any]]]) -> bool:
|
|||||||
# Web-public queries are only allowed for limited types of narrows.
|
# Web-public queries are only allowed for limited types of narrows.
|
||||||
# term == {'operator': 'channels', 'operand': 'web-public', 'negated': False}
|
# term == {'operator': 'channels', 'operand': 'web-public', 'negated': False}
|
||||||
# or term == {'operator': 'streams', 'operand': 'web-public', 'negated': False}
|
# or term == {'operator': 'streams', 'operand': 'web-public', 'negated': False}
|
||||||
term["operator"] in channels_operators
|
term.operator in channels_operators
|
||||||
and term["operand"] == "web-public"
|
and term.operand == "web-public"
|
||||||
and term["negated"] is False
|
and term.negated is False
|
||||||
for term in narrow
|
for term in narrow
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -204,8 +202,6 @@ class BadNarrowOperatorError(JsonableError):
|
|||||||
|
|
||||||
ConditionTransform: TypeAlias = Callable[[ClauseElement], ClauseElement]
|
ConditionTransform: TypeAlias = Callable[[ClauseElement], ClauseElement]
|
||||||
|
|
||||||
OptionalNarrowListT: TypeAlias = Optional[List[Dict[str, Any]]]
|
|
||||||
|
|
||||||
# These delimiters will not appear in rendered messages or HTML-escaped topics.
|
# These delimiters will not appear in rendered messages or HTML-escaped topics.
|
||||||
TS_START = "<ts-match>"
|
TS_START = "<ts-match>"
|
||||||
TS_STOP = "</ts-match>"
|
TS_STOP = "</ts-match>"
|
||||||
@@ -307,7 +303,7 @@ class NarrowBuilder:
|
|||||||
"No message can be both a channel message and direct message"
|
"No message can be both a channel message and direct message"
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_term(self, query: Select, term: Dict[str, Any]) -> Select:
|
def add_term(self, query: Select, term: NarrowParameter) -> Select:
|
||||||
"""
|
"""
|
||||||
Extend the given query to one narrowed by the given term, and return the result.
|
Extend the given query to one narrowed by the given term, and return the result.
|
||||||
|
|
||||||
@@ -320,10 +316,10 @@ class NarrowBuilder:
|
|||||||
# methods to the same criterion. See the class's block comment
|
# methods to the same criterion. See the class's block comment
|
||||||
# for details.
|
# for details.
|
||||||
|
|
||||||
operator = term["operator"]
|
operator = term.operator
|
||||||
operand = term["operand"]
|
operand = term.operand
|
||||||
|
|
||||||
negated = term.get("negated", False)
|
negated = term.negated
|
||||||
|
|
||||||
if operator in self.by_method_map:
|
if operator in self.by_method_map:
|
||||||
method = self.by_method_map[operator]
|
method = self.by_method_map[operator]
|
||||||
@@ -804,7 +800,9 @@ class NarrowBuilder:
|
|||||||
|
|
||||||
|
|
||||||
def ok_to_include_history(
|
def ok_to_include_history(
|
||||||
narrow: OptionalNarrowListT, user_profile: Optional[UserProfile], is_web_public_query: bool
|
narrow: Optional[List[NarrowParameter]],
|
||||||
|
user_profile: Optional[UserProfile],
|
||||||
|
is_web_public_query: bool,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
# There are occasions where we need to find Message rows that
|
# There are occasions where we need to find Message rows that
|
||||||
# have no corresponding UserMessage row, because the user is
|
# have no corresponding UserMessage row, because the user is
|
||||||
@@ -830,16 +828,16 @@ def ok_to_include_history(
|
|||||||
include_history = False
|
include_history = False
|
||||||
if narrow is not None:
|
if narrow is not None:
|
||||||
for term in narrow:
|
for term in narrow:
|
||||||
if term["operator"] in channel_operators and not term.get("negated", False):
|
if term.operator in channel_operators and not term.negated:
|
||||||
operand: Union[str, int] = term["operand"]
|
operand: Union[str, int] = term.operand
|
||||||
if isinstance(operand, str):
|
if isinstance(operand, str):
|
||||||
include_history = can_access_stream_history_by_name(user_profile, operand)
|
include_history = can_access_stream_history_by_name(user_profile, operand)
|
||||||
else:
|
else:
|
||||||
include_history = can_access_stream_history_by_id(user_profile, operand)
|
include_history = can_access_stream_history_by_id(user_profile, operand)
|
||||||
elif (
|
elif (
|
||||||
term["operator"] in channels_operators
|
term.operator in channels_operators
|
||||||
and term["operand"] == "public"
|
and term.operand == "public"
|
||||||
and not term.get("negated", False)
|
and not term.negated
|
||||||
and user_profile.can_access_public_streams()
|
and user_profile.can_access_public_streams()
|
||||||
):
|
):
|
||||||
include_history = True
|
include_history = True
|
||||||
@@ -847,24 +845,24 @@ def ok_to_include_history(
|
|||||||
# that's a property on the UserMessage table. There cannot be
|
# that's a property on the UserMessage table. There cannot be
|
||||||
# historical messages in these cases anyway.
|
# historical messages in these cases anyway.
|
||||||
for term in narrow:
|
for term in narrow:
|
||||||
if term["operator"] == "is" and term["operand"] not in {"resolved", "followed"}:
|
if term.operator == "is" and term.operand not in {"resolved", "followed"}:
|
||||||
include_history = False
|
include_history = False
|
||||||
|
|
||||||
return include_history
|
return include_history
|
||||||
|
|
||||||
|
|
||||||
def get_channel_from_narrow_access_unchecked(
|
def get_channel_from_narrow_access_unchecked(
|
||||||
narrow: OptionalNarrowListT, realm: Realm
|
narrow: Optional[List[NarrowParameter]], realm: Realm
|
||||||
) -> Optional[Stream]:
|
) -> Optional[Stream]:
|
||||||
if narrow is not None:
|
if narrow is not None:
|
||||||
for term in narrow:
|
for term in narrow:
|
||||||
if term["operator"] in channel_operators:
|
if term.operator in channel_operators:
|
||||||
return get_stream_by_narrow_operand_access_unchecked(term["operand"], realm)
|
return get_stream_by_narrow_operand_access_unchecked(term.operand, realm)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def exclude_muting_conditions(
|
def exclude_muting_conditions(
|
||||||
user_profile: UserProfile, narrow: OptionalNarrowListT
|
user_profile: UserProfile, narrow: Optional[List[NarrowParameter]]
|
||||||
) -> List[ClauseElement]:
|
) -> List[ClauseElement]:
|
||||||
conditions: List[ClauseElement] = []
|
conditions: List[ClauseElement] = []
|
||||||
channel_id = None
|
channel_id = None
|
||||||
@@ -957,7 +955,7 @@ def add_narrow_conditions(
|
|||||||
user_profile: Optional[UserProfile],
|
user_profile: Optional[UserProfile],
|
||||||
inner_msg_id_col: ColumnElement[Integer],
|
inner_msg_id_col: ColumnElement[Integer],
|
||||||
query: Select,
|
query: Select,
|
||||||
narrow: OptionalNarrowListT,
|
narrow: Optional[List[NarrowParameter]],
|
||||||
is_web_public_query: bool,
|
is_web_public_query: bool,
|
||||||
realm: Realm,
|
realm: Realm,
|
||||||
) -> Tuple[Select, bool]:
|
) -> Tuple[Select, bool]:
|
||||||
@@ -974,15 +972,15 @@ def add_narrow_conditions(
|
|||||||
# our query, but we need to collect the search operands and handle
|
# our query, but we need to collect the search operands and handle
|
||||||
# them after the loop.
|
# them after the loop.
|
||||||
for term in narrow:
|
for term in narrow:
|
||||||
if term["operator"] == "search":
|
if term.operator == "search":
|
||||||
search_operands.append(term["operand"])
|
search_operands.append(term.operand)
|
||||||
else:
|
else:
|
||||||
query = builder.add_term(query, term)
|
query = builder.add_term(query, term)
|
||||||
|
|
||||||
if search_operands:
|
if search_operands:
|
||||||
is_search = True
|
is_search = True
|
||||||
query = query.add_columns(topic_column_sa(), column("rendered_content", Text))
|
query = query.add_columns(topic_column_sa(), column("rendered_content", Text))
|
||||||
search_term = dict(
|
search_term = NarrowParameter(
|
||||||
operator="search",
|
operator="search",
|
||||||
operand=" ".join(search_operands),
|
operand=" ".join(search_operands),
|
||||||
)
|
)
|
||||||
@@ -992,7 +990,9 @@ def add_narrow_conditions(
|
|||||||
|
|
||||||
|
|
||||||
def find_first_unread_anchor(
|
def find_first_unread_anchor(
|
||||||
sa_conn: Connection, user_profile: Optional[UserProfile], narrow: OptionalNarrowListT
|
sa_conn: Connection,
|
||||||
|
user_profile: Optional[UserProfile],
|
||||||
|
narrow: Optional[List[NarrowParameter]],
|
||||||
) -> int:
|
) -> int:
|
||||||
# For anonymous web users, all messages are treated as read, and so
|
# For anonymous web users, all messages are treated as read, and so
|
||||||
# always return LARGER_THAN_MAX_MESSAGE_ID.
|
# always return LARGER_THAN_MAX_MESSAGE_ID.
|
||||||
@@ -1253,7 +1253,7 @@ class FetchedMessages(LimitedMessages[Row]):
|
|||||||
|
|
||||||
def fetch_messages(
|
def fetch_messages(
|
||||||
*,
|
*,
|
||||||
narrow: OptionalNarrowListT,
|
narrow: Optional[List[NarrowParameter]],
|
||||||
user_profile: Optional[UserProfile],
|
user_profile: Optional[UserProfile],
|
||||||
realm: Realm,
|
realm: Realm,
|
||||||
is_web_public_query: bool,
|
is_web_public_query: bool,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ from zerver.lib.narrow import (
|
|||||||
LARGER_THAN_MAX_MESSAGE_ID,
|
LARGER_THAN_MAX_MESSAGE_ID,
|
||||||
BadNarrowOperatorError,
|
BadNarrowOperatorError,
|
||||||
NarrowBuilder,
|
NarrowBuilder,
|
||||||
|
NarrowParameter,
|
||||||
exclude_muting_conditions,
|
exclude_muting_conditions,
|
||||||
find_first_unread_anchor,
|
find_first_unread_anchor,
|
||||||
is_spectator_compatible,
|
is_spectator_compatible,
|
||||||
@@ -122,31 +123,31 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
self.othello_email = self.example_user("othello").email
|
self.othello_email = self.example_user("othello").email
|
||||||
|
|
||||||
def test_add_term_using_not_defined_operator(self) -> None:
|
def test_add_term_using_not_defined_operator(self) -> None:
|
||||||
term = dict(operator="not-defined", operand="any")
|
term = NarrowParameter(operator="not-defined", operand="any")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_channel_operator(self) -> None:
|
def test_add_term_using_channel_operator(self) -> None:
|
||||||
term = dict(operator="channel", operand="Scotland")
|
term = NarrowParameter(operator="channel", operand="Scotland")
|
||||||
self._do_add_term_test(term, "WHERE recipient_id = %(recipient_id_1)s")
|
self._do_add_term_test(term, "WHERE recipient_id = %(recipient_id_1)s")
|
||||||
|
|
||||||
def test_add_term_using_channel_operator_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_channel_operator_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="channel", operand="Scotland", negated=True)
|
term = NarrowParameter(operator="channel", operand="Scotland", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE recipient_id != %(recipient_id_1)s")
|
self._do_add_term_test(term, "WHERE recipient_id != %(recipient_id_1)s")
|
||||||
|
|
||||||
def test_add_term_using_channel_operator_and_non_existing_operand_should_raise_error(
|
def test_add_term_using_channel_operator_and_non_existing_operand_should_raise_error(
|
||||||
self,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
term = dict(operator="channel", operand="non-existing-channel")
|
term = NarrowParameter(operator="channel", operand="non-existing-channel")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_channels_operator_and_invalid_operand_should_raise_error(
|
def test_add_term_using_channels_operator_and_invalid_operand_should_raise_error(
|
||||||
self,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
term = dict(operator="channels", operand="invalid_operands")
|
term = NarrowParameter(operator="channels", operand="invalid_operands")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_channels_operator_and_public_operand(self) -> None:
|
def test_add_term_using_channels_operator_and_public_operand(self) -> None:
|
||||||
term = dict(operator="channels", operand="public")
|
term = NarrowParameter(operator="channels", operand="public")
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE recipient_id IN (__[POSTCOMPILE_recipient_id_1])",
|
"WHERE recipient_id IN (__[POSTCOMPILE_recipient_id_1])",
|
||||||
@@ -182,7 +183,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_add_term_using_channels_operator_and_public_operand_negated(self) -> None:
|
def test_add_term_using_channels_operator_and_public_operand_negated(self) -> None:
|
||||||
term = dict(operator="channels", operand="public", negated=True)
|
term = NarrowParameter(operator="channels", operand="public", negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (recipient_id NOT IN (__[POSTCOMPILE_recipient_id_1]))",
|
"WHERE (recipient_id NOT IN (__[POSTCOMPILE_recipient_id_1]))",
|
||||||
@@ -218,28 +219,28 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_add_term_using_is_operator_and_dm_operand(self) -> None:
|
def test_add_term_using_is_operator_and_dm_operand(self) -> None:
|
||||||
term = dict(operator="is", operand="dm")
|
term = NarrowParameter(operator="is", operand="dm")
|
||||||
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s")
|
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_is_operator_dm_operand_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_is_operator_dm_operand_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="is", operand="dm", negated=True)
|
term = NarrowParameter(operator="is", operand="dm", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) = %(param_1)s")
|
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) = %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_is_operator_and_non_dm_operand(self) -> None:
|
def test_add_term_using_is_operator_and_non_dm_operand(self) -> None:
|
||||||
for operand in ["starred", "mentioned", "alerted"]:
|
for operand in ["starred", "mentioned", "alerted"]:
|
||||||
term = dict(operator="is", operand=operand)
|
term = NarrowParameter(operator="is", operand=operand)
|
||||||
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s")
|
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_is_operator_and_unread_operand(self) -> None:
|
def test_add_term_using_is_operator_and_unread_operand(self) -> None:
|
||||||
term = dict(operator="is", operand="unread")
|
term = NarrowParameter(operator="is", operand="unread")
|
||||||
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) = %(param_1)s")
|
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) = %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_is_operator_and_unread_operand_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_is_operator_and_unread_operand_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="is", operand="unread", negated=True)
|
term = NarrowParameter(operator="is", operand="unread", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s")
|
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_is_operator_non_dm_operand_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_is_operator_non_dm_operand_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="is", operand="starred", negated=True)
|
term = NarrowParameter(operator="is", operand="starred", negated=True)
|
||||||
where_clause = "WHERE (flags & %(flags_1)s) = %(param_1)s"
|
where_clause = "WHERE (flags & %(flags_1)s) = %(param_1)s"
|
||||||
params = dict(
|
params = dict(
|
||||||
flags_1=UserMessage.flags.starred.mask,
|
flags_1=UserMessage.flags.starred.mask,
|
||||||
@@ -247,7 +248,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
)
|
)
|
||||||
self._do_add_term_test(term, where_clause, params)
|
self._do_add_term_test(term, where_clause, params)
|
||||||
|
|
||||||
term = dict(operator="is", operand="alerted", negated=True)
|
term = NarrowParameter(operator="is", operand="alerted", negated=True)
|
||||||
where_clause = "WHERE (flags & %(flags_1)s) = %(param_1)s"
|
where_clause = "WHERE (flags & %(flags_1)s) = %(param_1)s"
|
||||||
params = dict(
|
params = dict(
|
||||||
flags_1=UserMessage.flags.has_alert_word.mask,
|
flags_1=UserMessage.flags.has_alert_word.mask,
|
||||||
@@ -255,7 +256,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
)
|
)
|
||||||
self._do_add_term_test(term, where_clause, params)
|
self._do_add_term_test(term, where_clause, params)
|
||||||
|
|
||||||
term = dict(operator="is", operand="mentioned", negated=True)
|
term = NarrowParameter(operator="is", operand="mentioned", negated=True)
|
||||||
where_clause = "WHERE (flags & %(flags_1)s) = %(param_1)s"
|
where_clause = "WHERE (flags & %(flags_1)s) = %(param_1)s"
|
||||||
mention_flags_mask = (
|
mention_flags_mask = (
|
||||||
UserMessage.flags.mentioned.mask
|
UserMessage.flags.mentioned.mask
|
||||||
@@ -270,63 +271,63 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
self._do_add_term_test(term, where_clause, params)
|
self._do_add_term_test(term, where_clause, params)
|
||||||
|
|
||||||
def test_add_term_using_is_operator_for_resolved_topics(self) -> None:
|
def test_add_term_using_is_operator_for_resolved_topics(self) -> None:
|
||||||
term = dict(operator="is", operand="resolved")
|
term = NarrowParameter(operator="is", operand="resolved")
|
||||||
self._do_add_term_test(term, "WHERE (subject LIKE %(subject_1)s || '%%'")
|
self._do_add_term_test(term, "WHERE (subject LIKE %(subject_1)s || '%%'")
|
||||||
|
|
||||||
def test_add_term_using_is_operator_for_negated_resolved_topics(self) -> None:
|
def test_add_term_using_is_operator_for_negated_resolved_topics(self) -> None:
|
||||||
term = dict(operator="is", operand="resolved", negated=True)
|
term = NarrowParameter(operator="is", operand="resolved", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE (subject NOT LIKE %(subject_1)s || '%%'")
|
self._do_add_term_test(term, "WHERE (subject NOT LIKE %(subject_1)s || '%%'")
|
||||||
|
|
||||||
def test_add_term_using_is_operator_for_followed_topics(self) -> None:
|
def test_add_term_using_is_operator_for_followed_topics(self) -> None:
|
||||||
term = dict(operator="is", operand="followed", negated=False)
|
term = NarrowParameter(operator="is", operand="followed", negated=False)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"EXISTS (SELECT 1 \nFROM zerver_usertopic \nWHERE zerver_usertopic.user_profile_id = %(param_1)s AND zerver_usertopic.visibility_policy = %(param_2)s AND upper(zerver_usertopic.topic_name) = upper(zerver_message.subject) AND zerver_usertopic.recipient_id = zerver_message.recipient_id)",
|
"EXISTS (SELECT 1 \nFROM zerver_usertopic \nWHERE zerver_usertopic.user_profile_id = %(param_1)s AND zerver_usertopic.visibility_policy = %(param_2)s AND upper(zerver_usertopic.topic_name) = upper(zerver_message.subject) AND zerver_usertopic.recipient_id = zerver_message.recipient_id)",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_add_term_using_is_operator_for_negated_followed_topics(self) -> None:
|
def test_add_term_using_is_operator_for_negated_followed_topics(self) -> None:
|
||||||
term = dict(operator="is", operand="followed", negated=True)
|
term = NarrowParameter(operator="is", operand="followed", negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"NOT (EXISTS (SELECT 1 \nFROM zerver_usertopic \nWHERE zerver_usertopic.user_profile_id = %(param_1)s AND zerver_usertopic.visibility_policy = %(param_2)s AND upper(zerver_usertopic.topic_name) = upper(zerver_message.subject) AND zerver_usertopic.recipient_id = zerver_message.recipient_id))",
|
"NOT (EXISTS (SELECT 1 \nFROM zerver_usertopic \nWHERE zerver_usertopic.user_profile_id = %(param_1)s AND zerver_usertopic.visibility_policy = %(param_2)s AND upper(zerver_usertopic.topic_name) = upper(zerver_message.subject) AND zerver_usertopic.recipient_id = zerver_message.recipient_id))",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_add_term_using_non_supported_operator_should_raise_error(self) -> None:
|
def test_add_term_using_non_supported_operator_should_raise_error(self) -> None:
|
||||||
term = dict(operator="is", operand="non_supported")
|
term = NarrowParameter(operator="is", operand="non_supported")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_topic_operator_and_lunch_operand(self) -> None:
|
def test_add_term_using_topic_operator_and_lunch_operand(self) -> None:
|
||||||
term = dict(operator="topic", operand="lunch")
|
term = NarrowParameter(operator="topic", operand="lunch")
|
||||||
self._do_add_term_test(term, "WHERE upper(subject) = upper(%(param_1)s)")
|
self._do_add_term_test(term, "WHERE upper(subject) = upper(%(param_1)s)")
|
||||||
|
|
||||||
def test_add_term_using_topic_operator_lunch_operand_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_topic_operator_lunch_operand_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="topic", operand="lunch", negated=True)
|
term = NarrowParameter(operator="topic", operand="lunch", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE upper(subject) != upper(%(param_1)s)")
|
self._do_add_term_test(term, "WHERE upper(subject) != upper(%(param_1)s)")
|
||||||
|
|
||||||
def test_add_term_using_topic_operator_and_personal_operand(self) -> None:
|
def test_add_term_using_topic_operator_and_personal_operand(self) -> None:
|
||||||
term = dict(operator="topic", operand="personal")
|
term = NarrowParameter(operator="topic", operand="personal")
|
||||||
self._do_add_term_test(term, "WHERE upper(subject) = upper(%(param_1)s)")
|
self._do_add_term_test(term, "WHERE upper(subject) = upper(%(param_1)s)")
|
||||||
|
|
||||||
def test_add_term_using_topic_operator_personal_operand_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_topic_operator_personal_operand_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="topic", operand="personal", negated=True)
|
term = NarrowParameter(operator="topic", operand="personal", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE upper(subject) != upper(%(param_1)s)")
|
self._do_add_term_test(term, "WHERE upper(subject) != upper(%(param_1)s)")
|
||||||
|
|
||||||
def test_add_term_using_sender_operator(self) -> None:
|
def test_add_term_using_sender_operator(self) -> None:
|
||||||
term = dict(operator="sender", operand=self.othello_email)
|
term = NarrowParameter(operator="sender", operand=self.othello_email)
|
||||||
self._do_add_term_test(term, "WHERE sender_id = %(param_1)s")
|
self._do_add_term_test(term, "WHERE sender_id = %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_sender_operator_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_sender_operator_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="sender", operand=self.othello_email, negated=True)
|
term = NarrowParameter(operator="sender", operand=self.othello_email, negated=True)
|
||||||
self._do_add_term_test(term, "WHERE sender_id != %(param_1)s")
|
self._do_add_term_test(term, "WHERE sender_id != %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_sender_operator_with_non_existing_user_as_operand(
|
def test_add_term_using_sender_operator_with_non_existing_user_as_operand(
|
||||||
self,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
term = dict(operator="sender", operand="non-existing@zulip.com")
|
term = NarrowParameter(operator="sender", operand="non-existing@zulip.com")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_dm_operator_and_not_the_same_user_as_operand(self) -> None:
|
def test_add_term_using_dm_operator_and_not_the_same_user_as_operand(self) -> None:
|
||||||
term = dict(operator="dm", operand=self.othello_email)
|
term = NarrowParameter(operator="dm", operand=self.othello_email)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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)",
|
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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)",
|
||||||
@@ -336,15 +337,15 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
expected_error_message = (
|
expected_error_message = (
|
||||||
"Invalid narrow operator: No message can be both a channel message and direct message"
|
"Invalid narrow operator: No message can be both a channel message and direct message"
|
||||||
)
|
)
|
||||||
term1 = dict(operator="dm", operand=self.othello_email)
|
term1 = NarrowParameter(operator="dm", operand=self.othello_email)
|
||||||
self._build_query(term1)
|
self._build_query(term1)
|
||||||
|
|
||||||
topic_term = dict(operator="topic", operand="bogus")
|
topic_term = NarrowParameter(operator="topic", operand="bogus")
|
||||||
with self.assertRaises(BadNarrowOperatorError) as error:
|
with self.assertRaises(BadNarrowOperatorError) as error:
|
||||||
self._build_query(topic_term)
|
self._build_query(topic_term)
|
||||||
self.assertEqual(expected_error_message, str(error.exception))
|
self.assertEqual(expected_error_message, str(error.exception))
|
||||||
|
|
||||||
channels_term = dict(operator="channels", operand="public")
|
channels_term = NarrowParameter(operator="channels", operand="public")
|
||||||
with self.assertRaises(BadNarrowOperatorError) as error:
|
with self.assertRaises(BadNarrowOperatorError) as error:
|
||||||
self._build_query(channels_term)
|
self._build_query(channels_term)
|
||||||
self.assertEqual(expected_error_message, str(error.exception))
|
self.assertEqual(expected_error_message, str(error.exception))
|
||||||
@@ -352,14 +353,14 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
def test_add_term_using_dm_operator_not_the_same_user_as_operand_and_negated(
|
def test_add_term_using_dm_operator_not_the_same_user_as_operand_and_negated(
|
||||||
self,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
term = dict(operator="dm", operand=self.othello_email, negated=True)
|
term = NarrowParameter(operator="dm", operand=self.othello_email, negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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))",
|
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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))",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_add_term_using_dm_operator_the_same_user_as_operand(self) -> None:
|
def test_add_term_using_dm_operator_the_same_user_as_operand(self) -> None:
|
||||||
term = dict(operator="dm", operand=self.hamlet_email)
|
term = NarrowParameter(operator="dm", operand=self.hamlet_email)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s",
|
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s",
|
||||||
@@ -368,7 +369,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
def test_add_term_using_dm_operator_the_same_user_as_operand_and_negated(
|
def test_add_term_using_dm_operator_the_same_user_as_operand_and_negated(
|
||||||
self,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
term = dict(operator="dm", operand=self.hamlet_email, negated=True)
|
term = NarrowParameter(operator="dm", operand=self.hamlet_email, negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s)",
|
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s)",
|
||||||
@@ -378,7 +379,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
myself_and_other = (
|
myself_and_other = (
|
||||||
f"{self.example_user('hamlet').email},{self.example_user('othello').email}"
|
f"{self.example_user('hamlet').email},{self.example_user('othello').email}"
|
||||||
)
|
)
|
||||||
term = dict(operator="dm", operand=myself_and_other)
|
term = NarrowParameter(operator="dm", operand=myself_and_other)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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)",
|
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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)",
|
||||||
@@ -387,7 +388,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
def test_add_term_using_dm_operator_more_than_one_user_as_operand_no_huddle(self) -> None:
|
def test_add_term_using_dm_operator_more_than_one_user_as_operand_no_huddle(self) -> None:
|
||||||
# If the group doesn't exist, it's a flat false
|
# If the group doesn't exist, it's a flat false
|
||||||
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
|
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
|
||||||
term = dict(operator="dm", operand=two_others)
|
term = NarrowParameter(operator="dm", operand=two_others)
|
||||||
self._do_add_term_test(term, "WHERE false")
|
self._do_add_term_test(term, "WHERE false")
|
||||||
|
|
||||||
def test_add_term_using_dm_operator_more_than_one_user_as_operand(self) -> None:
|
def test_add_term_using_dm_operator_more_than_one_user_as_operand(self) -> None:
|
||||||
@@ -400,7 +401,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
|
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
|
||||||
term = dict(operator="dm", operand=two_others)
|
term = NarrowParameter(operator="dm", operand=two_others)
|
||||||
self._do_add_term_test(term, "WHERE recipient_id = %(recipient_id_1)s")
|
self._do_add_term_test(term, "WHERE recipient_id = %(recipient_id_1)s")
|
||||||
|
|
||||||
def test_add_term_using_dm_operator_self_and_user_as_operand_and_negated(
|
def test_add_term_using_dm_operator_self_and_user_as_operand_and_negated(
|
||||||
@@ -409,7 +410,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
myself_and_other = (
|
myself_and_other = (
|
||||||
f"{self.example_user('hamlet').email},{self.example_user('othello').email}"
|
f"{self.example_user('hamlet').email},{self.example_user('othello').email}"
|
||||||
)
|
)
|
||||||
term = dict(operator="dm", operand=myself_and_other, negated=True)
|
term = NarrowParameter(operator="dm", operand=myself_and_other, negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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))",
|
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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))",
|
||||||
@@ -420,7 +421,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
# If the group doesn't exist, it's a flat true
|
# If the group doesn't exist, it's a flat true
|
||||||
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
|
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
|
||||||
term = dict(operator="dm", operand=two_others, negated=True)
|
term = NarrowParameter(operator="dm", operand=two_others, negated=True)
|
||||||
self._do_add_term_test(term, "WHERE true")
|
self._do_add_term_test(term, "WHERE true")
|
||||||
|
|
||||||
def test_add_term_using_dm_operator_more_than_one_user_as_operand_and_negated(
|
def test_add_term_using_dm_operator_more_than_one_user_as_operand_and_negated(
|
||||||
@@ -435,26 +436,28 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
|
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
|
||||||
term = dict(operator="dm", operand=two_others, negated=True)
|
term = NarrowParameter(operator="dm", operand=two_others, negated=True)
|
||||||
self._do_add_term_test(term, "WHERE recipient_id != %(recipient_id_1)s")
|
self._do_add_term_test(term, "WHERE recipient_id != %(recipient_id_1)s")
|
||||||
|
|
||||||
def test_add_term_using_dm_operator_with_comma_noise(self) -> None:
|
def test_add_term_using_dm_operator_with_comma_noise(self) -> None:
|
||||||
term = dict(operator="dm", operand=" ,,, ,,, ,")
|
term = NarrowParameter(operator="dm", operand=" ,,, ,,, ,")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_dm_operator_with_existing_and_non_existing_user_as_operand(
|
def test_add_term_using_dm_operator_with_existing_and_non_existing_user_as_operand(
|
||||||
self,
|
self,
|
||||||
) -> None:
|
) -> None:
|
||||||
term = dict(operator="dm", operand=self.othello_email + ",non-existing@zulip.com")
|
term = NarrowParameter(
|
||||||
|
operator="dm", operand=self.othello_email + ",non-existing@zulip.com"
|
||||||
|
)
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_dm_including_operator_with_logged_in_user_email(self) -> None:
|
def test_add_term_using_dm_including_operator_with_logged_in_user_email(self) -> None:
|
||||||
term = dict(operator="dm-including", operand=self.hamlet_email)
|
term = NarrowParameter(operator="dm-including", operand=self.hamlet_email)
|
||||||
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s")
|
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_dm_including_operator_with_different_user_email(self) -> None:
|
def test_add_term_using_dm_including_operator_with_different_user_email(self) -> None:
|
||||||
# Test without any such group direct messages existing
|
# Test without any such group direct messages existing
|
||||||
term = dict(operator="dm-including", operand=self.othello_email)
|
term = NarrowParameter(operator="dm-including", operand=self.othello_email)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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]))",
|
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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]))",
|
||||||
@@ -465,7 +468,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
self.user_profile, [self.example_user("othello"), self.example_user("cordelia")]
|
self.user_profile, [self.example_user("othello"), self.example_user("cordelia")]
|
||||||
)
|
)
|
||||||
|
|
||||||
term = dict(operator="dm-including", operand=self.othello_email)
|
term = NarrowParameter(operator="dm-including", operand=self.othello_email)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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]))",
|
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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]))",
|
||||||
@@ -474,37 +477,37 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
def test_add_term_using_dm_including_operator_with_different_user_email_and_negated(
|
def test_add_term_using_dm_including_operator_with_different_user_email_and_negated(
|
||||||
self,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
term = dict(operator="dm-including", operand=self.othello_email, negated=True)
|
term = NarrowParameter(operator="dm-including", operand=self.othello_email, negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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])))",
|
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (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_integer(self) -> None:
|
def test_add_term_using_id_operator_integer(self) -> None:
|
||||||
term = dict(operator="id", operand=555)
|
term = NarrowParameter(operator="id", operand=555)
|
||||||
self._do_add_term_test(term, "WHERE id = %(param_1)s")
|
self._do_add_term_test(term, "WHERE id = %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_id_operator_string(self) -> None:
|
def test_add_term_using_id_operator_string(self) -> None:
|
||||||
term = dict(operator="id", operand="555")
|
term = NarrowParameter(operator="id", operand="555")
|
||||||
self._do_add_term_test(term, "WHERE id = %(param_1)s")
|
self._do_add_term_test(term, "WHERE id = %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_id_operator_invalid(self) -> None:
|
def test_add_term_using_id_operator_invalid(self) -> None:
|
||||||
term = dict(operator="id", operand="")
|
term = NarrowParameter(operator="id", operand="")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
term = dict(operator="id", operand="notanint")
|
term = NarrowParameter(operator="id", operand="notanint")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
term = dict(operator="id", operand=str(Message.MAX_POSSIBLE_MESSAGE_ID + 1))
|
term = NarrowParameter(operator="id", operand=str(Message.MAX_POSSIBLE_MESSAGE_ID + 1))
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_id_operator_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_id_operator_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="id", operand=555, negated=True)
|
term = NarrowParameter(operator="id", operand=555, negated=True)
|
||||||
self._do_add_term_test(term, "WHERE id != %(param_1)s")
|
self._do_add_term_test(term, "WHERE id != %(param_1)s")
|
||||||
|
|
||||||
@override_settings(USING_PGROONGA=False)
|
@override_settings(USING_PGROONGA=False)
|
||||||
def test_add_term_using_search_operator(self) -> None:
|
def test_add_term_using_search_operator(self) -> None:
|
||||||
term = dict(operator="search", operand='"french fries"')
|
term = NarrowParameter(operator="search", operand='"french fries"')
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (content ILIKE %(content_1)s OR subject ILIKE %(subject_1)s) AND (search_tsvector @@ plainto_tsquery(%(param_4)s, %(param_5)s))",
|
"WHERE (content ILIKE %(content_1)s OR subject ILIKE %(subject_1)s) AND (search_tsvector @@ plainto_tsquery(%(param_4)s, %(param_5)s))",
|
||||||
@@ -512,7 +515,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
|
|
||||||
@override_settings(USING_PGROONGA=False)
|
@override_settings(USING_PGROONGA=False)
|
||||||
def test_add_term_using_search_operator_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_search_operator_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="search", operand='"french fries"', negated=True)
|
term = NarrowParameter(operator="search", operand='"french fries"', negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE NOT (content ILIKE %(content_1)s OR subject ILIKE %(subject_1)s) AND NOT (search_tsvector @@ plainto_tsquery(%(param_4)s, %(param_5)s))",
|
"WHERE NOT (content ILIKE %(content_1)s OR subject ILIKE %(subject_1)s) AND NOT (search_tsvector @@ plainto_tsquery(%(param_4)s, %(param_5)s))",
|
||||||
@@ -520,113 +523,113 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
|
|
||||||
@override_settings(USING_PGROONGA=True)
|
@override_settings(USING_PGROONGA=True)
|
||||||
def test_add_term_using_search_operator_pgroonga(self) -> None:
|
def test_add_term_using_search_operator_pgroonga(self) -> None:
|
||||||
term = dict(operator="search", operand='"french fries"')
|
term = NarrowParameter(operator="search", operand='"french fries"')
|
||||||
self._do_add_term_test(term, "WHERE search_pgroonga &@~ escape_html(%(escape_html_1)s)")
|
self._do_add_term_test(term, "WHERE search_pgroonga &@~ escape_html(%(escape_html_1)s)")
|
||||||
|
|
||||||
@override_settings(USING_PGROONGA=True)
|
@override_settings(USING_PGROONGA=True)
|
||||||
def test_add_term_using_search_operator_and_negated_pgroonga(self) -> None: # NEGATED
|
def test_add_term_using_search_operator_and_negated_pgroonga(self) -> None: # NEGATED
|
||||||
term = dict(operator="search", operand='"french fries"', negated=True)
|
term = NarrowParameter(operator="search", operand='"french fries"', negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term, "WHERE NOT (search_pgroonga &@~ escape_html(%(escape_html_1)s))"
|
term, "WHERE NOT (search_pgroonga &@~ escape_html(%(escape_html_1)s))"
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_add_term_using_has_operator_and_attachment_operand(self) -> None:
|
def test_add_term_using_has_operator_and_attachment_operand(self) -> None:
|
||||||
term = dict(operator="has", operand="attachment")
|
term = NarrowParameter(operator="has", operand="attachment")
|
||||||
self._do_add_term_test(term, "WHERE has_attachment")
|
self._do_add_term_test(term, "WHERE has_attachment")
|
||||||
|
|
||||||
def test_add_term_using_has_operator_attachment_operand_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_has_operator_attachment_operand_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="has", operand="attachment", negated=True)
|
term = NarrowParameter(operator="has", operand="attachment", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE NOT has_attachment")
|
self._do_add_term_test(term, "WHERE NOT has_attachment")
|
||||||
|
|
||||||
def test_add_term_using_has_operator_and_image_operand(self) -> None:
|
def test_add_term_using_has_operator_and_image_operand(self) -> None:
|
||||||
term = dict(operator="has", operand="image")
|
term = NarrowParameter(operator="has", operand="image")
|
||||||
self._do_add_term_test(term, "WHERE has_image")
|
self._do_add_term_test(term, "WHERE has_image")
|
||||||
|
|
||||||
def test_add_term_using_has_operator_image_operand_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_has_operator_image_operand_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="has", operand="image", negated=True)
|
term = NarrowParameter(operator="has", operand="image", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE NOT has_image")
|
self._do_add_term_test(term, "WHERE NOT has_image")
|
||||||
|
|
||||||
def test_add_term_using_has_operator_and_link_operand(self) -> None:
|
def test_add_term_using_has_operator_and_link_operand(self) -> None:
|
||||||
term = dict(operator="has", operand="link")
|
term = NarrowParameter(operator="has", operand="link")
|
||||||
self._do_add_term_test(term, "WHERE has_link")
|
self._do_add_term_test(term, "WHERE has_link")
|
||||||
|
|
||||||
def test_add_term_using_has_operator_link_operand_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_has_operator_link_operand_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="has", operand="link", negated=True)
|
term = NarrowParameter(operator="has", operand="link", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE NOT has_link")
|
self._do_add_term_test(term, "WHERE NOT has_link")
|
||||||
|
|
||||||
def test_add_term_using_has_operator_and_reaction_operand(self) -> None:
|
def test_add_term_using_has_operator_and_reaction_operand(self) -> None:
|
||||||
term = dict(operator="has", operand="reaction")
|
term = NarrowParameter(operator="has", operand="reaction")
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"EXISTS (SELECT 1 \nFROM zerver_reaction \nWHERE zerver_message.id = zerver_reaction.message_id)",
|
"EXISTS (SELECT 1 \nFROM zerver_reaction \nWHERE zerver_message.id = zerver_reaction.message_id)",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_add_term_using_has_operator_and_reaction_operand_and_negated(self) -> None:
|
def test_add_term_using_has_operator_and_reaction_operand_and_negated(self) -> None:
|
||||||
term = dict(operator="has", operand="reaction", negated=True)
|
term = NarrowParameter(operator="has", operand="reaction", negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"NOT (EXISTS (SELECT 1 \nFROM zerver_reaction \nWHERE zerver_message.id = zerver_reaction.message_id))",
|
"NOT (EXISTS (SELECT 1 \nFROM zerver_reaction \nWHERE zerver_message.id = zerver_reaction.message_id))",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_add_term_using_has_operator_non_supported_operand_should_raise_error(self) -> None:
|
def test_add_term_using_has_operator_non_supported_operand_should_raise_error(self) -> None:
|
||||||
term = dict(operator="has", operand="non_supported")
|
term = NarrowParameter(operator="has", operand="non_supported")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_in_operator(self) -> None:
|
def test_add_term_using_in_operator(self) -> None:
|
||||||
mute_channel(self.realm, self.user_profile, "Verona")
|
mute_channel(self.realm, self.user_profile, "Verona")
|
||||||
term = dict(operator="in", operand="home")
|
term = NarrowParameter(operator="in", operand="home")
|
||||||
self._do_add_term_test(term, "WHERE (recipient_id NOT IN (__[POSTCOMPILE_recipient_id_1]))")
|
self._do_add_term_test(term, "WHERE (recipient_id NOT IN (__[POSTCOMPILE_recipient_id_1]))")
|
||||||
|
|
||||||
def test_add_term_using_in_operator_and_negated(self) -> None:
|
def test_add_term_using_in_operator_and_negated(self) -> None:
|
||||||
# negated = True should not change anything
|
# negated = True should not change anything
|
||||||
mute_channel(self.realm, self.user_profile, "Verona")
|
mute_channel(self.realm, self.user_profile, "Verona")
|
||||||
term = dict(operator="in", operand="home", negated=True)
|
term = NarrowParameter(operator="in", operand="home", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE (recipient_id NOT IN (__[POSTCOMPILE_recipient_id_1]))")
|
self._do_add_term_test(term, "WHERE (recipient_id NOT IN (__[POSTCOMPILE_recipient_id_1]))")
|
||||||
|
|
||||||
def test_add_term_using_in_operator_and_all_operand(self) -> None:
|
def test_add_term_using_in_operator_and_all_operand(self) -> None:
|
||||||
mute_channel(self.realm, self.user_profile, "Verona")
|
mute_channel(self.realm, self.user_profile, "Verona")
|
||||||
term = dict(operator="in", operand="all")
|
term = NarrowParameter(operator="in", operand="all")
|
||||||
query = self._build_query(term)
|
query = self._build_query(term)
|
||||||
self.assertEqual(get_sqlalchemy_sql(query), "SELECT id \nFROM zerver_message")
|
self.assertEqual(get_sqlalchemy_sql(query), "SELECT id \nFROM zerver_message")
|
||||||
|
|
||||||
def test_add_term_using_in_operator_all_operand_and_negated(self) -> None:
|
def test_add_term_using_in_operator_all_operand_and_negated(self) -> None:
|
||||||
# negated = True should not change anything
|
# negated = True should not change anything
|
||||||
mute_channel(self.realm, self.user_profile, "Verona")
|
mute_channel(self.realm, self.user_profile, "Verona")
|
||||||
term = dict(operator="in", operand="all", negated=True)
|
term = NarrowParameter(operator="in", operand="all", negated=True)
|
||||||
query = self._build_query(term)
|
query = self._build_query(term)
|
||||||
self.assertEqual(get_sqlalchemy_sql(query), "SELECT id \nFROM zerver_message")
|
self.assertEqual(get_sqlalchemy_sql(query), "SELECT id \nFROM zerver_message")
|
||||||
|
|
||||||
def test_add_term_using_in_operator_and_not_defined_operand(self) -> None:
|
def test_add_term_using_in_operator_and_not_defined_operand(self) -> None:
|
||||||
term = dict(operator="in", operand="not_defined")
|
term = NarrowParameter(operator="in", operand="not_defined")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_near_operator(self) -> None:
|
def test_add_term_using_near_operator(self) -> None:
|
||||||
term = dict(operator="near", operand="operand")
|
term = NarrowParameter(operator="near", operand="operand")
|
||||||
query = self._build_query(term)
|
query = self._build_query(term)
|
||||||
self.assertEqual(get_sqlalchemy_sql(query), "SELECT id \nFROM zerver_message")
|
self.assertEqual(get_sqlalchemy_sql(query), "SELECT id \nFROM zerver_message")
|
||||||
|
|
||||||
def test_add_term_non_web_public_channel_in_web_public_query(self) -> None:
|
def test_add_term_non_web_public_channel_in_web_public_query(self) -> None:
|
||||||
self.make_stream("non-web-public-channel", realm=self.realm)
|
self.make_stream("non-web-public-channel", realm=self.realm)
|
||||||
term = dict(operator="channel", operand="non-web-public-channel")
|
term = NarrowParameter(operator="channel", operand="non-web-public-channel")
|
||||||
builder = NarrowBuilder(self.user_profile, column("id", Integer), self.realm, True)
|
builder = NarrowBuilder(self.user_profile, column("id", Integer), self.realm, True)
|
||||||
|
|
||||||
def _build_query(term: Dict[str, Any]) -> Select:
|
def _build_query(term: NarrowParameter) -> Select:
|
||||||
return builder.add_term(self.raw_query, term)
|
return builder.add_term(self.raw_query, term)
|
||||||
|
|
||||||
self.assertRaises(BadNarrowOperatorError, _build_query, term)
|
self.assertRaises(BadNarrowOperatorError, _build_query, term)
|
||||||
|
|
||||||
# Test "is:private" (legacy alias for "is:dm")
|
# Test "is:private" (legacy alias for "is:dm")
|
||||||
def test_add_term_using_is_operator_and_private_operand(self) -> None:
|
def test_add_term_using_is_operator_and_private_operand(self) -> None:
|
||||||
term = dict(operator="is", operand="private")
|
term = NarrowParameter(operator="is", operand="private")
|
||||||
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s")
|
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) != %(param_1)s")
|
||||||
|
|
||||||
def test_add_term_using_is_operator_private_operand_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_is_operator_private_operand_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="is", operand="private", negated=True)
|
term = NarrowParameter(operator="is", operand="private", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) = %(param_1)s")
|
self._do_add_term_test(term, "WHERE (flags & %(flags_1)s) = %(param_1)s")
|
||||||
|
|
||||||
# Test that "pm-with" (legacy alias for "dm") works.
|
# Test that "pm-with" (legacy alias for "dm") works.
|
||||||
def test_add_term_using_pm_with_operator(self) -> None:
|
def test_add_term_using_pm_with_operator(self) -> None:
|
||||||
term = dict(operator="pm-with", operand=self.hamlet_email)
|
term = NarrowParameter(operator="pm-with", operand=self.hamlet_email)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s",
|
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s",
|
||||||
@@ -634,7 +637,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
|
|
||||||
# Test that the underscore version of "pm-with" works.
|
# Test that the underscore version of "pm-with" works.
|
||||||
def test_add_term_using_underscore_version_of_pm_with_operator(self) -> None:
|
def test_add_term_using_underscore_version_of_pm_with_operator(self) -> None:
|
||||||
term = dict(operator="pm_with", operand=self.hamlet_email)
|
term = NarrowParameter(operator="pm_with", operand=self.hamlet_email)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s",
|
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s",
|
||||||
@@ -642,11 +645,11 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
|
|
||||||
# Test that deprecated "group-pm-with" (replaced by "dm-including" ) works.
|
# Test that deprecated "group-pm-with" (replaced by "dm-including" ) works.
|
||||||
def test_add_term_using_dm_including_operator_with_non_existing_user(self) -> None:
|
def test_add_term_using_dm_including_operator_with_non_existing_user(self) -> None:
|
||||||
term = dict(operator="dm-including", operand="non-existing@zulip.com")
|
term = NarrowParameter(operator="dm-including", operand="non-existing@zulip.com")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_group_pm_operator_and_not_the_same_user_as_operand(self) -> None:
|
def test_add_term_using_group_pm_operator_and_not_the_same_user_as_operand(self) -> None:
|
||||||
term = dict(operator="group-pm-with", operand=self.othello_email)
|
term = NarrowParameter(operator="group-pm-with", operand=self.othello_email)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND recipient_id IN (__[POSTCOMPILE_recipient_id_1])",
|
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND recipient_id IN (__[POSTCOMPILE_recipient_id_1])",
|
||||||
@@ -655,19 +658,19 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
def test_add_term_using_group_pm_operator_not_the_same_user_as_operand_and_negated(
|
def test_add_term_using_group_pm_operator_not_the_same_user_as_operand_and_negated(
|
||||||
self,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
term = dict(operator="group-pm-with", operand=self.othello_email, negated=True)
|
term = NarrowParameter(operator="group-pm-with", operand=self.othello_email, negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND recipient_id IN (__[POSTCOMPILE_recipient_id_1]))",
|
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND recipient_id IN (__[POSTCOMPILE_recipient_id_1]))",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_add_term_using_group_pm_operator_with_non_existing_user_as_operand(self) -> None:
|
def test_add_term_using_group_pm_operator_with_non_existing_user_as_operand(self) -> None:
|
||||||
term = dict(operator="group-pm-with", operand="non-existing@zulip.com")
|
term = NarrowParameter(operator="group-pm-with", operand="non-existing@zulip.com")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
# Test that the underscore version of "group-pm-with" works.
|
# Test that the underscore version of "group-pm-with" works.
|
||||||
def test_add_term_using_underscore_version_of_group_pm_with_operator(self) -> None:
|
def test_add_term_using_underscore_version_of_group_pm_with_operator(self) -> None:
|
||||||
term = dict(operator="group_pm_with", operand=self.othello_email)
|
term = NarrowParameter(operator="group_pm_with", operand=self.othello_email)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND recipient_id IN (__[POSTCOMPILE_recipient_id_1])",
|
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND recipient_id IN (__[POSTCOMPILE_recipient_id_1])",
|
||||||
@@ -675,42 +678,42 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
|
|
||||||
# Test that "stream" (legacy alias for "channel" operator) works.
|
# Test that "stream" (legacy alias for "channel" operator) works.
|
||||||
def test_add_term_using_stream_operator(self) -> None:
|
def test_add_term_using_stream_operator(self) -> None:
|
||||||
term = dict(operator="stream", operand="Scotland")
|
term = NarrowParameter(operator="stream", operand="Scotland")
|
||||||
self._do_add_term_test(term, "WHERE recipient_id = %(recipient_id_1)s")
|
self._do_add_term_test(term, "WHERE recipient_id = %(recipient_id_1)s")
|
||||||
|
|
||||||
def test_add_term_using_stream_operator_and_negated(self) -> None: # NEGATED
|
def test_add_term_using_stream_operator_and_negated(self) -> None: # NEGATED
|
||||||
term = dict(operator="stream", operand="Scotland", negated=True)
|
term = NarrowParameter(operator="stream", operand="Scotland", negated=True)
|
||||||
self._do_add_term_test(term, "WHERE recipient_id != %(recipient_id_1)s")
|
self._do_add_term_test(term, "WHERE recipient_id != %(recipient_id_1)s")
|
||||||
|
|
||||||
def test_add_term_using_stream_operator_and_non_existing_operand_should_raise_error(
|
def test_add_term_using_stream_operator_and_non_existing_operand_should_raise_error(
|
||||||
self,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
term = dict(operator="stream", operand="non-existing-channel")
|
term = NarrowParameter(operator="stream", operand="non-existing-channel")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
# Test that "streams" (legacy alias for "channels" operator) works.
|
# Test that "streams" (legacy alias for "channels" operator) works.
|
||||||
def test_add_term_using_streams_operator_and_invalid_operand_should_raise_error(
|
def test_add_term_using_streams_operator_and_invalid_operand_should_raise_error(
|
||||||
self,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
term = dict(operator="streams", operand="invalid_operands")
|
term = NarrowParameter(operator="streams", operand="invalid_operands")
|
||||||
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
self.assertRaises(BadNarrowOperatorError, self._build_query, term)
|
||||||
|
|
||||||
def test_add_term_using_streams_operator_and_public_operand(self) -> None:
|
def test_add_term_using_streams_operator_and_public_operand(self) -> None:
|
||||||
term = dict(operator="streams", operand="public")
|
term = NarrowParameter(operator="streams", operand="public")
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE recipient_id IN (__[POSTCOMPILE_recipient_id_1])",
|
"WHERE recipient_id IN (__[POSTCOMPILE_recipient_id_1])",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_add_term_using_streams_operator_and_public_operand_negated(self) -> None:
|
def test_add_term_using_streams_operator_and_public_operand_negated(self) -> None:
|
||||||
term = dict(operator="streams", operand="public", negated=True)
|
term = NarrowParameter(operator="streams", operand="public", negated=True)
|
||||||
self._do_add_term_test(
|
self._do_add_term_test(
|
||||||
term,
|
term,
|
||||||
"WHERE (recipient_id NOT IN (__[POSTCOMPILE_recipient_id_1]))",
|
"WHERE (recipient_id NOT IN (__[POSTCOMPILE_recipient_id_1]))",
|
||||||
)
|
)
|
||||||
|
|
||||||
def _do_add_term_test(
|
def _do_add_term_test(
|
||||||
self, term: Dict[str, Any], where_clause: str, params: Optional[Dict[str, Any]] = None
|
self, term: NarrowParameter, where_clause: str, params: Optional[Dict[str, Any]] = None
|
||||||
) -> None:
|
) -> None:
|
||||||
query = self._build_query(term)
|
query = self._build_query(term)
|
||||||
if params is not None:
|
if params is not None:
|
||||||
@@ -718,7 +721,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
|||||||
self.assertEqual(actual_params, params)
|
self.assertEqual(actual_params, params)
|
||||||
self.assertIn(where_clause, get_sqlalchemy_sql(query))
|
self.assertIn(where_clause, get_sqlalchemy_sql(query))
|
||||||
|
|
||||||
def _build_query(self, term: Dict[str, Any]) -> Select:
|
def _build_query(self, term: NarrowParameter) -> Select:
|
||||||
return self.builder.add_term(self.raw_query, term)
|
return self.builder.add_term(self.raw_query, term)
|
||||||
|
|
||||||
|
|
||||||
@@ -977,62 +980,86 @@ class NarrowLibraryTest(ZulipTestCase):
|
|||||||
|
|
||||||
def test_is_spectator_compatible(self) -> None:
|
def test_is_spectator_compatible(self) -> None:
|
||||||
self.assertTrue(is_spectator_compatible([]))
|
self.assertTrue(is_spectator_compatible([]))
|
||||||
self.assertTrue(is_spectator_compatible([{"operator": "has", "operand": "attachment"}]))
|
|
||||||
self.assertTrue(is_spectator_compatible([{"operator": "has", "operand": "image"}]))
|
|
||||||
self.assertTrue(is_spectator_compatible([{"operator": "search", "operand": "magic"}]))
|
|
||||||
self.assertTrue(is_spectator_compatible([{"operator": "near", "operand": "15"}]))
|
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
is_spectator_compatible(
|
is_spectator_compatible([NarrowParameter(operator="has", operand="attachment")])
|
||||||
[{"operator": "id", "operand": "15"}, {"operator": "has", "operand": "attachment"}]
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
self.assertTrue(is_spectator_compatible([NarrowParameter(operator="has", operand="image")]))
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
is_spectator_compatible([{"operator": "sender", "operand": "hamlet@zulip.com"}])
|
is_spectator_compatible([NarrowParameter(operator="search", operand="magic")])
|
||||||
)
|
)
|
||||||
self.assertFalse(
|
self.assertTrue(is_spectator_compatible([NarrowParameter(operator="near", operand="15")]))
|
||||||
is_spectator_compatible([{"operator": "dm", "operand": "hamlet@zulip.com"}])
|
|
||||||
)
|
|
||||||
self.assertFalse(
|
|
||||||
is_spectator_compatible([{"operator": "dm-including", "operand": "hamlet@zulip.com"}])
|
|
||||||
)
|
|
||||||
self.assertTrue(is_spectator_compatible([{"operator": "channel", "operand": "Denmark"}]))
|
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
is_spectator_compatible(
|
is_spectator_compatible(
|
||||||
[
|
[
|
||||||
{"operator": "channel", "operand": "Denmark"},
|
NarrowParameter(operator="id", operand="15"),
|
||||||
{"operator": "topic", "operand": "logic"},
|
NarrowParameter(operator="has", operand="attachment"),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.assertFalse(is_spectator_compatible([{"operator": "is", "operand": "starred"}]))
|
self.assertTrue(
|
||||||
self.assertFalse(is_spectator_compatible([{"operator": "is", "operand": "dm"}]))
|
is_spectator_compatible(
|
||||||
self.assertTrue(is_spectator_compatible([{"operator": "channels", "operand": "public"}]))
|
[NarrowParameter(operator="sender", operand="hamlet@zulip.com")]
|
||||||
|
|
||||||
# Malformed input not allowed
|
|
||||||
self.assertFalse(is_spectator_compatible([{"operator": "has"}]))
|
|
||||||
|
|
||||||
# "is:private" is a legacy alias for "is:dm".
|
|
||||||
self.assertFalse(is_spectator_compatible([{"operator": "is", "operand": "private"}]))
|
|
||||||
# "pm-with:"" is a legacy alias for "dm:"
|
|
||||||
self.assertFalse(
|
|
||||||
is_spectator_compatible([{"operator": "pm-with", "operand": "hamlet@zulip.com"}])
|
|
||||||
)
|
)
|
||||||
# "group-pm-with:" was deprecated by the addition of "dm-including:"
|
|
||||||
self.assertFalse(
|
|
||||||
is_spectator_compatible([{"operator": "group-pm-with", "operand": "hamlet@zulip.com"}])
|
|
||||||
)
|
)
|
||||||
# "stream" is a legacy alias for "channel" operator
|
self.assertFalse(
|
||||||
self.assertTrue(is_spectator_compatible([{"operator": "stream", "operand": "Denmark"}]))
|
is_spectator_compatible([NarrowParameter(operator="dm", operand="hamlet@zulip.com")])
|
||||||
|
)
|
||||||
|
self.assertFalse(
|
||||||
|
is_spectator_compatible(
|
||||||
|
[NarrowParameter(operator="dm-including", operand="hamlet@zulip.com")]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
is_spectator_compatible([NarrowParameter(operator="channel", operand="Denmark")])
|
||||||
|
)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
is_spectator_compatible(
|
is_spectator_compatible(
|
||||||
[
|
[
|
||||||
{"operator": "stream", "operand": "Denmark"},
|
NarrowParameter(operator="channel", operand="Denmark"),
|
||||||
{"operator": "topic", "operand": "logic"},
|
NarrowParameter(operator="topic", operand="logic"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertFalse(
|
||||||
|
is_spectator_compatible([NarrowParameter(operator="is", operand="starred")])
|
||||||
|
)
|
||||||
|
self.assertFalse(is_spectator_compatible([NarrowParameter(operator="is", operand="dm")]))
|
||||||
|
self.assertTrue(
|
||||||
|
is_spectator_compatible([NarrowParameter(operator="channels", operand="public")])
|
||||||
|
)
|
||||||
|
|
||||||
|
# "is:private" is a legacy alias for "is:dm".
|
||||||
|
self.assertFalse(
|
||||||
|
is_spectator_compatible([NarrowParameter(operator="is", operand="private")])
|
||||||
|
)
|
||||||
|
# "pm-with:"" is a legacy alias for "dm:"
|
||||||
|
self.assertFalse(
|
||||||
|
is_spectator_compatible(
|
||||||
|
[NarrowParameter(operator="pm-with", operand="hamlet@zulip.com")]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# "group-pm-with:" was deprecated by the addition of "dm-including:"
|
||||||
|
self.assertFalse(
|
||||||
|
is_spectator_compatible(
|
||||||
|
[NarrowParameter(operator="group-pm-with", operand="hamlet@zulip.com")]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# "stream" is a legacy alias for "channel" operator
|
||||||
|
self.assertTrue(
|
||||||
|
is_spectator_compatible([NarrowParameter(operator="stream", operand="Denmark")])
|
||||||
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
is_spectator_compatible(
|
||||||
|
[
|
||||||
|
NarrowParameter(operator="stream", operand="Denmark"),
|
||||||
|
NarrowParameter(operator="topic", operand="logic"),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# "streams" is a legacy alias for "channels" operator
|
# "streams" is a legacy alias for "channels" operator
|
||||||
self.assertTrue(is_spectator_compatible([{"operator": "streams", "operand": "public"}]))
|
self.assertTrue(
|
||||||
|
is_spectator_compatible([NarrowParameter(operator="streams", operand="public")])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class IncludeHistoryTest(ZulipTestCase):
|
class IncludeHistoryTest(ZulipTestCase):
|
||||||
@@ -1042,19 +1069,19 @@ class IncludeHistoryTest(ZulipTestCase):
|
|||||||
|
|
||||||
# Negated channel searches should not include history.
|
# Negated channel searches should not include history.
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="public_channel", negated=True),
|
NarrowParameter(operator="channel", operand="public_channel", negated=True),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
|
|
||||||
# channels:public searches should include history for non-guest members.
|
# channels:public searches should include history for non-guest members.
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channels", operand="public"),
|
NarrowParameter(operator="channels", operand="public"),
|
||||||
]
|
]
|
||||||
self.assertTrue(ok_to_include_history(narrow, user_profile, False))
|
self.assertTrue(ok_to_include_history(narrow, user_profile, False))
|
||||||
|
|
||||||
# Negated -channels:public searches should not include history.
|
# Negated -channels:public searches should not include history.
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channels", operand="public", negated=True),
|
NarrowParameter(operator="channels", operand="public", negated=True),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
|
|
||||||
@@ -1063,7 +1090,7 @@ class IncludeHistoryTest(ZulipTestCase):
|
|||||||
subscribed_user_profile = self.example_user("cordelia")
|
subscribed_user_profile = self.example_user("cordelia")
|
||||||
self.subscribe(subscribed_user_profile, "private_channel")
|
self.subscribe(subscribed_user_profile, "private_channel")
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="private_channel"),
|
NarrowParameter(operator="channel", operand="private_channel"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
|
|
||||||
@@ -1078,69 +1105,69 @@ class IncludeHistoryTest(ZulipTestCase):
|
|||||||
subscribed_user_profile = self.example_user("cordelia")
|
subscribed_user_profile = self.example_user("cordelia")
|
||||||
self.subscribe(subscribed_user_profile, "private_channel_2")
|
self.subscribe(subscribed_user_profile, "private_channel_2")
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="private_channel_2"),
|
NarrowParameter(operator="channel", operand="private_channel_2"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
self.assertTrue(ok_to_include_history(narrow, subscribed_user_profile, False))
|
self.assertTrue(ok_to_include_history(narrow, subscribed_user_profile, False))
|
||||||
|
|
||||||
# History doesn't apply to direct messages.
|
# History doesn't apply to direct messages.
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="is", operand="dm"),
|
NarrowParameter(operator="is", operand="dm"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
# "is:private" is a legacy alias for "is:dm".
|
# "is:private" is a legacy alias for "is:dm".
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="is", operand="private"),
|
NarrowParameter(operator="is", operand="private"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
|
|
||||||
# History doesn't apply to unread messages.
|
# History doesn't apply to unread messages.
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="is", operand="unread"),
|
NarrowParameter(operator="is", operand="unread"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
|
|
||||||
# If we are looking for something like starred messages, there is
|
# If we are looking for something like starred messages, there is
|
||||||
# no point in searching historical messages.
|
# no point in searching historical messages.
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="public_channel"),
|
NarrowParameter(operator="channel", operand="public_channel"),
|
||||||
dict(operator="is", operand="starred"),
|
NarrowParameter(operator="is", operand="starred"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
|
|
||||||
# No point in searching history for is operator even if included with
|
# No point in searching history for is operator even if included with
|
||||||
# channels:public
|
# channels:public
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channels", operand="public"),
|
NarrowParameter(operator="channels", operand="public"),
|
||||||
dict(operator="is", operand="mentioned"),
|
NarrowParameter(operator="is", operand="mentioned"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channels", operand="public"),
|
NarrowParameter(operator="channels", operand="public"),
|
||||||
dict(operator="is", operand="unread"),
|
NarrowParameter(operator="is", operand="unread"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channels", operand="public"),
|
NarrowParameter(operator="channels", operand="public"),
|
||||||
dict(operator="is", operand="alerted"),
|
NarrowParameter(operator="is", operand="alerted"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, user_profile, False))
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channels", operand="public"),
|
NarrowParameter(operator="channels", operand="public"),
|
||||||
dict(operator="is", operand="resolved"),
|
NarrowParameter(operator="is", operand="resolved"),
|
||||||
]
|
]
|
||||||
self.assertTrue(ok_to_include_history(narrow, user_profile, False))
|
self.assertTrue(ok_to_include_history(narrow, user_profile, False))
|
||||||
|
|
||||||
# simple True case
|
# simple True case
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="public_channel"),
|
NarrowParameter(operator="channel", operand="public_channel"),
|
||||||
]
|
]
|
||||||
self.assertTrue(ok_to_include_history(narrow, user_profile, False))
|
self.assertTrue(ok_to_include_history(narrow, user_profile, False))
|
||||||
|
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="public_channel"),
|
NarrowParameter(operator="channel", operand="public_channel"),
|
||||||
dict(operator="topic", operand="whatever"),
|
NarrowParameter(operator="topic", operand="whatever"),
|
||||||
dict(operator="search", operand="needle in haystack"),
|
NarrowParameter(operator="search", operand="needle in haystack"),
|
||||||
]
|
]
|
||||||
self.assertTrue(ok_to_include_history(narrow, user_profile, False))
|
self.assertTrue(ok_to_include_history(narrow, user_profile, False))
|
||||||
|
|
||||||
@@ -1151,14 +1178,14 @@ class IncludeHistoryTest(ZulipTestCase):
|
|||||||
|
|
||||||
# channels:public searches should not include history for guest members.
|
# channels:public searches should not include history for guest members.
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channels", operand="public"),
|
NarrowParameter(operator="channels", operand="public"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, guest_user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, guest_user_profile, False))
|
||||||
|
|
||||||
# Guest user can't access public channel
|
# Guest user can't access public channel
|
||||||
self.subscribe(subscribed_user_profile, "public_channel_2")
|
self.subscribe(subscribed_user_profile, "public_channel_2")
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="public_channel_2"),
|
NarrowParameter(operator="channel", operand="public_channel_2"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, guest_user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, guest_user_profile, False))
|
||||||
self.assertTrue(ok_to_include_history(narrow, subscribed_user_profile, False))
|
self.assertTrue(ok_to_include_history(narrow, subscribed_user_profile, False))
|
||||||
@@ -1166,7 +1193,7 @@ class IncludeHistoryTest(ZulipTestCase):
|
|||||||
# Definitely, a guest user can't access the unsubscribed private channel
|
# Definitely, a guest user can't access the unsubscribed private channel
|
||||||
self.subscribe(subscribed_user_profile, "private_channel_3")
|
self.subscribe(subscribed_user_profile, "private_channel_3")
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="private_channel_3"),
|
NarrowParameter(operator="channel", operand="private_channel_3"),
|
||||||
]
|
]
|
||||||
self.assertFalse(ok_to_include_history(narrow, guest_user_profile, False))
|
self.assertFalse(ok_to_include_history(narrow, guest_user_profile, False))
|
||||||
self.assertTrue(ok_to_include_history(narrow, subscribed_user_profile, False))
|
self.assertTrue(ok_to_include_history(narrow, subscribed_user_profile, False))
|
||||||
@@ -1175,7 +1202,7 @@ class IncludeHistoryTest(ZulipTestCase):
|
|||||||
self.subscribe(guest_user_profile, "private_channel_4")
|
self.subscribe(guest_user_profile, "private_channel_4")
|
||||||
self.subscribe(subscribed_user_profile, "private_channel_4")
|
self.subscribe(subscribed_user_profile, "private_channel_4")
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="private_channel_4"),
|
NarrowParameter(operator="channel", operand="private_channel_4"),
|
||||||
]
|
]
|
||||||
self.assertTrue(ok_to_include_history(narrow, guest_user_profile, False))
|
self.assertTrue(ok_to_include_history(narrow, guest_user_profile, False))
|
||||||
self.assertTrue(ok_to_include_history(narrow, subscribed_user_profile, False))
|
self.assertTrue(ok_to_include_history(narrow, subscribed_user_profile, False))
|
||||||
@@ -4123,8 +4150,8 @@ class GetOldMessagesTest(ZulipTestCase):
|
|||||||
|
|
||||||
# If nothing relevant is muted, then exclude_muting_conditions()
|
# If nothing relevant is muted, then exclude_muting_conditions()
|
||||||
# should return an empty list.
|
# should return an empty list.
|
||||||
narrow: List[Dict[str, object]] = [
|
narrow: List[NarrowParameter] = [
|
||||||
dict(operator="channel", operand="Scotland"),
|
NarrowParameter(operator="channel", operand="Scotland"),
|
||||||
]
|
]
|
||||||
muting_conditions = exclude_muting_conditions(user_profile, narrow)
|
muting_conditions = exclude_muting_conditions(user_profile, narrow)
|
||||||
self.assertEqual(muting_conditions, [])
|
self.assertEqual(muting_conditions, [])
|
||||||
@@ -4132,7 +4159,7 @@ class GetOldMessagesTest(ZulipTestCase):
|
|||||||
# Also test that passing channel ID works
|
# Also test that passing channel ID works
|
||||||
channel_id = get_stream("Scotland", realm).id
|
channel_id = get_stream("Scotland", realm).id
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand=channel_id),
|
NarrowParameter(operator="channel", operand=channel_id),
|
||||||
]
|
]
|
||||||
muting_conditions = exclude_muting_conditions(user_profile, narrow)
|
muting_conditions = exclude_muting_conditions(user_profile, narrow)
|
||||||
self.assertEqual(muting_conditions, [])
|
self.assertEqual(muting_conditions, [])
|
||||||
@@ -4146,7 +4173,7 @@ class GetOldMessagesTest(ZulipTestCase):
|
|||||||
|
|
||||||
# And verify that our query will exclude them.
|
# And verify that our query will exclude them.
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="Scotland"),
|
NarrowParameter(operator="channel", operand="Scotland"),
|
||||||
]
|
]
|
||||||
|
|
||||||
muting_conditions = exclude_muting_conditions(user_profile, narrow)
|
muting_conditions = exclude_muting_conditions(user_profile, narrow)
|
||||||
@@ -4173,7 +4200,7 @@ WHERE NOT (recipient_id = %(recipient_id_1)s AND upper(subject) = upper(%(param_
|
|||||||
# Using a bogus channel name should be similar to using no narrow at
|
# Using a bogus channel name should be similar to using no narrow at
|
||||||
# all, and we'll exclude all mutes.
|
# all, and we'll exclude all mutes.
|
||||||
narrow = [
|
narrow = [
|
||||||
dict(operator="channel", operand="bogus-channel-name"),
|
NarrowParameter(operator="channel", operand="bogus-channel-name"),
|
||||||
]
|
]
|
||||||
|
|
||||||
muting_conditions = exclude_muting_conditions(user_profile, narrow)
|
muting_conditions = exclude_muting_conditions(user_profile, narrow)
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ from zerver.lib.exceptions import JsonableError, MissingAuthenticationError
|
|||||||
from zerver.lib.message import get_first_visible_message_id, messages_for_ids
|
from zerver.lib.message import get_first_visible_message_id, messages_for_ids
|
||||||
from zerver.lib.narrow import (
|
from zerver.lib.narrow import (
|
||||||
NarrowParameter,
|
NarrowParameter,
|
||||||
OptionalNarrowListT,
|
|
||||||
add_narrow_conditions,
|
add_narrow_conditions,
|
||||||
fetch_messages,
|
fetch_messages,
|
||||||
is_spectator_compatible,
|
is_spectator_compatible,
|
||||||
@@ -83,7 +82,9 @@ def get_search_fields(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def clean_narrow_for_web_public_api(narrow: OptionalNarrowListT) -> OptionalNarrowListT:
|
def clean_narrow_for_web_public_api(
|
||||||
|
narrow: Optional[List[NarrowParameter]],
|
||||||
|
) -> Optional[List[NarrowParameter]]:
|
||||||
if narrow is None:
|
if narrow is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ def clean_narrow_for_web_public_api(narrow: OptionalNarrowListT) -> OptionalNarr
|
|||||||
return [
|
return [
|
||||||
term
|
term
|
||||||
for term in narrow
|
for term in narrow
|
||||||
if not (term["operator"] == "in" and term["operand"] == "home" and not term["negated"])
|
if not (term.operator == "in" and term.operand == "home" and not term.negated)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -123,11 +124,6 @@ def get_messages_backend(
|
|||||||
if num_before > 0 and num_after > 0 and not include_anchor:
|
if num_before > 0 and num_after > 0 and not include_anchor:
|
||||||
raise JsonableError(_("The anchor can only be excluded at an end of the range"))
|
raise JsonableError(_("The anchor can only be excluded at an end of the range"))
|
||||||
|
|
||||||
if narrow is not None and len(narrow) > 0:
|
|
||||||
narrow_parameter_list: OptionalNarrowListT = [x.model_dump() for x in narrow]
|
|
||||||
else:
|
|
||||||
narrow_parameter_list = None
|
|
||||||
|
|
||||||
realm = get_valid_realm_from_request(request)
|
realm = get_valid_realm_from_request(request)
|
||||||
if not maybe_user_profile.is_authenticated:
|
if not maybe_user_profile.is_authenticated:
|
||||||
# If user is not authenticated, clients must include
|
# If user is not authenticated, clients must include
|
||||||
@@ -142,11 +138,11 @@ def get_messages_backend(
|
|||||||
# non-web-public stream messages) via this path.
|
# non-web-public stream messages) via this path.
|
||||||
if not realm.allow_web_public_streams_access():
|
if not realm.allow_web_public_streams_access():
|
||||||
raise MissingAuthenticationError
|
raise MissingAuthenticationError
|
||||||
narrow_parameter_list = clean_narrow_for_web_public_api(narrow_parameter_list)
|
narrow = clean_narrow_for_web_public_api(narrow)
|
||||||
if not is_web_public_narrow(narrow_parameter_list):
|
if not is_web_public_narrow(narrow):
|
||||||
raise MissingAuthenticationError
|
raise MissingAuthenticationError
|
||||||
assert narrow_parameter_list is not None
|
assert narrow is not None
|
||||||
if not is_spectator_compatible(narrow_parameter_list):
|
if not is_spectator_compatible(narrow):
|
||||||
raise MissingAuthenticationError
|
raise MissingAuthenticationError
|
||||||
|
|
||||||
# We use None to indicate unauthenticated requests as it's more
|
# We use None to indicate unauthenticated requests as it's more
|
||||||
@@ -168,14 +164,14 @@ def get_messages_backend(
|
|||||||
# email_address_visibility setting.
|
# email_address_visibility setting.
|
||||||
client_gravatar = False
|
client_gravatar = False
|
||||||
|
|
||||||
if narrow_parameter_list is not None:
|
if narrow is not None:
|
||||||
# Add some metadata to our logging data for narrows
|
# Add some metadata to our logging data for narrows
|
||||||
verbose_operators = []
|
verbose_operators = []
|
||||||
for term in narrow_parameter_list:
|
for term in narrow:
|
||||||
if term["operator"] == "is":
|
if term.operator == "is":
|
||||||
verbose_operators.append("is:" + term["operand"])
|
verbose_operators.append("is:" + term.operand)
|
||||||
else:
|
else:
|
||||||
verbose_operators.append(term["operator"])
|
verbose_operators.append(term.operator)
|
||||||
log_data = RequestNotes.get_notes(request).log_data
|
log_data = RequestNotes.get_notes(request).log_data
|
||||||
assert log_data is not None
|
assert log_data is not None
|
||||||
log_data["extra"] = "[{}]".format(",".join(verbose_operators))
|
log_data["extra"] = "[{}]".format(",".join(verbose_operators))
|
||||||
@@ -206,7 +202,7 @@ def get_messages_backend(
|
|||||||
cursor.execute("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY")
|
cursor.execute("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY")
|
||||||
|
|
||||||
query_info = fetch_messages(
|
query_info = fetch_messages(
|
||||||
narrow=narrow_parameter_list,
|
narrow=narrow,
|
||||||
user_profile=user_profile,
|
user_profile=user_profile,
|
||||||
realm=realm,
|
realm=realm,
|
||||||
is_web_public_query=is_web_public_query,
|
is_web_public_query=is_web_public_query,
|
||||||
@@ -297,8 +293,6 @@ def messages_in_narrow_backend(
|
|||||||
msg_ids: Json[List[int]],
|
msg_ids: Json[List[int]],
|
||||||
narrow: Json[List[NarrowParameter]],
|
narrow: Json[List[NarrowParameter]],
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
narrow_parameter_list: OptionalNarrowListT = [x.model_dump() for x in narrow]
|
|
||||||
|
|
||||||
first_visible_message_id = get_first_visible_message_id(user_profile.realm)
|
first_visible_message_id = get_first_visible_message_id(user_profile.realm)
|
||||||
msg_ids = [message_id for message_id in msg_ids if message_id >= first_visible_message_id]
|
msg_ids = [message_id for message_id in msg_ids if message_id >= first_visible_message_id]
|
||||||
# This query is limited to messages the user has access to because they
|
# This query is limited to messages the user has access to because they
|
||||||
@@ -326,7 +320,7 @@ def messages_in_narrow_backend(
|
|||||||
user_profile=user_profile,
|
user_profile=user_profile,
|
||||||
inner_msg_id_col=inner_msg_id_col,
|
inner_msg_id_col=inner_msg_id_col,
|
||||||
query=query,
|
query=query,
|
||||||
narrow=narrow_parameter_list,
|
narrow=narrow,
|
||||||
is_web_public_query=False,
|
is_web_public_query=False,
|
||||||
realm=user_profile.realm,
|
realm=user_profile.realm,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -92,13 +92,8 @@ def update_message_flags_for_narrow(
|
|||||||
)
|
)
|
||||||
num_after = min(num_after, MAX_MESSAGES_PER_UPDATE - num_before)
|
num_after = min(num_after, MAX_MESSAGES_PER_UPDATE - num_before)
|
||||||
|
|
||||||
if narrow is not None and len(narrow) > 0:
|
|
||||||
narrow_dict = [x.model_dump() for x in narrow]
|
|
||||||
else:
|
|
||||||
narrow_dict = None
|
|
||||||
|
|
||||||
query_info = fetch_messages(
|
query_info = fetch_messages(
|
||||||
narrow=narrow_dict,
|
narrow=narrow,
|
||||||
user_profile=user_profile,
|
user_profile=user_profile,
|
||||||
realm=user_profile.realm,
|
realm=user_profile.realm,
|
||||||
is_web_public_query=False,
|
is_web_public_query=False,
|
||||||
|
|||||||
Reference in New Issue
Block a user