mirror of
https://github.com/zulip/zulip.git
synced 2026-07-15 21:03:26 +08:00
tests: Move GetUnreadMsgsTest.
The tests in this suite are 90% about handling unread messages, and the only event-related logic is apply_unread_message_event.
This commit is contained in:
parent
5da71048e6
commit
4c28786d2d
@ -93,14 +93,7 @@ from zerver.lib.actions import (
|
||||
)
|
||||
from zerver.lib.events import apply_events, fetch_initial_state_data, post_process_state
|
||||
from zerver.lib.markdown import MentionData
|
||||
from zerver.lib.message import (
|
||||
MessageDict,
|
||||
UnreadMessagesResult,
|
||||
aggregate_unread_data,
|
||||
apply_unread_message_event,
|
||||
get_raw_unread_data,
|
||||
render_markdown,
|
||||
)
|
||||
from zerver.lib.message import render_markdown
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.lib.test_helpers import (
|
||||
create_dummy_file,
|
||||
@ -111,7 +104,6 @@ from zerver.lib.test_helpers import (
|
||||
)
|
||||
from zerver.lib.test_runner import slow
|
||||
from zerver.lib.topic import ORIG_TOPIC, TOPIC_LINKS, TOPIC_NAME
|
||||
from zerver.lib.topic_mutes import add_topic_mute
|
||||
from zerver.lib.validator import (
|
||||
Validator,
|
||||
check_bool,
|
||||
@ -134,10 +126,8 @@ from zerver.models import (
|
||||
Realm,
|
||||
RealmAuditLog,
|
||||
RealmDomain,
|
||||
Recipient,
|
||||
Service,
|
||||
Stream,
|
||||
Subscription,
|
||||
UserGroup,
|
||||
UserMessage,
|
||||
UserPresence,
|
||||
@ -2620,419 +2610,3 @@ class EventsRegisterTest(ZulipTestCase):
|
||||
])
|
||||
events = self.do_test(lambda: do_set_zoom_token(self.user_profile, None))
|
||||
schema_checker('events[0]', events[0])
|
||||
|
||||
class GetUnreadMsgsTest(ZulipTestCase):
|
||||
def mute_stream(self, user_profile: UserProfile, stream: Stream) -> None:
|
||||
recipient = Recipient.objects.get(type_id=stream.id, type=Recipient.STREAM)
|
||||
subscription = Subscription.objects.get(
|
||||
user_profile=user_profile,
|
||||
recipient=recipient,
|
||||
)
|
||||
subscription.is_muted = True
|
||||
subscription.save()
|
||||
|
||||
def mute_topic(self, user_profile: UserProfile, stream_name: str,
|
||||
topic_name: str) -> None:
|
||||
realm = user_profile.realm
|
||||
stream = get_stream(stream_name, realm)
|
||||
recipient = stream.recipient
|
||||
|
||||
add_topic_mute(
|
||||
user_profile=user_profile,
|
||||
stream_id=stream.id,
|
||||
recipient_id=recipient.id,
|
||||
topic_name=topic_name,
|
||||
)
|
||||
|
||||
def test_raw_unread_stream(self) -> None:
|
||||
cordelia = self.example_user('cordelia')
|
||||
hamlet = self.example_user('hamlet')
|
||||
realm = hamlet.realm
|
||||
|
||||
for stream_name in ['social', 'devel', 'test here']:
|
||||
self.subscribe(hamlet, stream_name)
|
||||
self.subscribe(cordelia, stream_name)
|
||||
|
||||
all_message_ids: Set[int] = set()
|
||||
message_ids = dict()
|
||||
|
||||
tups = [
|
||||
('social', 'lunch'),
|
||||
('test here', 'bla'),
|
||||
('devel', 'python'),
|
||||
('devel', 'ruby'),
|
||||
]
|
||||
|
||||
for stream_name, topic_name in tups:
|
||||
message_ids[topic_name] = [
|
||||
self.send_stream_message(
|
||||
sender=cordelia,
|
||||
stream_name=stream_name,
|
||||
topic_name=topic_name,
|
||||
) for i in range(3)
|
||||
]
|
||||
all_message_ids |= set(message_ids[topic_name])
|
||||
|
||||
self.assertEqual(len(all_message_ids), 12) # sanity check on test setup
|
||||
|
||||
self.mute_stream(
|
||||
user_profile=hamlet,
|
||||
stream=get_stream('test here', realm),
|
||||
)
|
||||
|
||||
self.mute_topic(
|
||||
user_profile=hamlet,
|
||||
stream_name='devel',
|
||||
topic_name='ruby',
|
||||
)
|
||||
|
||||
raw_unread_data = get_raw_unread_data(
|
||||
user_profile=hamlet,
|
||||
)
|
||||
|
||||
stream_dict = raw_unread_data['stream_dict']
|
||||
|
||||
self.assertEqual(
|
||||
set(stream_dict.keys()),
|
||||
all_message_ids,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
raw_unread_data['unmuted_stream_msgs'],
|
||||
set(message_ids['python']) | set(message_ids['lunch']),
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
stream_dict[message_ids['lunch'][0]],
|
||||
dict(
|
||||
sender_id=cordelia.id,
|
||||
stream_id=get_stream('social', realm).id,
|
||||
topic='lunch',
|
||||
),
|
||||
)
|
||||
|
||||
def test_raw_unread_huddle(self) -> None:
|
||||
cordelia = self.example_user('cordelia')
|
||||
othello = self.example_user('othello')
|
||||
hamlet = self.example_user('hamlet')
|
||||
prospero = self.example_user('prospero')
|
||||
|
||||
huddle1_message_ids = [
|
||||
self.send_huddle_message(
|
||||
cordelia,
|
||||
[hamlet, othello],
|
||||
)
|
||||
for i in range(3)
|
||||
]
|
||||
|
||||
huddle2_message_ids = [
|
||||
self.send_huddle_message(
|
||||
cordelia,
|
||||
[hamlet, prospero],
|
||||
)
|
||||
for i in range(3)
|
||||
]
|
||||
|
||||
raw_unread_data = get_raw_unread_data(
|
||||
user_profile=hamlet,
|
||||
)
|
||||
|
||||
huddle_dict = raw_unread_data['huddle_dict']
|
||||
|
||||
self.assertEqual(
|
||||
set(huddle_dict.keys()),
|
||||
set(huddle1_message_ids) | set(huddle2_message_ids),
|
||||
)
|
||||
|
||||
huddle_string = ','.join(
|
||||
str(uid)
|
||||
for uid in sorted([cordelia.id, hamlet.id, othello.id])
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
huddle_dict[huddle1_message_ids[0]],
|
||||
dict(user_ids_string=huddle_string),
|
||||
)
|
||||
|
||||
def test_raw_unread_personal(self) -> None:
|
||||
cordelia = self.example_user('cordelia')
|
||||
othello = self.example_user('othello')
|
||||
hamlet = self.example_user('hamlet')
|
||||
|
||||
cordelia_pm_message_ids = [
|
||||
self.send_personal_message(cordelia, hamlet)
|
||||
for i in range(3)
|
||||
]
|
||||
|
||||
othello_pm_message_ids = [
|
||||
self.send_personal_message(othello, hamlet)
|
||||
for i in range(3)
|
||||
]
|
||||
|
||||
raw_unread_data = get_raw_unread_data(
|
||||
user_profile=hamlet,
|
||||
)
|
||||
|
||||
pm_dict = raw_unread_data['pm_dict']
|
||||
|
||||
self.assertEqual(
|
||||
set(pm_dict.keys()),
|
||||
set(cordelia_pm_message_ids) | set(othello_pm_message_ids),
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
pm_dict[cordelia_pm_message_ids[0]],
|
||||
dict(sender_id=cordelia.id),
|
||||
)
|
||||
|
||||
def test_raw_unread_personal_from_self(self) -> None:
|
||||
hamlet = self.example_user('hamlet')
|
||||
|
||||
def send_unread_pm(other_user: UserProfile) -> Message:
|
||||
# It is rare to send a message from Hamlet to Othello
|
||||
# (or any other user) and have it be unread for
|
||||
# Hamlet himself, but that is actually normal
|
||||
# behavior for most API clients.
|
||||
message_id = self.send_personal_message(
|
||||
from_user=hamlet,
|
||||
to_user=other_user,
|
||||
sending_client_name='some_api_program',
|
||||
)
|
||||
|
||||
# Check our test setup is correct--the message should
|
||||
# not have looked like it was sent by a human.
|
||||
message = Message.objects.get(id=message_id)
|
||||
self.assertFalse(message.sent_by_human())
|
||||
|
||||
# And since it was not sent by a human, it should not
|
||||
# be read, not even by the sender (Hamlet).
|
||||
um = UserMessage.objects.get(
|
||||
user_profile_id=hamlet.id,
|
||||
message_id=message_id,
|
||||
)
|
||||
self.assertFalse(um.flags.read)
|
||||
|
||||
return message
|
||||
|
||||
othello = self.example_user('othello')
|
||||
othello_msg = send_unread_pm(other_user=othello)
|
||||
|
||||
# And now check the unread data structure...
|
||||
raw_unread_data = get_raw_unread_data(
|
||||
user_profile=hamlet,
|
||||
)
|
||||
|
||||
pm_dict = raw_unread_data['pm_dict']
|
||||
|
||||
self.assertEqual(set(pm_dict.keys()), {othello_msg.id})
|
||||
|
||||
# For legacy reason we call the field `sender_id` here,
|
||||
# but it really refers to the other user id in the conversation,
|
||||
# which is Othello.
|
||||
self.assertEqual(
|
||||
pm_dict[othello_msg.id],
|
||||
dict(sender_id=othello.id),
|
||||
)
|
||||
|
||||
cordelia = self.example_user('cordelia')
|
||||
cordelia_msg = send_unread_pm(other_user=cordelia)
|
||||
|
||||
apply_unread_message_event(
|
||||
user_profile=hamlet,
|
||||
state=raw_unread_data,
|
||||
message=MessageDict.wide_dict(cordelia_msg),
|
||||
flags=[],
|
||||
)
|
||||
self.assertEqual(
|
||||
set(pm_dict.keys()),
|
||||
{othello_msg.id, cordelia_msg.id},
|
||||
)
|
||||
|
||||
# Again, `sender_id` is misnamed here.
|
||||
self.assertEqual(
|
||||
pm_dict[cordelia_msg.id],
|
||||
dict(sender_id=cordelia.id),
|
||||
)
|
||||
|
||||
# Send a message to ourself.
|
||||
hamlet_msg = send_unread_pm(other_user=hamlet)
|
||||
apply_unread_message_event(
|
||||
user_profile=hamlet,
|
||||
state=raw_unread_data,
|
||||
message=MessageDict.wide_dict(hamlet_msg),
|
||||
flags=[],
|
||||
)
|
||||
self.assertEqual(
|
||||
set(pm_dict.keys()),
|
||||
{othello_msg.id, cordelia_msg.id, hamlet_msg.id},
|
||||
)
|
||||
|
||||
# Again, `sender_id` is misnamed here.
|
||||
self.assertEqual(
|
||||
pm_dict[hamlet_msg.id],
|
||||
dict(sender_id=hamlet.id),
|
||||
)
|
||||
|
||||
# Call get_raw_unread_data again.
|
||||
raw_unread_data = get_raw_unread_data(
|
||||
user_profile=hamlet,
|
||||
)
|
||||
pm_dict = raw_unread_data['pm_dict']
|
||||
|
||||
self.assertEqual(
|
||||
set(pm_dict.keys()),
|
||||
{othello_msg.id, cordelia_msg.id, hamlet_msg.id},
|
||||
)
|
||||
|
||||
# Again, `sender_id` is misnamed here.
|
||||
self.assertEqual(
|
||||
pm_dict[hamlet_msg.id],
|
||||
dict(sender_id=hamlet.id),
|
||||
)
|
||||
|
||||
def test_unread_msgs(self) -> None:
|
||||
sender = self.example_user('cordelia')
|
||||
sender_id = sender.id
|
||||
user_profile = self.example_user('hamlet')
|
||||
othello = self.example_user('othello')
|
||||
|
||||
pm1_message_id = self.send_personal_message(sender, user_profile, "hello1")
|
||||
pm2_message_id = self.send_personal_message(sender, user_profile, "hello2")
|
||||
|
||||
muted_stream = self.subscribe(user_profile, 'Muted Stream')
|
||||
self.mute_stream(user_profile, muted_stream)
|
||||
self.mute_topic(user_profile, 'Denmark', 'muted-topic')
|
||||
|
||||
stream_message_id = self.send_stream_message(sender, "Denmark", "hello")
|
||||
muted_stream_message_id = self.send_stream_message(sender, "Muted Stream", "hello")
|
||||
muted_topic_message_id = self.send_stream_message(
|
||||
sender,
|
||||
"Denmark",
|
||||
topic_name="muted-topic",
|
||||
content="hello",
|
||||
)
|
||||
|
||||
huddle_message_id = self.send_huddle_message(
|
||||
sender,
|
||||
[user_profile, othello],
|
||||
'hello3',
|
||||
)
|
||||
|
||||
def get_unread_data() -> UnreadMessagesResult:
|
||||
raw_unread_data = get_raw_unread_data(user_profile)
|
||||
aggregated_data = aggregate_unread_data(raw_unread_data)
|
||||
return aggregated_data
|
||||
|
||||
result = get_unread_data()
|
||||
|
||||
# The count here reflects the count of unread messages that we will
|
||||
# report to users in the bankruptcy dialog, and for now it excludes unread messages
|
||||
# from muted treams, but it doesn't exclude unread messages from muted topics yet.
|
||||
self.assertEqual(result['count'], 4)
|
||||
|
||||
unread_pm = result['pms'][0]
|
||||
self.assertEqual(unread_pm['sender_id'], sender_id)
|
||||
self.assertEqual(unread_pm['unread_message_ids'], [pm1_message_id, pm2_message_id])
|
||||
self.assertTrue('sender_ids' not in unread_pm)
|
||||
|
||||
unread_stream = result['streams'][0]
|
||||
self.assertEqual(unread_stream['stream_id'], get_stream('Denmark', user_profile.realm).id)
|
||||
self.assertEqual(unread_stream['topic'], 'muted-topic')
|
||||
self.assertEqual(unread_stream['unread_message_ids'], [muted_topic_message_id])
|
||||
self.assertEqual(unread_stream['sender_ids'], [sender_id])
|
||||
|
||||
unread_stream = result['streams'][1]
|
||||
self.assertEqual(unread_stream['stream_id'], get_stream('Denmark', user_profile.realm).id)
|
||||
self.assertEqual(unread_stream['topic'], 'test')
|
||||
self.assertEqual(unread_stream['unread_message_ids'], [stream_message_id])
|
||||
self.assertEqual(unread_stream['sender_ids'], [sender_id])
|
||||
|
||||
unread_stream = result['streams'][2]
|
||||
self.assertEqual(unread_stream['stream_id'], get_stream('Muted Stream', user_profile.realm).id)
|
||||
self.assertEqual(unread_stream['topic'], 'test')
|
||||
self.assertEqual(unread_stream['unread_message_ids'], [muted_stream_message_id])
|
||||
self.assertEqual(unread_stream['sender_ids'], [sender_id])
|
||||
|
||||
huddle_string = ','.join(str(uid) for uid in sorted([sender_id, user_profile.id, othello.id]))
|
||||
|
||||
unread_huddle = result['huddles'][0]
|
||||
self.assertEqual(unread_huddle['user_ids_string'], huddle_string)
|
||||
self.assertEqual(unread_huddle['unread_message_ids'], [huddle_message_id])
|
||||
self.assertTrue('sender_ids' not in unread_huddle)
|
||||
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um = UserMessage.objects.get(
|
||||
user_profile_id=user_profile.id,
|
||||
message_id=stream_message_id,
|
||||
)
|
||||
um.flags |= UserMessage.flags.mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [stream_message_id])
|
||||
|
||||
um.flags = UserMessage.flags.has_alert_word
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
# TODO: This should change when we make alert words work better.
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um.flags = UserMessage.flags.wildcard_mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [stream_message_id])
|
||||
|
||||
um.flags = 0
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
# Test with a muted stream
|
||||
um = UserMessage.objects.get(
|
||||
user_profile_id=user_profile.id,
|
||||
message_id=muted_stream_message_id,
|
||||
)
|
||||
um.flags = UserMessage.flags.mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [muted_stream_message_id])
|
||||
|
||||
um.flags = UserMessage.flags.has_alert_word
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um.flags = UserMessage.flags.wildcard_mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um.flags = 0
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
# Test with a muted topic
|
||||
um = UserMessage.objects.get(
|
||||
user_profile_id=user_profile.id,
|
||||
message_id=muted_topic_message_id,
|
||||
)
|
||||
um.flags = UserMessage.flags.mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [muted_topic_message_id])
|
||||
|
||||
um.flags = UserMessage.flags.has_alert_word
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um.flags = UserMessage.flags.wildcard_mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um.flags = 0
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
@ -1,14 +1,30 @@
|
||||
from typing import Any, List, Mapping
|
||||
from typing import Any, List, Mapping, Set
|
||||
from unittest import mock
|
||||
|
||||
import ujson
|
||||
from django.db import connection
|
||||
|
||||
from zerver.lib.fix_unreads import fix, fix_unsubscribed
|
||||
from zerver.lib.message import (
|
||||
MessageDict,
|
||||
UnreadMessagesResult,
|
||||
aggregate_unread_data,
|
||||
apply_unread_message_event,
|
||||
get_raw_unread_data,
|
||||
)
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.lib.test_helpers import get_subscription, tornado_redirected_to_list
|
||||
from zerver.lib.topic_mutes import add_topic_mute
|
||||
from zerver.models import Subscription, UserMessage, UserProfile, get_realm, get_stream
|
||||
from zerver.models import (
|
||||
Message,
|
||||
Recipient,
|
||||
Stream,
|
||||
Subscription,
|
||||
UserMessage,
|
||||
UserProfile,
|
||||
get_realm,
|
||||
get_stream,
|
||||
)
|
||||
|
||||
|
||||
class FirstUnreadAnchorTests(ZulipTestCase):
|
||||
@ -422,3 +438,419 @@ class PushNotificationMarkReadFlowsTest(ZulipTestCase):
|
||||
self.assertEqual(self.get_mobile_push_notification_ids(user_profile),
|
||||
[])
|
||||
mock_push_notifications.assert_called()
|
||||
|
||||
class GetUnreadMsgsTest(ZulipTestCase):
|
||||
def mute_stream(self, user_profile: UserProfile, stream: Stream) -> None:
|
||||
recipient = Recipient.objects.get(type_id=stream.id, type=Recipient.STREAM)
|
||||
subscription = Subscription.objects.get(
|
||||
user_profile=user_profile,
|
||||
recipient=recipient,
|
||||
)
|
||||
subscription.is_muted = True
|
||||
subscription.save()
|
||||
|
||||
def mute_topic(self, user_profile: UserProfile, stream_name: str,
|
||||
topic_name: str) -> None:
|
||||
realm = user_profile.realm
|
||||
stream = get_stream(stream_name, realm)
|
||||
recipient = stream.recipient
|
||||
|
||||
add_topic_mute(
|
||||
user_profile=user_profile,
|
||||
stream_id=stream.id,
|
||||
recipient_id=recipient.id,
|
||||
topic_name=topic_name,
|
||||
)
|
||||
|
||||
def test_raw_unread_stream(self) -> None:
|
||||
cordelia = self.example_user('cordelia')
|
||||
hamlet = self.example_user('hamlet')
|
||||
realm = hamlet.realm
|
||||
|
||||
for stream_name in ['social', 'devel', 'test here']:
|
||||
self.subscribe(hamlet, stream_name)
|
||||
self.subscribe(cordelia, stream_name)
|
||||
|
||||
all_message_ids: Set[int] = set()
|
||||
message_ids = dict()
|
||||
|
||||
tups = [
|
||||
('social', 'lunch'),
|
||||
('test here', 'bla'),
|
||||
('devel', 'python'),
|
||||
('devel', 'ruby'),
|
||||
]
|
||||
|
||||
for stream_name, topic_name in tups:
|
||||
message_ids[topic_name] = [
|
||||
self.send_stream_message(
|
||||
sender=cordelia,
|
||||
stream_name=stream_name,
|
||||
topic_name=topic_name,
|
||||
) for i in range(3)
|
||||
]
|
||||
all_message_ids |= set(message_ids[topic_name])
|
||||
|
||||
self.assertEqual(len(all_message_ids), 12) # sanity check on test setup
|
||||
|
||||
self.mute_stream(
|
||||
user_profile=hamlet,
|
||||
stream=get_stream('test here', realm),
|
||||
)
|
||||
|
||||
self.mute_topic(
|
||||
user_profile=hamlet,
|
||||
stream_name='devel',
|
||||
topic_name='ruby',
|
||||
)
|
||||
|
||||
raw_unread_data = get_raw_unread_data(
|
||||
user_profile=hamlet,
|
||||
)
|
||||
|
||||
stream_dict = raw_unread_data['stream_dict']
|
||||
|
||||
self.assertEqual(
|
||||
set(stream_dict.keys()),
|
||||
all_message_ids,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
raw_unread_data['unmuted_stream_msgs'],
|
||||
set(message_ids['python']) | set(message_ids['lunch']),
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
stream_dict[message_ids['lunch'][0]],
|
||||
dict(
|
||||
sender_id=cordelia.id,
|
||||
stream_id=get_stream('social', realm).id,
|
||||
topic='lunch',
|
||||
),
|
||||
)
|
||||
|
||||
def test_raw_unread_huddle(self) -> None:
|
||||
cordelia = self.example_user('cordelia')
|
||||
othello = self.example_user('othello')
|
||||
hamlet = self.example_user('hamlet')
|
||||
prospero = self.example_user('prospero')
|
||||
|
||||
huddle1_message_ids = [
|
||||
self.send_huddle_message(
|
||||
cordelia,
|
||||
[hamlet, othello],
|
||||
)
|
||||
for i in range(3)
|
||||
]
|
||||
|
||||
huddle2_message_ids = [
|
||||
self.send_huddle_message(
|
||||
cordelia,
|
||||
[hamlet, prospero],
|
||||
)
|
||||
for i in range(3)
|
||||
]
|
||||
|
||||
raw_unread_data = get_raw_unread_data(
|
||||
user_profile=hamlet,
|
||||
)
|
||||
|
||||
huddle_dict = raw_unread_data['huddle_dict']
|
||||
|
||||
self.assertEqual(
|
||||
set(huddle_dict.keys()),
|
||||
set(huddle1_message_ids) | set(huddle2_message_ids),
|
||||
)
|
||||
|
||||
huddle_string = ','.join(
|
||||
str(uid)
|
||||
for uid in sorted([cordelia.id, hamlet.id, othello.id])
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
huddle_dict[huddle1_message_ids[0]],
|
||||
dict(user_ids_string=huddle_string),
|
||||
)
|
||||
|
||||
def test_raw_unread_personal(self) -> None:
|
||||
cordelia = self.example_user('cordelia')
|
||||
othello = self.example_user('othello')
|
||||
hamlet = self.example_user('hamlet')
|
||||
|
||||
cordelia_pm_message_ids = [
|
||||
self.send_personal_message(cordelia, hamlet)
|
||||
for i in range(3)
|
||||
]
|
||||
|
||||
othello_pm_message_ids = [
|
||||
self.send_personal_message(othello, hamlet)
|
||||
for i in range(3)
|
||||
]
|
||||
|
||||
raw_unread_data = get_raw_unread_data(
|
||||
user_profile=hamlet,
|
||||
)
|
||||
|
||||
pm_dict = raw_unread_data['pm_dict']
|
||||
|
||||
self.assertEqual(
|
||||
set(pm_dict.keys()),
|
||||
set(cordelia_pm_message_ids) | set(othello_pm_message_ids),
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
pm_dict[cordelia_pm_message_ids[0]],
|
||||
dict(sender_id=cordelia.id),
|
||||
)
|
||||
|
||||
def test_raw_unread_personal_from_self(self) -> None:
|
||||
hamlet = self.example_user('hamlet')
|
||||
|
||||
def send_unread_pm(other_user: UserProfile) -> Message:
|
||||
# It is rare to send a message from Hamlet to Othello
|
||||
# (or any other user) and have it be unread for
|
||||
# Hamlet himself, but that is actually normal
|
||||
# behavior for most API clients.
|
||||
message_id = self.send_personal_message(
|
||||
from_user=hamlet,
|
||||
to_user=other_user,
|
||||
sending_client_name='some_api_program',
|
||||
)
|
||||
|
||||
# Check our test setup is correct--the message should
|
||||
# not have looked like it was sent by a human.
|
||||
message = Message.objects.get(id=message_id)
|
||||
self.assertFalse(message.sent_by_human())
|
||||
|
||||
# And since it was not sent by a human, it should not
|
||||
# be read, not even by the sender (Hamlet).
|
||||
um = UserMessage.objects.get(
|
||||
user_profile_id=hamlet.id,
|
||||
message_id=message_id,
|
||||
)
|
||||
self.assertFalse(um.flags.read)
|
||||
|
||||
return message
|
||||
|
||||
othello = self.example_user('othello')
|
||||
othello_msg = send_unread_pm(other_user=othello)
|
||||
|
||||
# And now check the unread data structure...
|
||||
raw_unread_data = get_raw_unread_data(
|
||||
user_profile=hamlet,
|
||||
)
|
||||
|
||||
pm_dict = raw_unread_data['pm_dict']
|
||||
|
||||
self.assertEqual(set(pm_dict.keys()), {othello_msg.id})
|
||||
|
||||
# For legacy reason we call the field `sender_id` here,
|
||||
# but it really refers to the other user id in the conversation,
|
||||
# which is Othello.
|
||||
self.assertEqual(
|
||||
pm_dict[othello_msg.id],
|
||||
dict(sender_id=othello.id),
|
||||
)
|
||||
|
||||
cordelia = self.example_user('cordelia')
|
||||
cordelia_msg = send_unread_pm(other_user=cordelia)
|
||||
|
||||
apply_unread_message_event(
|
||||
user_profile=hamlet,
|
||||
state=raw_unread_data,
|
||||
message=MessageDict.wide_dict(cordelia_msg),
|
||||
flags=[],
|
||||
)
|
||||
self.assertEqual(
|
||||
set(pm_dict.keys()),
|
||||
{othello_msg.id, cordelia_msg.id},
|
||||
)
|
||||
|
||||
# Again, `sender_id` is misnamed here.
|
||||
self.assertEqual(
|
||||
pm_dict[cordelia_msg.id],
|
||||
dict(sender_id=cordelia.id),
|
||||
)
|
||||
|
||||
# Send a message to ourself.
|
||||
hamlet_msg = send_unread_pm(other_user=hamlet)
|
||||
apply_unread_message_event(
|
||||
user_profile=hamlet,
|
||||
state=raw_unread_data,
|
||||
message=MessageDict.wide_dict(hamlet_msg),
|
||||
flags=[],
|
||||
)
|
||||
self.assertEqual(
|
||||
set(pm_dict.keys()),
|
||||
{othello_msg.id, cordelia_msg.id, hamlet_msg.id},
|
||||
)
|
||||
|
||||
# Again, `sender_id` is misnamed here.
|
||||
self.assertEqual(
|
||||
pm_dict[hamlet_msg.id],
|
||||
dict(sender_id=hamlet.id),
|
||||
)
|
||||
|
||||
# Call get_raw_unread_data again.
|
||||
raw_unread_data = get_raw_unread_data(
|
||||
user_profile=hamlet,
|
||||
)
|
||||
pm_dict = raw_unread_data['pm_dict']
|
||||
|
||||
self.assertEqual(
|
||||
set(pm_dict.keys()),
|
||||
{othello_msg.id, cordelia_msg.id, hamlet_msg.id},
|
||||
)
|
||||
|
||||
# Again, `sender_id` is misnamed here.
|
||||
self.assertEqual(
|
||||
pm_dict[hamlet_msg.id],
|
||||
dict(sender_id=hamlet.id),
|
||||
)
|
||||
|
||||
def test_unread_msgs(self) -> None:
|
||||
sender = self.example_user('cordelia')
|
||||
sender_id = sender.id
|
||||
user_profile = self.example_user('hamlet')
|
||||
othello = self.example_user('othello')
|
||||
|
||||
pm1_message_id = self.send_personal_message(sender, user_profile, "hello1")
|
||||
pm2_message_id = self.send_personal_message(sender, user_profile, "hello2")
|
||||
|
||||
muted_stream = self.subscribe(user_profile, 'Muted Stream')
|
||||
self.mute_stream(user_profile, muted_stream)
|
||||
self.mute_topic(user_profile, 'Denmark', 'muted-topic')
|
||||
|
||||
stream_message_id = self.send_stream_message(sender, "Denmark", "hello")
|
||||
muted_stream_message_id = self.send_stream_message(sender, "Muted Stream", "hello")
|
||||
muted_topic_message_id = self.send_stream_message(
|
||||
sender,
|
||||
"Denmark",
|
||||
topic_name="muted-topic",
|
||||
content="hello",
|
||||
)
|
||||
|
||||
huddle_message_id = self.send_huddle_message(
|
||||
sender,
|
||||
[user_profile, othello],
|
||||
'hello3',
|
||||
)
|
||||
|
||||
def get_unread_data() -> UnreadMessagesResult:
|
||||
raw_unread_data = get_raw_unread_data(user_profile)
|
||||
aggregated_data = aggregate_unread_data(raw_unread_data)
|
||||
return aggregated_data
|
||||
|
||||
result = get_unread_data()
|
||||
|
||||
# The count here reflects the count of unread messages that we will
|
||||
# report to users in the bankruptcy dialog, and for now it excludes unread messages
|
||||
# from muted treams, but it doesn't exclude unread messages from muted topics yet.
|
||||
self.assertEqual(result['count'], 4)
|
||||
|
||||
unread_pm = result['pms'][0]
|
||||
self.assertEqual(unread_pm['sender_id'], sender_id)
|
||||
self.assertEqual(unread_pm['unread_message_ids'], [pm1_message_id, pm2_message_id])
|
||||
self.assertTrue('sender_ids' not in unread_pm)
|
||||
|
||||
unread_stream = result['streams'][0]
|
||||
self.assertEqual(unread_stream['stream_id'], get_stream('Denmark', user_profile.realm).id)
|
||||
self.assertEqual(unread_stream['topic'], 'muted-topic')
|
||||
self.assertEqual(unread_stream['unread_message_ids'], [muted_topic_message_id])
|
||||
self.assertEqual(unread_stream['sender_ids'], [sender_id])
|
||||
|
||||
unread_stream = result['streams'][1]
|
||||
self.assertEqual(unread_stream['stream_id'], get_stream('Denmark', user_profile.realm).id)
|
||||
self.assertEqual(unread_stream['topic'], 'test')
|
||||
self.assertEqual(unread_stream['unread_message_ids'], [stream_message_id])
|
||||
self.assertEqual(unread_stream['sender_ids'], [sender_id])
|
||||
|
||||
unread_stream = result['streams'][2]
|
||||
self.assertEqual(unread_stream['stream_id'], get_stream('Muted Stream', user_profile.realm).id)
|
||||
self.assertEqual(unread_stream['topic'], 'test')
|
||||
self.assertEqual(unread_stream['unread_message_ids'], [muted_stream_message_id])
|
||||
self.assertEqual(unread_stream['sender_ids'], [sender_id])
|
||||
|
||||
huddle_string = ','.join(str(uid) for uid in sorted([sender_id, user_profile.id, othello.id]))
|
||||
|
||||
unread_huddle = result['huddles'][0]
|
||||
self.assertEqual(unread_huddle['user_ids_string'], huddle_string)
|
||||
self.assertEqual(unread_huddle['unread_message_ids'], [huddle_message_id])
|
||||
self.assertTrue('sender_ids' not in unread_huddle)
|
||||
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um = UserMessage.objects.get(
|
||||
user_profile_id=user_profile.id,
|
||||
message_id=stream_message_id,
|
||||
)
|
||||
um.flags |= UserMessage.flags.mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [stream_message_id])
|
||||
|
||||
um.flags = UserMessage.flags.has_alert_word
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
# TODO: This should change when we make alert words work better.
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um.flags = UserMessage.flags.wildcard_mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [stream_message_id])
|
||||
|
||||
um.flags = 0
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
# Test with a muted stream
|
||||
um = UserMessage.objects.get(
|
||||
user_profile_id=user_profile.id,
|
||||
message_id=muted_stream_message_id,
|
||||
)
|
||||
um.flags = UserMessage.flags.mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [muted_stream_message_id])
|
||||
|
||||
um.flags = UserMessage.flags.has_alert_word
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um.flags = UserMessage.flags.wildcard_mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um.flags = 0
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
# Test with a muted topic
|
||||
um = UserMessage.objects.get(
|
||||
user_profile_id=user_profile.id,
|
||||
message_id=muted_topic_message_id,
|
||||
)
|
||||
um.flags = UserMessage.flags.mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [muted_topic_message_id])
|
||||
|
||||
um.flags = UserMessage.flags.has_alert_word
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um.flags = UserMessage.flags.wildcard_mentioned
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
um.flags = 0
|
||||
um.save()
|
||||
result = get_unread_data()
|
||||
self.assertEqual(result['mentions'], [])
|
||||
|
||||
Loading…
Reference in New Issue
Block a user