diff --git a/analytics/management/commands/populate_analytics_db.py b/analytics/management/commands/populate_analytics_db.py index 43a264dd19..adce720547 100644 --- a/analytics/management/commands/populate_analytics_db.py +++ b/analytics/management/commands/populate_analytics_db.py @@ -16,7 +16,7 @@ from analytics.models import ( StreamCount, UserCount, ) -from zerver.lib.actions import STREAM_ASSIGNMENT_COLORS, do_change_user_role +from zerver.lib.actions import STREAM_ASSIGNMENT_COLORS, do_change_user_role, do_create_realm from zerver.lib.create_user import create_user from zerver.lib.timestamp import floor_to_day from zerver.models import Client, Realm, Recipient, Stream, Subscription, UserProfile @@ -73,9 +73,10 @@ class Command(BaseCommand): installation_time = timezone_now() - timedelta(days=self.DAYS_OF_DATA) last_end_time = floor_to_day(timezone_now()) - realm = Realm.objects.create( + realm = do_create_realm( string_id="analytics", name="Analytics", date_created=installation_time ) + with mock.patch("zerver.lib.create_user.timezone_now", return_value=installation_time): shylock = create_user( "shylock@analytics.ds", diff --git a/analytics/tests/test_counts.py b/analytics/tests/test_counts.py index 74e61340e0..278269b5d6 100644 --- a/analytics/tests/test_counts.py +++ b/analytics/tests/test_counts.py @@ -35,6 +35,7 @@ from analytics.models import ( from zerver.lib.actions import ( InvitationError, do_activate_user, + do_create_realm, do_create_user, do_deactivate_user, do_invite_users, @@ -75,9 +76,10 @@ class AnalyticsTestCase(ZulipTestCase): def setUp(self) -> None: super().setUp() - self.default_realm = Realm.objects.create( + self.default_realm = do_create_realm( string_id="realmtest", name="Realm Test", date_created=self.TIME_ZERO - 2 * self.DAY ) + # used to generate unique names in self.create_* self.name_counter = 100 # used as defaults in self.assertCountEquals @@ -440,11 +442,12 @@ class TestCountStats(AnalyticsTestCase): # This tests two things for each of the queries/CountStats: Handling # more than 1 realm, and the time bounds (time_start and time_end in # the queries). - self.second_realm = Realm.objects.create( + self.second_realm = do_create_realm( string_id="second-realm", name="Second Realm", date_created=self.TIME_ZERO - 2 * self.DAY, ) + for minutes_ago in [0, 1, 61, 60 * 24 + 1]: creation_time = self.TIME_ZERO - minutes_ago * self.MINUTE user = self.create_user( @@ -461,11 +464,12 @@ class TestCountStats(AnalyticsTestCase): # This realm should not show up in the *Count tables for any of the # messages_* CountStats - self.no_message_realm = Realm.objects.create( + self.no_message_realm = do_create_realm( string_id="no-message-realm", name="No Message Realm", date_created=self.TIME_ZERO - 2 * self.DAY, ) + self.create_user(realm=self.no_message_realm) self.create_stream_with_recipient(realm=self.no_message_realm) # This huddle should not show up anywhere @@ -1195,7 +1199,7 @@ class TestDoIncrementLoggingStat(AnalyticsTestCase): # the appropriate *Count table, and that using a different zerver_object # results in a new row being created self.current_property = "test" - second_realm = Realm.objects.create(string_id="moo", name="moo") + second_realm = do_create_realm(string_id="moo", name="moo") stat = LoggingCountStat("test", RealmCount, CountStat.DAY) do_increment_logging_stat(self.default_realm, stat, None, self.TIME_ZERO) do_increment_logging_stat(second_realm, stat, None, self.TIME_ZERO) @@ -1572,7 +1576,7 @@ class TestActiveUsersAudit(AnalyticsTestCase): def test_multiple_users_realms_and_bots(self) -> None: user1 = self.create_user() user2 = self.create_user() - second_realm = Realm.objects.create(string_id="moo", name="moo") + second_realm = do_create_realm(string_id="moo", name="moo") user3 = self.create_user(realm=second_realm) user4 = self.create_user(realm=second_realm, is_bot=True) for user in [user1, user2, user3, user4]: @@ -1617,7 +1621,7 @@ class TestActiveUsersAudit(AnalyticsTestCase): def test_empty_realm_or_user_with_no_relevant_activity(self) -> None: self.add_event(RealmAuditLog.USER_SOFT_ACTIVATED, 1) self.create_user() # also test a user with no RealmAuditLog entries - Realm.objects.create(string_id="moo", name="moo") + do_create_realm(string_id="moo", name="moo") do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO) self.assertTableState(UserCount, [], []) @@ -1722,7 +1726,7 @@ class TestRealmActiveHumans(AnalyticsTestCase): def test_multiple_users_realms_and_times(self) -> None: user1 = self.create_user() user2 = self.create_user() - second_realm = Realm.objects.create(string_id="second", name="second") + second_realm = do_create_realm(string_id="second", name="second") user3 = self.create_user(realm=second_realm) user4 = self.create_user(realm=second_realm) user5 = self.create_user(realm=second_realm) @@ -1752,7 +1756,7 @@ class TestRealmActiveHumans(AnalyticsTestCase): self.mark_15day_active(user2, end_time=self.TIME_ZERO + self.DAY) self.mark_15day_active(user2, end_time=self.TIME_ZERO - self.DAY) self.create_user() - third_realm = Realm.objects.create(string_id="third", name="third") + third_realm = do_create_realm(string_id="third", name="third") self.create_user(realm=third_realm) RealmCount.objects.all().delete() diff --git a/corporate/tests/test_stripe.py b/corporate/tests/test_stripe.py index 48b883d923..b94d8c4288 100644 --- a/corporate/tests/test_stripe.py +++ b/corporate/tests/test_stripe.py @@ -55,6 +55,7 @@ from corporate.models import ( ) from zerver.lib.actions import ( do_activate_user, + do_create_realm, do_create_user, do_deactivate_realm, do_deactivate_user, @@ -1543,7 +1544,7 @@ class StripeTest(StripeTestCase): ) self.assertEqual(get_latest_seat_count(realm), initial_count) # Test 1 member and 5 guests - realm = Realm.objects.create(string_id="second", name="second") + realm = do_create_realm(string_id="second", name="second") UserProfile.objects.create( realm=realm, email="member@second.com", delivery_email="member@second.com" ) diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index d53b9a8389..02297580fe 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -4383,7 +4383,10 @@ def do_change_stream_message_retention_days( def do_create_realm( - string_id: str, name: str, emails_restricted_to_domains: Optional[bool] = None + string_id: str, + name: str, + emails_restricted_to_domains: Optional[bool] = None, + date_created: Optional[datetime.datetime] = None, ) -> Realm: if Realm.objects.filter(string_id=string_id).exists(): raise AssertionError(f"Realm {string_id} already exists!") @@ -4394,6 +4397,11 @@ def do_create_realm( kwargs: Dict[str, Any] = {} if emails_restricted_to_domains is not None: kwargs["emails_restricted_to_domains"] = emails_restricted_to_domains + if date_created is not None: + # The date_created parameter is intended only for use by test + # suites that want to backdate the date of a realm's creation. + assert not settings.PRODUCTION + kwargs["date_created"] = date_created realm = Realm(string_id=string_id, name=name, **kwargs) realm.save() diff --git a/zerver/tests/test_auth_backends.py b/zerver/tests/test_auth_backends.py index b9370815fe..bd6a07a821 100644 --- a/zerver/tests/test_auth_backends.py +++ b/zerver/tests/test_auth_backends.py @@ -5125,7 +5125,7 @@ class TestLDAP(ZulipLDAPTestCase): def test_login_success_with_different_subdomain(self) -> None: ldap_user_attr_map = {"full_name": "cn"} - Realm.objects.create(string_id="acme") + do_create_realm(string_id="acme", name="acme") with self.settings( LDAP_APPEND_DOMAIN="zulip.com", AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map ): diff --git a/zerver/tests/test_markdown.py b/zerver/tests/test_markdown.py index a65453b36f..c23661f609 100644 --- a/zerver/tests/test_markdown.py +++ b/zerver/tests/test_markdown.py @@ -12,6 +12,7 @@ from markdown import Markdown from zerver.lib.actions import ( do_add_alert_words, + do_create_realm, do_remove_realm_emoji, do_set_realm_property, do_set_user_display_setting, @@ -47,7 +48,6 @@ from zerver.lib.user_groups import create_user_group from zerver.models import ( MAX_MESSAGE_LENGTH, Message, - Realm, RealmEmoji, RealmFilter, Stream, @@ -472,7 +472,7 @@ class MarkdownTest(ZulipTestCase): clear_state_for_testing() with self.settings(ENABLE_FILE_LINKS=False): - realm = Realm.objects.create(string_id="file_links_test") + realm = do_create_realm(string_id="file_links_test", name="file_links_test") maybe_update_markdown_engines(realm.id, False) converted = markdown_convert(msg, message_realm=realm) self.assertEqual( @@ -2377,7 +2377,9 @@ class MarkdownTest(ZulipTestCase): ) self.assertEqual(converted, expected_output) - realm = Realm.objects.create(string_id="code_block_processor_test") + realm = do_create_realm( + string_id="code_block_processor_test", name="code_block_processor_test" + ) maybe_update_markdown_engines(realm.id, True) converted = markdown_convert(msg, message_realm=realm, email_gateway=True) expected_output = ( diff --git a/zerver/tests/test_message_send.py b/zerver/tests/test_message_send.py index 1b2ecc0153..2fe36edc4d 100644 --- a/zerver/tests/test_message_send.py +++ b/zerver/tests/test_message_send.py @@ -17,6 +17,7 @@ from zerver.lib.actions import ( check_send_stream_message, do_change_can_forge_sender, do_change_stream_post_policy, + do_create_realm, do_create_user, do_deactivate_user, do_send_messages, @@ -2114,7 +2115,8 @@ class InternalPrepTest(ZulipTestCase): class TestCrossRealmPMs(ZulipTestCase): def make_realm(self, domain: str) -> Realm: - realm = Realm.objects.create(string_id=domain, invite_required=False) + realm = do_create_realm(string_id=domain, name=domain) + do_set_realm_property(realm, "invite_required", False) RealmDomain.objects.create(realm=realm, domain=domain) return realm diff --git a/zerver/tests/test_retention.py b/zerver/tests/test_retention.py index 40350b7527..cfcd7d53e1 100644 --- a/zerver/tests/test_retention.py +++ b/zerver/tests/test_retention.py @@ -5,7 +5,13 @@ from unittest import mock from django.conf import settings from django.utils.timezone import now as timezone_now -from zerver.lib.actions import do_add_submessage, do_delete_messages, internal_send_private_message +from zerver.lib.actions import ( + do_add_submessage, + do_create_realm, + do_delete_messages, + do_set_realm_property, + internal_send_private_message, +) from zerver.lib.retention import ( archive_messages, clean_archived_data, @@ -946,11 +952,19 @@ class TestGetRealmAndStreamsForArchiving(ZulipTestCase): archiving_enabled_zephyr_stream.message_retention_days = 1 archiving_enabled_zephyr_stream.save() - Realm.objects.create( - string_id="no_archiving", invite_required=False, message_retention_days=-1 + no_archiving_realm = do_create_realm(string_id="no_archiving", name="no_archiving") + do_set_realm_property(no_archiving_realm, "invite_required", False) + do_set_realm_property(no_archiving_realm, "message_retention_days", -1) + + # Realm for testing the edge case where it has a default retention policy, + # but all streams disable it. + realm_all_streams_archiving_disabled = do_create_realm( + string_id="with_archiving", name="with_archiving" ) - empty_realm_with_archiving = Realm.objects.create( - string_id="with_archiving", invite_required=False, message_retention_days=1 + do_set_realm_property(realm_all_streams_archiving_disabled, "invite_required", False) + do_set_realm_property(realm_all_streams_archiving_disabled, "message_retention_days", 1) + Stream.objects.filter(realm=realm_all_streams_archiving_disabled).update( + message_retention_days=-1 ) # We construct a list representing how the result of get_realms_and_streams_for_archiving should be. @@ -961,7 +975,7 @@ class TestGetRealmAndStreamsForArchiving(ZulipTestCase): expected_result = [ (zulip_realm, list(Stream.objects.filter(realm=zulip_realm).exclude(id=verona.id))), (zephyr_realm, [archiving_enabled_zephyr_stream]), - (empty_realm_with_archiving, []), + (realm_all_streams_archiving_disabled, []), ] self.fix_ordering_of_result(expected_result) diff --git a/zerver/tests/test_subs.py b/zerver/tests/test_subs.py index c78ac7356a..c8148c3c8a 100644 --- a/zerver/tests/test_subs.py +++ b/zerver/tests/test_subs.py @@ -1380,7 +1380,7 @@ class StreamAdminTest(ZulipTestCase): user_profile = self.example_user("hamlet") self.login_user(user_profile) - other_realm = Realm.objects.create(string_id="other") + other_realm = do_create_realm(string_id="other", name="other") stream = self.make_stream("other_realm_stream", realm=other_realm) result = self.client_delete("/json/streams/" + str(stream.id)) diff --git a/zerver/tests/test_upload.py b/zerver/tests/test_upload.py index 382dda05e0..56bdc9c722 100644 --- a/zerver/tests/test_upload.py +++ b/zerver/tests/test_upload.py @@ -21,6 +21,7 @@ from zerver.lib.actions import ( do_change_icon_source, do_change_logo_source, do_change_plan_type, + do_create_realm, do_delete_old_unclaimed_attachments, do_set_realm_property, internal_send_private_message, @@ -566,7 +567,8 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase): user2_email = "test-og-bot@zulip.com" user3_email = "other-user@uploadtest.example.com" - r1 = Realm.objects.create(string_id=test_subdomain, invite_required=False) + r1 = do_create_realm(string_id=test_subdomain, name=test_subdomain) + do_set_realm_property(r1, "invite_required", False) RealmDomain.objects.create(realm=r1, domain=test_subdomain) user_1 = create_user(user1_email, test_subdomain) diff --git a/zilencer/management/commands/populate_db.py b/zilencer/management/commands/populate_db.py index 4384226efb..e91ad56aae 100644 --- a/zilencer/management/commands/populate_db.py +++ b/zilencer/management/commands/populate_db.py @@ -872,8 +872,13 @@ def generate_and_send_messages( random.shuffle(dialog) texts = itertools.cycle(dialog) + # 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 + # our message generation mechanism below. + stream_ids = Stream.objects.filter(realm=get_realm("zulip")).values_list("id", flat=True) recipient_streams: List[int] = [ - klass.id for klass in Recipient.objects.filter(type=Recipient.STREAM) + recipient.id + for recipient in Recipient.objects.filter(type=Recipient.STREAM, type_id__in=stream_ids) ] recipient_huddles: List[int] = [h.id for h in Recipient.objects.filter(type=Recipient.HUDDLE)]