mirror of
https://github.com/zulip/zulip.git
synced 2025-11-13 02:17:19 +00:00
* Have the `get_active_presence_idle_user_ids` function look at all the user data, not just `private_message` and `mentioned`. * Fix a couple of incorrect `missedmessage_hook` tests, which did not catch the earlier behaviour. * Add some comments to the tests for this function for clarity. * Add a helper to create `UserMessageNotificationsData` objects from the user ID lists. This will later help us deduplicate code in the event_queue logic. This fixes a bug which earlier existed, that if a user turned on stream notifications, and received a message in that stream which did not mention them, they wouldn't be in the `presence_idle_users` list, and hence would never get notifications for that message. Note that, after this commit, users might still not get notifications in the above scenarios in some cases, because the downstream logic in the notification queue consumers sometimes erroneously skips sending notifications for stream messages.
109 lines
4.4 KiB
Python
109 lines
4.4 KiB
Python
import datetime
|
|
from typing import List
|
|
|
|
from django.utils.timezone import now as timezone_now
|
|
|
|
from zerver.lib.actions import get_active_presence_idle_user_ids, get_client
|
|
from zerver.lib.test_classes import ZulipTestCase
|
|
from zerver.models import (
|
|
Message,
|
|
UserPresence,
|
|
UserProfile,
|
|
bulk_get_huddle_user_ids,
|
|
get_huddle_user_ids,
|
|
)
|
|
|
|
|
|
class MissedMessageTest(ZulipTestCase):
|
|
def test_presence_idle_user_ids(self) -> None:
|
|
UserPresence.objects.all().delete()
|
|
|
|
sender = self.example_user("cordelia")
|
|
realm = sender.realm
|
|
hamlet = self.example_user("hamlet")
|
|
othello = self.example_user("othello")
|
|
user_data_objects = [
|
|
self.create_user_notifications_data_object(id=hamlet.id),
|
|
self.create_user_notifications_data_object(id=othello.id),
|
|
]
|
|
message_type = "private"
|
|
|
|
def assert_missing(user_ids: List[int]) -> None:
|
|
presence_idle_user_ids = get_active_presence_idle_user_ids(
|
|
realm=realm,
|
|
sender_id=sender.id,
|
|
message_type=message_type,
|
|
active_users_data=user_data_objects,
|
|
)
|
|
self.assertEqual(sorted(user_ids), sorted(presence_idle_user_ids))
|
|
|
|
def set_presence(user: UserProfile, client_name: str, ago: int) -> None:
|
|
when = timezone_now() - datetime.timedelta(seconds=ago)
|
|
UserPresence.objects.create(
|
|
user_profile_id=user.id,
|
|
realm_id=user.realm_id,
|
|
client=get_client(client_name),
|
|
timestamp=when,
|
|
)
|
|
|
|
message_type = "private"
|
|
assert_missing([hamlet.id, othello.id])
|
|
|
|
# We have already thoroughly tested the `is_notifiable` function elsewhere,
|
|
# so we needn't test all cases here. This test exists mainly to avoid a bug
|
|
# which existed earlier with `get_active_presence_idle_user_ids` only looking
|
|
# at `private_message` and the `mentioned` flag, not stream level notifications.
|
|
# Simulate Hamlet has turned on notifications for the stream, and test that he's
|
|
# in the list.
|
|
message_type = "stream"
|
|
user_data_objects[0].stream_email_notify = True
|
|
assert_missing([hamlet.id])
|
|
|
|
# We don't currently send push or email notifications for alert words -- only
|
|
# desktop notifications, so `is_notifiable` will return False even if the flags contain
|
|
# alert words. Test that `get_active_presence_idle_user_ids` correctly includes even
|
|
# the alert word case in the list.
|
|
user_data_objects[0].stream_email_notify = False
|
|
user_data_objects[0].flags = ["has_alert_word"]
|
|
assert_missing([hamlet.id])
|
|
|
|
# Hamlet is idle (and the message has an alert word), so he should be in the list.
|
|
set_presence(hamlet, "iPhone", ago=5000)
|
|
assert_missing([hamlet.id])
|
|
|
|
# If Hamlet is active, don't include him in the `presence_idle` list.
|
|
set_presence(hamlet, "website", ago=15)
|
|
assert_missing([])
|
|
|
|
# Hamlet is active now, so only Othello should be in the list for a huddle
|
|
# message.
|
|
message_type = "private"
|
|
assert_missing([othello.id])
|
|
|
|
|
|
class TestBulkGetHuddleUserIds(ZulipTestCase):
|
|
def test_bulk_get_huddle_user_ids(self) -> None:
|
|
hamlet = self.example_user("hamlet")
|
|
cordelia = self.example_user("cordelia")
|
|
othello = self.example_user("othello")
|
|
iago = self.example_user("iago")
|
|
message_ids = [
|
|
self.send_huddle_message(hamlet, [cordelia, othello], "test"),
|
|
self.send_huddle_message(cordelia, [hamlet, othello, iago], "test"),
|
|
]
|
|
|
|
messages = Message.objects.filter(id__in=message_ids).order_by("id")
|
|
first_huddle_recipient = messages[0].recipient
|
|
first_huddle_user_ids = list(get_huddle_user_ids(first_huddle_recipient))
|
|
second_huddle_recipient = messages[1].recipient
|
|
second_huddle_user_ids = list(get_huddle_user_ids(second_huddle_recipient))
|
|
|
|
huddle_user_ids = bulk_get_huddle_user_ids(
|
|
[first_huddle_recipient, second_huddle_recipient]
|
|
)
|
|
self.assertEqual(huddle_user_ids[first_huddle_recipient.id], first_huddle_user_ids)
|
|
self.assertEqual(huddle_user_ids[second_huddle_recipient.id], second_huddle_user_ids)
|
|
|
|
def test_bulk_get_huddle_user_ids_empty_list(self) -> None:
|
|
self.assertEqual(bulk_get_huddle_user_ids([]), {})
|