narrow_filter: Pass message/flags to narrow_filter.

We no longer pass in a big opaque event to narrow_filter
(which is inside build_narrow_filter). We instead explicitly
pass in message and flags. This leads to a bit more type
safety, and it's also more flexible. There's no reason to
build an entire event just to see if a message belongs to
a narrow.

The changes to the test work around the fact that the fixtures
are sloppy with types. I plan a subsequent commit to clean
up those tests significantly.
This commit is contained in:
Steve Howell 2023-06-28 16:19:45 +00:00 committed by Tim Abbott
parent 0c55fb7e89
commit 8ea0c5bbad
3 changed files with 20 additions and 8 deletions

View File

@ -9,7 +9,6 @@ from typing import (
Generic,
Iterable,
List,
Mapping,
Optional,
Sequence,
Set,
@ -23,6 +22,7 @@ from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import connection
from django.utils.translation import gettext as _
from mypy_extensions import NamedArg
from sqlalchemy.dialects import postgresql
from sqlalchemy.engine import Connection, Row
from sqlalchemy.sql import (
@ -132,14 +132,14 @@ def is_web_public_narrow(narrow: Optional[Iterable[Dict[str, Any]]]) -> bool:
)
def build_narrow_filter(narrow: Collection[Sequence[str]]) -> Callable[[Mapping[str, Any]], bool]:
def build_narrow_filter(
narrow: Collection[Sequence[str]],
) -> Callable[[NamedArg(Dict[str, Any], "message"), NamedArg(List[str], "flags")], bool]:
"""Changes to this function should come with corresponding changes to
NarrowLibraryTest."""
check_supported_events_narrow_filter(narrow)
def narrow_filter(event: Mapping[str, Any]) -> bool:
message = event["message"]
flags = event["flags"]
def narrow_filter(*, message: Dict[str, Any], flags: List[str]) -> bool:
for element in narrow:
operator = element[0]
operand = element[1]

View File

@ -603,9 +603,21 @@ class NarrowLibraryTest(ZulipTestCase):
reject_events = scenario["reject_events"]
narrow_filter = build_narrow_filter(narrow)
for e in accept_events:
self.assertTrue(narrow_filter(e))
message = e["message"]
flags = e["flags"]
if message is None:
message = {}
if flags is None:
flags = []
self.assertTrue(narrow_filter(message=message, flags=flags))
for e in reject_events:
self.assertFalse(narrow_filter(e))
message = e["message"]
flags = e["flags"]
if message is None:
message = {}
if flags is None:
flags = []
self.assertFalse(narrow_filter(message=message, flags=flags))
def test_build_narrow_filter_invalid(self) -> None:
with self.assertRaises(JsonableError):

View File

@ -226,7 +226,7 @@ class ClientDescriptor:
# older servers that don't support user_topic.
return False
if event["type"] == "message":
return self.narrow_filter(event)
return self.narrow_filter(message=event["message"], flags=event["flags"])
if event["type"] == "typing" and "stream_id" in event:
# Typing notifications for stream messages are only
# delivered if the stream_typing_notifications