models: Add denormalized .realm column to Message.

This commit adds the OPTIONAL .realm attribute to Message
(and ArchivedMessage), with the server changes for making new Messages
have this set. Old Messages still have to be migrated to backfill this,
before it can be non-nullable.

Appropriate test changes to correctly set .realm for Messages the tests
manually create are included here as well.
This commit is contained in:
Mateusz Mandera 2022-09-27 21:42:31 +02:00 committed by Tim Abbott
parent a4008d938a
commit 00b3546c9f
21 changed files with 176 additions and 36 deletions

View File

@ -70,6 +70,7 @@ from zerver.models import (
UserProfile, UserProfile,
get_client, get_client,
get_user, get_user,
is_cross_realm_bot_email,
) )
@ -158,7 +159,12 @@ class AnalyticsTestCase(ZulipTestCase):
"content": "hi", "content": "hi",
"date_sent": self.TIME_LAST_HOUR, "date_sent": self.TIME_LAST_HOUR,
"sending_client": get_client("website"), "sending_client": get_client("website"),
"realm_id": sender.realm_id,
} }
# For simplicity, this helper doesn't support creating cross-realm messages
# since it'd require adding an additional realm argument.
assert not is_cross_realm_bot_email(sender.delivery_email)
for key, value in defaults.items(): for key, value in defaults.items():
kwargs[key] = kwargs.get(key, value) kwargs[key] = kwargs.get(key, value)
return Message.objects.create(**kwargs) return Message.objects.create(**kwargs)

View File

@ -510,6 +510,7 @@ def build_message_send_dict(
""" """
if realm is None: if realm is None:
realm = message.sender.realm realm = message.sender.realm
assert realm == message.realm
if mention_backend is None: if mention_backend is None:
mention_backend = MentionBackend(realm.id) mention_backend = MentionBackend(realm.id)
@ -1442,6 +1443,7 @@ def check_message(
message.sender = sender message.sender = sender
message.content = message_content message.content = message_content
message.recipient = recipient message.recipient = recipient
message.realm = realm
if addressee.is_stream(): if addressee.is_stream():
message.set_topic_name(topic_name) message.set_topic_name(topic_name)
if forged and forged_timestamp is not None: if forged and forged_timestamp is not None:

View File

@ -233,6 +233,7 @@ def convert_gitter_workspace_messages(
stream_map: Dict[str, int], stream_map: Dict[str, int],
user_short_name_to_full_name: Dict[str, str], user_short_name_to_full_name: Dict[str, str],
zerver_userprofile: List[ZerverFieldsT], zerver_userprofile: List[ZerverFieldsT],
realm_id: int,
chunk_size: int = MESSAGE_BATCH_CHUNK_SIZE, chunk_size: int = MESSAGE_BATCH_CHUNK_SIZE,
) -> None: ) -> None:
""" """
@ -279,6 +280,7 @@ def convert_gitter_workspace_messages(
rendered_content=rendered_content, rendered_content=rendered_content,
user_id=user_id, user_id=user_id,
recipient_id=recipient_id, recipient_id=recipient_id,
realm_id=realm_id,
) )
zerver_message.append(zulip_message) zerver_message.append(zulip_message)
@ -365,6 +367,7 @@ def do_convert_data(gitter_data_file: str, output_dir: str, threads: int = 6) ->
stream_map, stream_map,
user_short_name_to_full_name, user_short_name_to_full_name,
realm["zerver_userprofile"], realm["zerver_userprofile"],
realm_id=realm_id,
) )
avatar_folder = os.path.join(output_dir, "avatars") avatar_folder = os.path.join(output_dir, "avatars")

View File

@ -495,6 +495,7 @@ def build_message(
rendered_content: Optional[str], rendered_content: Optional[str],
user_id: int, user_id: int,
recipient_id: int, recipient_id: int,
realm_id: int,
has_image: bool = False, has_image: bool = False,
has_link: bool = False, has_link: bool = False,
has_attachment: bool = True, has_attachment: bool = True,

View File

@ -492,6 +492,7 @@ def process_raw_message_batch(
message_id=message_id, message_id=message_id,
date_sent=date_sent, date_sent=date_sent,
recipient_id=recipient_id, recipient_id=recipient_id,
realm_id=realm_id,
rendered_content=rendered_content, rendered_content=rendered_content,
topic_name=topic_name, topic_name=topic_name,
user_id=sender_user_id, user_id=sender_user_id,

View File

@ -543,6 +543,7 @@ def process_raw_message_batch(
message_id=message_id, message_id=message_id,
date_sent=date_sent, date_sent=date_sent,
recipient_id=recipient_id, recipient_id=recipient_id,
realm_id=realm_id,
rendered_content=rendered_content, rendered_content=rendered_content,
topic_name=topic_name, topic_name=topic_name,
user_id=sender_user_id, user_id=sender_user_id,

View File

@ -960,6 +960,7 @@ def channel_message_to_zerver_message(
rendered_content=rendered_content, rendered_content=rendered_content,
user_id=slack_user_id_to_zulip_user_id[slack_user_id], user_id=slack_user_id_to_zulip_user_id[slack_user_id],
recipient_id=recipient_id, recipient_id=recipient_id,
realm_id=realm_id,
has_image=has_image, has_image=has_image,
has_link=has_link, has_link=has_link,
has_attachment=has_attachment, has_attachment=has_attachment,

View File

@ -1469,6 +1469,8 @@ def import_message_data(realm: Realm, sender_map: Dict[int, Record], import_dir:
# apply them. # apply them.
message_id_map = ID_MAP["message"] message_id_map = ID_MAP["message"]
for row in data["zerver_message"]: for row in data["zerver_message"]:
del row["realm"]
row["realm_id"] = realm.id
row["id"] = message_id_map[row["id"]] row["id"] = message_id_map[row["id"]]
for row in data["zerver_usermessage"]: for row in data["zerver_usermessage"]:

View File

@ -32,6 +32,7 @@ Usage: ./manage.py deliver_scheduled_messages
original_sender = scheduled_message.sender original_sender = scheduled_message.sender
message.content = scheduled_message.content message.content = scheduled_message.content
message.recipient = scheduled_message.recipient message.recipient = scheduled_message.recipient
message.realm = scheduled_message.realm
message.subject = scheduled_message.subject message.subject = scheduled_message.subject
message.date_sent = timezone_now() message.date_sent = timezone_now()
message.sending_client = scheduled_message.sending_client message.sending_client = scheduled_message.sending_client

View File

@ -0,0 +1,28 @@
# Generated by Django 4.0.7 on 2022-09-26 21:02
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("zerver", "0417_alter_customprofilefield_field_type"),
]
operations = [
migrations.AddField(
model_name="archivedmessage",
name="realm",
field=models.ForeignKey(
null=True, on_delete=django.db.models.deletion.CASCADE, to="zerver.realm"
),
),
migrations.AddField(
model_name="message",
name="realm",
field=models.ForeignKey(
null=True, on_delete=django.db.models.deletion.CASCADE, to="zerver.realm"
),
),
]

View File

@ -2811,6 +2811,8 @@ class AbstractMessage(models.Model):
# See the Recipient class for details. # See the Recipient class for details.
recipient = models.ForeignKey(Recipient, on_delete=CASCADE) recipient = models.ForeignKey(Recipient, on_delete=CASCADE)
realm = models.ForeignKey(Realm, on_delete=CASCADE, null=True)
# The message's topic. # The message's topic.
# #
# Early versions of Zulip called this concept a "subject", as in an email # Early versions of Zulip called this concept a "subject", as in an email

View File

@ -526,14 +526,22 @@ class TestDigestContentInBrowser(ZulipTestCase):
class TestDigestTopics(ZulipTestCase): class TestDigestTopics(ZulipTestCase):
def populate_topic( def populate_topic(
self, topic: DigestTopic, humans: int, human_messages: int, bots: int, bot_messages: int self,
topic: DigestTopic,
humans: int,
human_messages: int,
bots: int,
bot_messages: int,
realm: Realm,
) -> None: ) -> None:
def send_messages(client: Client, users: int, messages: int) -> None: def send_messages(client: Client, users: int, messages: int) -> None:
messages_sent = 0 messages_sent = 0
while messages_sent < messages: while messages_sent < messages:
for index, username in enumerate(self.example_user_map, start=1): for index, username in enumerate(self.example_user_map, start=1):
topic.add_message( topic.add_message(
Message(sender=self.example_user(username), sending_client=client) Message(
sender=self.example_user(username), sending_client=client, realm=realm
)
) )
messages_sent += 1 messages_sent += 1
if messages_sent == messages: if messages_sent == messages:
@ -549,31 +557,49 @@ class TestDigestTopics(ZulipTestCase):
denmark = get_stream("Denmark", realm) denmark = get_stream("Denmark", realm)
verona = get_stream("Verona", realm) verona = get_stream("Verona", realm)
diverse_topic_a = DigestTopic((denmark.id, "5 humans talking")) diverse_topic_a = DigestTopic((denmark.id, "5 humans talking"))
self.populate_topic(diverse_topic_a, humans=5, human_messages=10, bots=0, bot_messages=0) self.populate_topic(
diverse_topic_a, humans=5, human_messages=10, bots=0, bot_messages=0, realm=realm
)
diverse_topic_b = DigestTopic((denmark.id, "4 humans talking")) diverse_topic_b = DigestTopic((denmark.id, "4 humans talking"))
self.populate_topic(diverse_topic_b, humans=4, human_messages=15, bots=0, bot_messages=0) self.populate_topic(
diverse_topic_b, humans=4, human_messages=15, bots=0, bot_messages=0, realm=realm
)
diverse_topic_c = DigestTopic((verona.id, "5 humans talking in another stream")) diverse_topic_c = DigestTopic((verona.id, "5 humans talking in another stream"))
self.populate_topic(diverse_topic_c, humans=5, human_messages=15, bots=0, bot_messages=0) self.populate_topic(
diverse_topic_c, humans=5, human_messages=15, bots=0, bot_messages=0, realm=realm
)
diverse_topic_d = DigestTopic((denmark.id, "3 humans and 2 bots talking")) diverse_topic_d = DigestTopic((denmark.id, "3 humans and 2 bots talking"))
self.populate_topic(diverse_topic_d, humans=3, human_messages=15, bots=2, bot_messages=10) self.populate_topic(
diverse_topic_d, humans=3, human_messages=15, bots=2, bot_messages=10, realm=realm
)
diverse_topic_e = DigestTopic((denmark.id, "3 humans talking")) diverse_topic_e = DigestTopic((denmark.id, "3 humans talking"))
self.populate_topic(diverse_topic_a, humans=3, human_messages=20, bots=0, bot_messages=0) self.populate_topic(
diverse_topic_a, humans=3, human_messages=20, bots=0, bot_messages=0, realm=realm
)
lengthy_topic_a = DigestTopic((denmark.id, "2 humans talking a lot")) lengthy_topic_a = DigestTopic((denmark.id, "2 humans talking a lot"))
self.populate_topic(lengthy_topic_a, humans=2, human_messages=40, bots=0, bot_messages=0) self.populate_topic(
lengthy_topic_a, humans=2, human_messages=40, bots=0, bot_messages=0, realm=realm
)
lengthy_topic_b = DigestTopic((denmark.id, "2 humans talking")) lengthy_topic_b = DigestTopic((denmark.id, "2 humans talking"))
self.populate_topic(lengthy_topic_b, humans=2, human_messages=30, bots=0, bot_messages=0) self.populate_topic(
lengthy_topic_b, humans=2, human_messages=30, bots=0, bot_messages=0, realm=realm
)
lengthy_topic_c = DigestTopic((denmark.id, "a human and bot talking")) lengthy_topic_c = DigestTopic((denmark.id, "a human and bot talking"))
self.populate_topic(lengthy_topic_c, humans=1, human_messages=20, bots=1, bot_messages=20) self.populate_topic(
lengthy_topic_c, humans=1, human_messages=20, bots=1, bot_messages=20, realm=realm
)
lengthy_topic_d = DigestTopic((verona.id, "2 humans talking in another stream")) lengthy_topic_d = DigestTopic((verona.id, "2 humans talking in another stream"))
self.populate_topic(lengthy_topic_d, humans=2, human_messages=35, bots=0, bot_messages=0) self.populate_topic(
lengthy_topic_d, humans=2, human_messages=35, bots=0, bot_messages=0, realm=realm
)
topics = [ topics = [
diverse_topic_a, diverse_topic_a,

View File

@ -965,6 +965,11 @@ class RealmImportExportTest(ExportFile):
imported_realm.authentication_methods_dict(), imported_realm.authentication_methods_dict(),
) )
self.assertEqual(
Message.objects.filter(realm=original_realm).count(),
Message.objects.filter(realm=imported_realm).count(),
)
def get_realm_getters(self) -> List[Callable[[Realm], object]]: def get_realm_getters(self) -> List[Callable[[Realm], object]]:
names = set() names = set()
getters: List[Callable[[Realm], object]] = [] getters: List[Callable[[Realm], object]] = []

View File

@ -143,6 +143,7 @@ class MessageDictTest(ZulipTestCase):
def test_bulk_message_fetching(self) -> None: def test_bulk_message_fetching(self) -> None:
sender = self.example_user("othello") sender = self.example_user("othello")
receiver = self.example_user("hamlet") receiver = self.example_user("hamlet")
realm = get_realm("zulip")
pm_recipient = Recipient.objects.get(type_id=receiver.id, type=Recipient.PERSONAL) pm_recipient = Recipient.objects.get(type_id=receiver.id, type=Recipient.PERSONAL)
stream_name = "Çiğdem" stream_name = "Çiğdem"
stream = self.make_stream(stream_name) stream = self.make_stream(stream_name)
@ -155,6 +156,7 @@ class MessageDictTest(ZulipTestCase):
message = Message( message = Message(
sender=sender, sender=sender,
recipient=recipient, recipient=recipient,
realm=realm,
content=f"whatever {i}", content=f"whatever {i}",
rendered_content="DOES NOT MATTER", rendered_content="DOES NOT MATTER",
rendered_content_version=markdown_version, rendered_content_version=markdown_version,
@ -192,6 +194,7 @@ class MessageDictTest(ZulipTestCase):
message = Message( message = Message(
sender=sender, sender=sender,
recipient=recipient, recipient=recipient,
realm=receiver.realm,
content="hello **world**", content="hello **world**",
date_sent=timezone_now(), date_sent=timezone_now(),
sending_client=sending_client, sending_client=sending_client,
@ -222,6 +225,7 @@ class MessageDictTest(ZulipTestCase):
message = Message( message = Message(
sender=sender, sender=sender,
recipient=recipient, recipient=recipient,
realm=receiver.realm,
content="hello **world**", content="hello **world**",
date_sent=timezone_now(), date_sent=timezone_now(),
sending_client=sending_client, sending_client=sending_client,
@ -287,6 +291,7 @@ class MessageDictTest(ZulipTestCase):
message = Message( message = Message(
sender=sender, sender=sender,
recipient=recipient, recipient=recipient,
realm=receiver.realm,
content="hello **world**", content="hello **world**",
date_sent=timezone_now(), date_sent=timezone_now(),
sending_client=sending_client, sending_client=sending_client,
@ -620,6 +625,7 @@ class SewMessageAndReactionTest(ZulipTestCase):
def test_sew_messages_and_reaction(self) -> None: def test_sew_messages_and_reaction(self) -> None:
sender = self.example_user("othello") sender = self.example_user("othello")
receiver = self.example_user("hamlet") receiver = self.example_user("hamlet")
realm = get_realm("zulip")
pm_recipient = Recipient.objects.get(type_id=receiver.id, type=Recipient.PERSONAL) pm_recipient = Recipient.objects.get(type_id=receiver.id, type=Recipient.PERSONAL)
stream_name = "Çiğdem" stream_name = "Çiğdem"
stream = self.make_stream(stream_name) stream = self.make_stream(stream_name)
@ -632,6 +638,7 @@ class SewMessageAndReactionTest(ZulipTestCase):
message = Message( message = Message(
sender=sender, sender=sender,
recipient=recipient, recipient=recipient,
realm=realm,
content=f"whatever {i}", content=f"whatever {i}",
date_sent=timezone_now(), date_sent=timezone_now(),
sending_client=sending_client, sending_client=sending_client,

View File

@ -1578,6 +1578,7 @@ class StreamMessagesTest(ZulipTestCase):
message = Message( message = Message(
sender=sender, sender=sender,
recipient=recipient, recipient=recipient,
realm=stream.realm,
content=message_content, content=message_content,
date_sent=timezone_now(), date_sent=timezone_now(),
sending_client=sending_client, sending_client=sending_client,

View File

@ -40,6 +40,7 @@ class TopicHistoryTest(ZulipTestCase):
message = Message( message = Message(
sender=hamlet, sender=hamlet,
recipient=recipient, recipient=recipient,
realm=stream.realm,
content="whatever", content="whatever",
date_sent=timezone_now(), date_sent=timezone_now(),
sending_client=get_client("whatever"), sending_client=get_client("whatever"),

View File

@ -31,7 +31,7 @@ from zerver.models import get_stream
# been tested for a migration being merged. # been tested for a migration being merged.
@skip("Will not pass once newer migrations are merged.") # nocoverage # skipped @skip("Fails because newer migrations have since been merged.") # nocoverage # skipped
class MessageEditHistoryLegacyFormats(MigrationsTestCase): class MessageEditHistoryLegacyFormats(MigrationsTestCase):
migrate_from = "0376_set_realmemoji_author_and_reupload_realmemoji" migrate_from = "0376_set_realmemoji_author_and_reupload_realmemoji"
migrate_to = "0377_message_edit_history_format" migrate_to = "0377_message_edit_history_format"
@ -170,7 +170,7 @@ class MessageEditHistoryLegacyFormats(MigrationsTestCase):
) )
@skip("Will not pass once newer migrations are merged.") # nocoverage # skipped @skip("Fails because newer migrations have since been merged.") # nocoverage # skipped
class MessageEditHistoryModernFormats(MigrationsTestCase): class MessageEditHistoryModernFormats(MigrationsTestCase):
migrate_from = "0376_set_realmemoji_author_and_reupload_realmemoji" migrate_from = "0376_set_realmemoji_author_and_reupload_realmemoji"
migrate_to = "0377_message_edit_history_format" migrate_to = "0377_message_edit_history_format"
@ -292,7 +292,7 @@ class MessageEditHistoryModernFormats(MigrationsTestCase):
) )
@skip("Will not pass once newer migrations are merged.") # nocoverage # skipped @skip("Fails because newer migrations have since been merged.") # nocoverage # skipped
class MessageEditHistoryIntermediateFormats(MigrationsTestCase): class MessageEditHistoryIntermediateFormats(MigrationsTestCase):
migrate_from = "0376_set_realmemoji_author_and_reupload_realmemoji" migrate_from = "0376_set_realmemoji_author_and_reupload_realmemoji"
migrate_to = "0377_message_edit_history_format" migrate_to = "0377_message_edit_history_format"

View File

@ -839,7 +839,7 @@ class PushNotificationTest(BouncerTestCase):
self.sender = self.example_user("hamlet") self.sender = self.example_user("hamlet")
self.personal_recipient_user = self.example_user("othello") self.personal_recipient_user = self.example_user("othello")
def get_message(self, type: int, type_id: int) -> Message: def get_message(self, type: int, type_id: int, realm_id: int) -> Message:
recipient, _ = Recipient.objects.get_or_create( recipient, _ = Recipient.objects.get_or_create(
type_id=type_id, type_id=type_id,
type=type, type=type,
@ -848,6 +848,7 @@ class PushNotificationTest(BouncerTestCase):
message = Message( message = Message(
sender=self.sender, sender=self.sender,
recipient=recipient, recipient=recipient,
realm_id=realm_id,
content="This is test content", content="This is test content",
rendered_content="This is test content", rendered_content="This is test content",
date_sent=now(), date_sent=now(),
@ -943,7 +944,11 @@ class HandlePushNotificationTest(PushNotificationTest):
self.setup_apns_tokens() self.setup_apns_tokens()
self.setup_gcm_tokens() self.setup_gcm_tokens()
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
UserMessage.objects.create( UserMessage.objects.create(
user_profile=self.user_profile, user_profile=self.user_profile,
message=message, message=message,
@ -1001,7 +1006,11 @@ class HandlePushNotificationTest(PushNotificationTest):
self.setup_apns_tokens() self.setup_apns_tokens()
self.setup_gcm_tokens() self.setup_gcm_tokens()
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
UserMessage.objects.create( UserMessage.objects.create(
user_profile=self.user_profile, user_profile=self.user_profile,
message=message, message=message,
@ -1055,7 +1064,11 @@ class HandlePushNotificationTest(PushNotificationTest):
self.setup_apns_tokens() self.setup_apns_tokens()
self.setup_gcm_tokens() self.setup_gcm_tokens()
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
UserMessage.objects.create( UserMessage.objects.create(
user_profile=self.user_profile, user_profile=self.user_profile,
message=message, message=message,
@ -1081,7 +1094,11 @@ class HandlePushNotificationTest(PushNotificationTest):
@mock.patch("zerver.lib.push_notifications.push_notifications_enabled", return_value=True) @mock.patch("zerver.lib.push_notifications.push_notifications_enabled", return_value=True)
def test_read_message(self, mock_push_notifications: mock.MagicMock) -> None: def test_read_message(self, mock_push_notifications: mock.MagicMock) -> None:
user_profile = self.example_user("hamlet") user_profile = self.example_user("hamlet")
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
usermessage = UserMessage.objects.create( usermessage = UserMessage.objects.create(
user_profile=user_profile, user_profile=user_profile,
@ -1118,7 +1135,11 @@ class HandlePushNotificationTest(PushNotificationTest):
def test_deleted_message(self) -> None: def test_deleted_message(self) -> None:
"""Simulates the race where message is deleted before handling push notifications""" """Simulates the race where message is deleted before handling push notifications"""
user_profile = self.example_user("hamlet") user_profile = self.example_user("hamlet")
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
UserMessage.objects.create( UserMessage.objects.create(
user_profile=user_profile, user_profile=user_profile,
flags=UserMessage.flags.read, flags=UserMessage.flags.read,
@ -1147,7 +1168,11 @@ class HandlePushNotificationTest(PushNotificationTest):
def test_missing_message(self) -> None: def test_missing_message(self) -> None:
"""Simulates the race where message is missing when handling push notifications""" """Simulates the race where message is missing when handling push notifications"""
user_profile = self.example_user("hamlet") user_profile = self.example_user("hamlet")
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
UserMessage.objects.create( UserMessage.objects.create(
user_profile=user_profile, user_profile=user_profile,
flags=UserMessage.flags.read, flags=UserMessage.flags.read,
@ -1179,7 +1204,11 @@ class HandlePushNotificationTest(PushNotificationTest):
def test_send_notifications_to_bouncer(self) -> None: def test_send_notifications_to_bouncer(self) -> None:
user_profile = self.example_user("hamlet") user_profile = self.example_user("hamlet")
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
UserMessage.objects.create( UserMessage.objects.create(
user_profile=user_profile, user_profile=user_profile,
message=message, message=message,
@ -1217,7 +1246,11 @@ class HandlePushNotificationTest(PushNotificationTest):
def test_non_bouncer_push(self) -> None: def test_non_bouncer_push(self) -> None:
self.setup_apns_tokens() self.setup_apns_tokens()
self.setup_gcm_tokens() self.setup_gcm_tokens()
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
UserMessage.objects.create( UserMessage.objects.create(
user_profile=self.user_profile, user_profile=self.user_profile,
message=message, message=message,
@ -1256,7 +1289,11 @@ class HandlePushNotificationTest(PushNotificationTest):
def test_send_remove_notifications_to_bouncer(self) -> None: def test_send_remove_notifications_to_bouncer(self) -> None:
user_profile = self.example_user("hamlet") user_profile = self.example_user("hamlet")
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
UserMessage.objects.create( UserMessage.objects.create(
user_profile=user_profile, user_profile=user_profile,
message=message, message=message,
@ -1299,7 +1336,11 @@ class HandlePushNotificationTest(PushNotificationTest):
def test_non_bouncer_push_remove(self) -> None: def test_non_bouncer_push_remove(self) -> None:
self.setup_apns_tokens() self.setup_apns_tokens()
self.setup_gcm_tokens() self.setup_gcm_tokens()
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
UserMessage.objects.create( UserMessage.objects.create(
user_profile=self.user_profile, user_profile=self.user_profile,
message=message, message=message,
@ -1514,7 +1555,11 @@ class HandlePushNotificationTest(PushNotificationTest):
self, mock_push_notifications: mock.MagicMock, mock_info: mock.MagicMock self, mock_push_notifications: mock.MagicMock, mock_info: mock.MagicMock
) -> None: ) -> None:
user_profile = self.example_user("hamlet") user_profile = self.example_user("hamlet")
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
UserMessage.objects.create( UserMessage.objects.create(
user_profile=user_profile, user_profile=user_profile,
flags=UserMessage.flags.active_mobile_push_notification, flags=UserMessage.flags.active_mobile_push_notification,
@ -1767,7 +1812,7 @@ class TestGetAPNsPayload(PushNotificationTest):
def test_get_message_payload_apns_stream_message(self) -> None: def test_get_message_payload_apns_stream_message(self) -> None:
stream = Stream.objects.filter(name="Verona").get() stream = Stream.objects.filter(name="Verona").get()
message = self.get_message(Recipient.STREAM, stream.id) message = self.get_message(Recipient.STREAM, stream.id, stream.realm_id)
payload = get_message_payload_apns(self.sender, message, NotificationTriggers.STREAM_PUSH) payload = get_message_payload_apns(self.sender, message, NotificationTriggers.STREAM_PUSH)
expected = { expected = {
"alert": { "alert": {
@ -1798,7 +1843,7 @@ class TestGetAPNsPayload(PushNotificationTest):
def test_get_message_payload_apns_stream_mention(self) -> None: def test_get_message_payload_apns_stream_mention(self) -> None:
user_profile = self.example_user("othello") user_profile = self.example_user("othello")
stream = Stream.objects.filter(name="Verona").get() stream = Stream.objects.filter(name="Verona").get()
message = self.get_message(Recipient.STREAM, stream.id) message = self.get_message(Recipient.STREAM, stream.id, stream.realm_id)
payload = get_message_payload_apns(user_profile, message, NotificationTriggers.MENTION) payload = get_message_payload_apns(user_profile, message, NotificationTriggers.MENTION)
expected = { expected = {
"alert": { "alert": {
@ -1830,7 +1875,7 @@ class TestGetAPNsPayload(PushNotificationTest):
user_profile = self.example_user("othello") user_profile = self.example_user("othello")
user_group = create_user_group("test_user_group", [user_profile], get_realm("zulip")) user_group = create_user_group("test_user_group", [user_profile], get_realm("zulip"))
stream = Stream.objects.filter(name="Verona").get() stream = Stream.objects.filter(name="Verona").get()
message = self.get_message(Recipient.STREAM, stream.id) message = self.get_message(Recipient.STREAM, stream.id, stream.realm_id)
payload = get_message_payload_apns( payload = get_message_payload_apns(
user_profile, message, NotificationTriggers.MENTION, user_group.id, user_group.name user_profile, message, NotificationTriggers.MENTION, user_group.id, user_group.name
) )
@ -1865,7 +1910,7 @@ class TestGetAPNsPayload(PushNotificationTest):
def test_get_message_payload_apns_stream_wildcard_mention(self) -> None: def test_get_message_payload_apns_stream_wildcard_mention(self) -> None:
user_profile = self.example_user("othello") user_profile = self.example_user("othello")
stream = Stream.objects.filter(name="Verona").get() stream = Stream.objects.filter(name="Verona").get()
message = self.get_message(Recipient.STREAM, stream.id) message = self.get_message(Recipient.STREAM, stream.id, stream.realm_id)
payload = get_message_payload_apns( payload = get_message_payload_apns(
user_profile, message, NotificationTriggers.WILDCARD_MENTION user_profile, message, NotificationTriggers.WILDCARD_MENTION
) )
@ -1946,7 +1991,7 @@ class TestGetGCMPayload(PushNotificationTest):
mentioned_user_group_name: Optional[str] = None, mentioned_user_group_name: Optional[str] = None,
) -> None: ) -> None:
stream = Stream.objects.filter(name="Verona").get() stream = Stream.objects.filter(name="Verona").get()
message = self.get_message(Recipient.STREAM, stream.id) message = self.get_message(Recipient.STREAM, stream.id, stream.realm_id)
message.content = "a" * 210 message.content = "a" * 210
message.rendered_content = "a" * 210 message.rendered_content = "a" * 210
message.save() message.save()
@ -2008,7 +2053,11 @@ class TestGetGCMPayload(PushNotificationTest):
) )
def test_get_message_payload_gcm_private_message(self) -> None: def test_get_message_payload_gcm_private_message(self) -> None:
message = self.get_message(Recipient.PERSONAL, type_id=self.personal_recipient_user.id) message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
realm_id=self.personal_recipient_user.realm_id,
)
hamlet = self.example_user("hamlet") hamlet = self.example_user("hamlet")
payload, gcm_options = get_message_payload_gcm( payload, gcm_options = get_message_payload_gcm(
hamlet, message, NotificationTriggers.PRIVATE_MESSAGE hamlet, message, NotificationTriggers.PRIVATE_MESSAGE
@ -2042,7 +2091,7 @@ class TestGetGCMPayload(PushNotificationTest):
def test_get_message_payload_gcm_stream_notifications(self) -> None: def test_get_message_payload_gcm_stream_notifications(self) -> None:
stream = Stream.objects.get(name="Denmark") stream = Stream.objects.get(name="Denmark")
message = self.get_message(Recipient.STREAM, stream.id) message = self.get_message(Recipient.STREAM, stream.id, stream.realm_id)
hamlet = self.example_user("hamlet") hamlet = self.example_user("hamlet")
payload, gcm_options = get_message_payload_gcm( payload, gcm_options = get_message_payload_gcm(
hamlet, message, NotificationTriggers.STREAM_PUSH hamlet, message, NotificationTriggers.STREAM_PUSH
@ -2080,7 +2129,7 @@ class TestGetGCMPayload(PushNotificationTest):
@override_settings(PUSH_NOTIFICATION_REDACT_CONTENT=True) @override_settings(PUSH_NOTIFICATION_REDACT_CONTENT=True)
def test_get_message_payload_gcm_redacted_content(self) -> None: def test_get_message_payload_gcm_redacted_content(self) -> None:
stream = Stream.objects.get(name="Denmark") stream = Stream.objects.get(name="Denmark")
message = self.get_message(Recipient.STREAM, stream.id) message = self.get_message(Recipient.STREAM, stream.id, stream.realm_id)
hamlet = self.example_user("hamlet") hamlet = self.example_user("hamlet")
payload, gcm_options = get_message_payload_gcm( payload, gcm_options = get_message_payload_gcm(
hamlet, message, NotificationTriggers.STREAM_PUSH hamlet, message, NotificationTriggers.STREAM_PUSH

View File

@ -374,6 +374,7 @@ class SoftDeactivationMessageTest(ZulipTestCase):
recipient = stream.recipient recipient = stream.recipient
message = Message( message = Message(
sender=sender, sender=sender,
realm=realm,
recipient=recipient, recipient=recipient,
content=message_content, content=message_content,
date_sent=timezone_now(), date_sent=timezone_now(),

View File

@ -339,6 +339,7 @@ def render_message_backend(
) -> HttpResponse: ) -> HttpResponse:
message = Message() message = Message()
message.sender = user_profile message.sender = user_profile
message.realm = user_profile.realm
message.content = content message.content = content
client = RequestNotes.get_notes(request).client client = RequestNotes.get_notes(request).client
assert client is not None assert client is not None

View File

@ -1008,6 +1008,7 @@ def get_recipient_by_id(rid: int) -> Recipient:
def generate_and_send_messages( def generate_and_send_messages(
data: Tuple[int, Sequence[Sequence[int]], Mapping[str, Any], int] data: Tuple[int, Sequence[Sequence[int]], Mapping[str, Any], int]
) -> int: ) -> int:
realm = get_realm("zulip")
(tot_messages, personals_pairs, options, random_seed) = data (tot_messages, personals_pairs, options, random_seed) = data
random.seed(random_seed) random.seed(random_seed)
@ -1021,7 +1022,7 @@ def generate_and_send_messages(
# We need to filter out streams from the analytics realm as we don't want to generate # We need to filter out streams from the analytics realm as we don't want to generate
# messages to its streams - and they might also have no subscribers, which would break # messages to its streams - and they might also have no subscribers, which would break
# our message generation mechanism below. # our message generation mechanism below.
stream_ids = Stream.objects.filter(realm=get_realm("zulip")).values_list("id", flat=True) stream_ids = Stream.objects.filter(realm=realm).values_list("id", flat=True)
recipient_streams: List[int] = [ recipient_streams: List[int] = [
recipient.id recipient.id
for recipient in Recipient.objects.filter(type=Recipient.STREAM, type_id__in=stream_ids) for recipient in Recipient.objects.filter(type=Recipient.STREAM, type_id__in=stream_ids)
@ -1053,7 +1054,7 @@ def generate_and_send_messages(
messages: List[Message] = [] messages: List[Message] = []
while num_messages < tot_messages: while num_messages < tot_messages:
saved_data: Dict[str, Any] = {} saved_data: Dict[str, Any] = {}
message = Message() message = Message(realm=realm)
message.sending_client = get_client("populate_db") message.sending_client = get_client("populate_db")
message.content = next(texts) message.content = next(texts)