diff --git a/tools/lib/capitalization.py b/tools/lib/capitalization.py index fd38834d60..4188a6712d 100644 --- a/tools/lib/capitalization.py +++ b/tools/lib/capitalization.py @@ -105,6 +105,12 @@ IGNORED_PHRASES = [ r"^new channels$", r"^channel events$", r"^general$", + r"^sandbox$", + r"^experiments$", + r"^greetings$", + r"^moving messages$", + r"^start a conversation$", + r"^welcome to Zulip!$", # These are used as example short names (e.g. an uncapitalized context): r"^marketing$", r"^cookie$", diff --git a/web/e2e-tests/message-basics.test.ts b/web/e2e-tests/message-basics.test.ts index 8e19a06503..7d4914ede2 100644 --- a/web/e2e-tests/message-basics.test.ts +++ b/web/e2e-tests/message-basics.test.ts @@ -375,21 +375,28 @@ async function test_stream_search_filters_stream_list(page: Page): Promise await page.waitForSelector((await get_stream_li(page, "Denmark")) + ".highlighted_stream", { hidden: true, }); + await page.waitForSelector((await get_stream_li(page, "sandbox")) + ".highlighted_stream", { + hidden: true, + }); await page.waitForSelector((await get_stream_li(page, "Venice")) + ".highlighted_stream", { hidden: true, }); await page.waitForSelector((await get_stream_li(page, "Verona")) + ".highlighted_stream", { hidden: true, }); + await page.waitForSelector((await get_stream_li(page, "Zulip")) + ".highlighted_stream", { + hidden: true, + }); // Navigate through suggestions using arrow keys await arrow(page, "Down"); // core team -> Denmark - await arrow(page, "Down"); // Denmark -> Venice - await arrow(page, "Up"); // Venice -> Denmark + await arrow(page, "Down"); // Denmark -> sandbox + await arrow(page, "Up"); // sandbox -> Denmark await arrow(page, "Up"); // Denmark -> core team await arrow(page, "Up"); // core team -> core team await arrow(page, "Down"); // core team -> Denmark - await arrow(page, "Down"); // Denmark -> Venice + await arrow(page, "Down"); // Denmark -> sandbox + await arrow(page, "Down"); // sandbox-> Venice await arrow(page, "Down"); // Venice -> Verona await page.waitForSelector((await get_stream_li(page, "Verona")) + ".highlighted_stream", { @@ -405,6 +412,9 @@ async function test_stream_search_filters_stream_list(page: Page): Promise await page.waitForSelector((await get_stream_li(page, "Venice")) + ".highlighted_stream", { hidden: true, }); + await page.waitForSelector((await get_stream_li(page, "Zulip")) + ".highlighted_stream", { + hidden: true, + }); await test_search_venice(page); // Search for beginning of "Verona". diff --git a/zerver/actions/create_realm.py b/zerver/actions/create_realm.py index 8f1f6fee31..32ca3c8465 100644 --- a/zerver/actions/create_realm.py +++ b/zerver/actions/create_realm.py @@ -278,20 +278,37 @@ def do_create_realm( maybe_enqueue_audit_log_upload(realm) - # Create stream once Realm object has been saved + # Create channels once Realm object has been saved + zulip_discussion_channel = ensure_stream( + realm, + str(Realm.ZULIP_DISCUSSION_CHANNEL_NAME), + stream_description=_("Questions and discussion about using Zulip."), + acting_user=None, + ) + zulip_sandbox_channel = ensure_stream( + realm, + str(Realm.ZULIP_SANDBOX_CHANNEL_NAME), + stream_description=_("Experiment with Zulip here. :test_tube:"), + acting_user=None, + ) new_stream_announcements_stream = ensure_stream( realm, str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), - stream_description="Everyone is added to this stream by default. Welcome! :octopus:", + stream_description=_("For team-wide conversations"), acting_user=None, ) # By default, 'New stream' & 'Zulip update' announcements are sent to the same stream. realm.new_stream_announcements_stream = new_stream_announcements_stream realm.zulip_update_announcements_stream = new_stream_announcements_stream - # With the current initial streams situation, the only public - # stream is the new_stream_announcements_stream. - DefaultStream.objects.create(stream=new_stream_announcements_stream, realm=realm) + # With the current initial streams situation, the public channels are + # 'zulip_discussion_channel', 'zulip_sandbox_channel', 'new_stream_announcements_stream'. + public_channels = [ + DefaultStream(stream=zulip_discussion_channel, realm=realm), + DefaultStream(stream=zulip_sandbox_channel, realm=realm), + DefaultStream(stream=new_stream_announcements_stream, realm=realm), + ] + DefaultStream.objects.bulk_create(public_channels) # New realm is initialized with the latest zulip update announcements # level as it shouldn't receive a bunch of old updates. diff --git a/zerver/lib/onboarding.py b/zerver/lib/onboarding.py index b40dba0707..fceadae948 100644 --- a/zerver/lib/onboarding.py +++ b/zerver/lib/onboarding.py @@ -263,45 +263,119 @@ def send_welcome_bot_response(send_request: SendMessageRequest) -> None: @transaction.atomic def send_initial_realm_messages(realm: Realm) -> None: + # Sends the initial messages for a new organization. + # + # Technical note: Each stream created in the realm creation + # process should have at least one message declared in this + # function, to enforce the pseudo-invariant that every stream has + # at least one message. welcome_bot = get_system_bot(settings.WELCOME_BOT, realm.id) - # Make sure each stream created in the realm creation process has at least one message below - # Order corresponds to the ordering of the streams on the left sidebar, to make the initial Home - # view slightly less overwhelming + with override_language(realm.default_language): - content1_of_topic_demonstration_topic_name = ( - _( - "This is a message on channel #**{default_notification_channel_name}** with the " - "topic `topic demonstration`." + # Content is declared here to apply translation properly. + # + # remove_single_newlines needs to be called on any multiline + # strings for them to render properly. + content1_of_moving_messages_topic_name = remove_single_newlines( + ( + _(""" +If anything is out of place, it’s easy to [move messages]({move_content_another_topic_help_url}), +[rename]({rename_topic_help_url}) and [split]({move_content_another_topic_help_url}) topics, +or even move a topic [to a different channel]({move_content_another_channel_help_url}). +""") + ).format( + move_content_another_topic_help_url="/help/move-content-to-another-topic", + rename_topic_help_url="/help/rename-a-topic", + move_content_another_channel_help_url="/help/move-content-to-another-channel", ) - ).format(default_notification_channel_name=str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME)) - - content2_of_topic_demonstration_topic_name = ( - _("Topics are a lightweight tool to keep conversations organized.") - + " " - + _( - "You can learn more about topics at [Introduction to topics]({about_topics_help_url})." - ) - ).format(about_topics_help_url="/help/introduction-to-topics") - - content_of_swimming_turtles_topic_name = ( - _( - "This is a message on channel #**{default_notification_channel_name}** with the " - "topic `swimming turtles`." - ) - + "\n" - "\n" - "[](/static/images/cute/turtle.png)" - "\n" - "\n" - + _( - "[Start a new topic]({start_topic_help_url}) any time you're not replying to a \ - previous message." - ) - ).format( - default_notification_channel_name=str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), - start_topic_help_url="/help/introduction-to-topics#how-to-start-a-new-topic", ) + content2_of_moving_messages_topic_name = _(""" +:point_right: Try moving this message to another topic and back! +""") + + content1_of_welcome_to_zulip_topic_name = _(""" +Zulip is organized to help you communicate more efficiently. +""") + + content2_of_welcome_to_zulip_topic_name = remove_single_newlines( + ( + _(""" +In Zulip, **channels** determine who gets a message. + +Each conversation in a channel is labeled with a **topic**. This message is in +the #**{zulip_discussion_channel_name}** channel, in the "{topic_name}" topic, as you can +see in the left sidebar and above. +""") + ).format( + zulip_discussion_channel_name=str(Realm.ZULIP_DISCUSSION_CHANNEL_NAME), + topic_name=_("welcome to Zulip!"), + ) + ) + + content3_of_welcome_to_zulip_topic_name = remove_single_newlines( + _(""" +You can read Zulip one conversation at a time, seeing each message in context, +no matter how many other conversations are going on. +""") + ) + + content4_of_welcome_to_zulip_topic_name = remove_single_newlines( + _(""" +:point_right: When you're ready, check out your [Inbox](/#inbox) for other +conversations with unread messages. You can come back to this conversation +if you need to from your **Starred** messages. +""") + ) + + content1_of_start_conversation_topic_name = remove_single_newlines( + _(""" +To kick off a new conversation, click **Start new conversation** below. +The new conversation thread won’t interrupt ongoing discussions. +""") + ) + + content2_of_start_conversation_topic_name = _(""" +For a good topic name, think about finishing the sentence: “Hey, can we chat about…?” +""") + + content3_of_start_conversation_topic_name = _(""" +:point_right: Try starting a new conversation in this channel. +""") + + content1_of_experiments_topic_name = ( + _(""" +:point_right: Use this topic to try out [Zulip's messaging features]({format_message_help_url}). +""") + ).format(format_message_help_url="/help/format-your-message-using-markdown") + + content2_of_experiments_topic_name = ( + _(""" +```spoiler Want to see some examples? + +````python +print("code blocks") +```` + +- bulleted +- lists + +Link to a conversation: #**{zulip_discussion_channel_name}>{topic_name}** +``` +""") + ).format( + zulip_discussion_channel_name=str(Realm.ZULIP_DISCUSSION_CHANNEL_NAME), + topic_name=_("welcome to Zulip!"), + ) + + content1_of_greetings_topic_name = _(""" +This **greetings** topic is a great place to say "hi" :wave: to your teammates. +""") + + content2_of_greetings_topic_name = _(""" +:point_right: Click on any message to start a reply in the same topic. +""") + content_of_zulip_update_announcements_topic_name = remove_single_newlines( ( _(""" @@ -319,34 +393,94 @@ they can be disabled. [Learn more]({zulip_update_announcements_help_url}). ) ) - welcome_messages: List[Dict[str, str]] = [ + welcome_messages: List[Dict[str, str]] = [] + + # Messages added to the "welcome messages" list last will be most + # visible to users, since welcome messages will likely be browsed + # via the right sidebar or recent conversations view, both of + # which are sorted newest-first. + # + # Initial messages are configured below. + + # Zulip updates system advertisement. + welcome_messages += [ { - "stream": str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), - "topic_name": "topic demonstration", - "content": content1_of_topic_demonstration_topic_name, - }, - { - "stream": str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), - "topic_name": "topic demonstration", - "content": content2_of_topic_demonstration_topic_name, - }, - { - "stream": str(realm.DEFAULT_NOTIFICATION_STREAM_NAME), - "topic_name": "swimming turtles", - "content": content_of_swimming_turtles_topic_name, - }, - { - "stream": str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), + "channel_name": str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), "topic_name": str(Realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME), "content": content_of_zulip_update_announcements_topic_name, }, ] + # Advertising moving messages. + welcome_messages += [ + { + "channel_name": str(Realm.ZULIP_DISCUSSION_CHANNEL_NAME), + "topic_name": _("moving messages"), + "content": content, + } + for content in [ + content1_of_moving_messages_topic_name, + content2_of_moving_messages_topic_name, + ] + ] + + # Suggestion to start your first new conversation. + welcome_messages += [ + { + "channel_name": str(realm.ZULIP_SANDBOX_CHANNEL_NAME), + "topic_name": _("start a conversation"), + "content": content, + } + for content in [ + content1_of_start_conversation_topic_name, + content2_of_start_conversation_topic_name, + content3_of_start_conversation_topic_name, + ] + ] + + # Suggestion to test messaging features. + # Dependency on knowing how to send messages. + welcome_messages += [ + { + "channel_name": str(realm.ZULIP_SANDBOX_CHANNEL_NAME), + "topic_name": _("experiments"), + "content": content, + } + for content in [content1_of_experiments_topic_name, content2_of_experiments_topic_name] + ] + + # Suggestion to send first message as a hi to your team. + welcome_messages += [ + { + "channel_name": str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), + "topic_name": _("greetings"), + "content": content, + } + for content in [content1_of_greetings_topic_name, content2_of_greetings_topic_name] + ] + + # Main welcome message, this should be last. + welcome_messages += [ + { + "channel_name": str(realm.ZULIP_DISCUSSION_CHANNEL_NAME), + "topic_name": _("welcome to Zulip!"), + "content": content, + } + for content in [ + content1_of_welcome_to_zulip_topic_name, + content2_of_welcome_to_zulip_topic_name, + content3_of_welcome_to_zulip_topic_name, + content4_of_welcome_to_zulip_topic_name, + ] + ] + + # End of message declarations; now we actually send them. + messages = [ internal_prep_stream_message_by_name( realm, welcome_bot, - message["stream"], + message["channel_name"], message["topic_name"], message["content"], ) @@ -356,13 +490,15 @@ they can be disabled. [Learn more]({zulip_update_announcements_help_url}). sent_message_result.message_id for sent_message_result in do_send_messages(messages) ] - # We find the one of our just-sent messages with turtle.png in it, - # and react to it. This is a bit hacky, but works and is kinda a - # 1-off thing. - turtle_message = Message.objects.select_for_update().get( - id__in=message_ids, content__icontains="cute/turtle.png" + # We find the one of our just-sent greetings messages, and react to it. + # This is a bit hacky, but works and is kinda a 1-off thing. + greetings_message = ( + Message.objects.select_for_update() + .filter(id__in=message_ids, content__icontains='a great place to say "hi"') + .first() ) - emoji_data = get_emoji_data(realm.id, "turtle") + assert greetings_message is not None + emoji_data = get_emoji_data(realm.id, "wave") do_add_reaction( - welcome_bot, turtle_message, "turtle", emoji_data.emoji_code, emoji_data.reaction_type + welcome_bot, greetings_message, "wave", emoji_data.emoji_code, emoji_data.reaction_type ) diff --git a/zerver/models/realms.py b/zerver/models/realms.py index 8d1ee974b8..b9de2250c5 100644 --- a/zerver/models/realms.py +++ b/zerver/models/realms.py @@ -333,6 +333,8 @@ class Realm(models.Model): # type: ignore[django-manager-missing] # django-stub # Defaults for new users default_language = models.CharField(default="en", max_length=MAX_LANGUAGE_ID_LENGTH) + ZULIP_DISCUSSION_CHANNEL_NAME = gettext_lazy("Zulip") + ZULIP_SANDBOX_CHANNEL_NAME = gettext_lazy("sandbox") DEFAULT_NOTIFICATION_STREAM_NAME = gettext_lazy("general") STREAM_EVENTS_NOTIFICATION_TOPIC_NAME = gettext_lazy("channel events") new_stream_announcements_stream = models.ForeignKey( diff --git a/zerver/openapi/python_examples.py b/zerver/openapi/python_examples.py index 86ebf01eca..1ac3a2817c 100644 --- a/zerver/openapi/python_examples.py +++ b/zerver/openapi/python_examples.py @@ -161,7 +161,7 @@ def get_presence(client: Client) -> None: def add_default_stream(client: Client) -> None: # {code_example|start} # Add a stream to the set of default streams for new users. - stream_id = 4 + stream_id = 10 result = client.add_default_stream(stream_id) # {code_example|end} @@ -173,7 +173,7 @@ def add_default_stream(client: Client) -> None: def remove_default_stream(client: Client) -> None: # {code_example|start} # Remove a stream from the set of default streams for new users. - request = {"stream_id": 4} + request = {"stream_id": 10} result = client.call_endpoint( url="/default_streams", @@ -321,7 +321,7 @@ def send_invitations(client: Client) -> None: "invitee_emails": "example@zulip.com, logan@zulip.com", "invite_expires_in_minutes": 60 * 24 * 10, # 10 days "invite_as": 400, - "stream_ids": [1, 5, 6], + "stream_ids": [1, 11, 12], } result = client.call_endpoint(url="/invites", method="POST", request=request) # {code_example|end} @@ -336,7 +336,7 @@ def create_reusable_invitation_link(client: Client) -> None: request = { "invite_expires_in_minutes": 60 * 24 * 10, # 10 days "invite_as": 400, - "stream_ids": [1, 5, 6], + "stream_ids": [1, 11, 12], } result = client.call_endpoint(url="/invites/multiuse", method="POST", request=request) # {code_example|end} @@ -350,7 +350,7 @@ def revoke_email_invitation(client: Client) -> None: "invitee_emails": "delete-invite@zulip.com", "invite_expires_in_minutes": 14400, # 10 days "invite_as": 400, - "stream_ids": [1, 5, 6], + "stream_ids": [1, 11, 12], } result = client.call_endpoint(url="/invites", method="POST", request=request) @@ -668,7 +668,7 @@ def get_streams(client: Client) -> None: # {code_example|end} validate_against_openapi_schema(result, "/streams", "get", "200") - assert len(result["streams"]) == 5 + assert len(result["streams"]) == 7 @openapi_test_function("/streams/{stream_id}:patch") @@ -915,7 +915,7 @@ def update_subscription_settings(client: Client) -> None: "value": True, }, { - "stream_id": 4, + "stream_id": 10, "property": "color", "value": "#f00f00", }, diff --git a/zerver/openapi/zulip.yaml b/zerver/openapi/zulip.yaml index 1c020cefa7..17740e9853 100644 --- a/zerver/openapi/zulip.yaml +++ b/zerver/openapi/zulip.yaml @@ -5879,7 +5879,7 @@ paths: items: type: integer minLength: 1 - example: 5 + example: 11 content: description: | The updated content of the scheduled message. @@ -6022,7 +6022,7 @@ paths: description: | The ID of the target stream. type: integer - example: 4 + example: 10 required: - stream_id encoding: @@ -6073,7 +6073,7 @@ paths: description: | The ID of the target stream. type: integer - example: 4 + example: 10 required: - stream_id encoding: @@ -11977,7 +11977,7 @@ paths: type: array items: type: integer - example: [1, 4] + example: [1, 10] required: - invitee_emails - stream_ids @@ -12115,7 +12115,7 @@ paths: items: type: integer default: [] - example: [1, 4] + example: [1, 10] encoding: invite_expires_in_minutes: contentType: application/json diff --git a/zerver/tests/test_audit_log.py b/zerver/tests/test_audit_log.py index cc34a43022..8ad8377110 100644 --- a/zerver/tests/test_audit_log.py +++ b/zerver/tests/test_audit_log.py @@ -113,7 +113,7 @@ class TestRealmAuditLog(ZulipTestCase): do_activate_mirror_dummy_user(user, acting_user=user) do_deactivate_user(user, acting_user=user) do_reactivate_user(user, acting_user=user) - self.assertEqual(RealmAuditLog.objects.filter(event_time__gte=now).count(), 8) + self.assertEqual(RealmAuditLog.objects.filter(event_time__gte=now).count(), 10) event_types = list( RealmAuditLog.objects.filter( realm=realm, diff --git a/zerver/tests/test_digest.py b/zerver/tests/test_digest.py index d7e9857517..9a81b77104 100644 --- a/zerver/tests/test_digest.py +++ b/zerver/tests/test_digest.py @@ -82,10 +82,10 @@ class TestDigestEmailMessages(ZulipTestCase): # are 3 reused streams and one new one, for a net of two fewer # than before. iago = self.example_user("iago") - with self.assert_database_query_count(8): + with self.assert_database_query_count(10): bulk_handle_digest_email([iago.id], cutoff) self.assertEqual(get_recent_topics.cache_info().hits, 3) - self.assertEqual(get_recent_topics.cache_info().currsize, 4) + self.assertEqual(get_recent_topics.cache_info().currsize, 6) # Two users in the same batch, with only one new stream from # the above. @@ -94,7 +94,7 @@ class TestDigestEmailMessages(ZulipTestCase): with self.assert_database_query_count(9): bulk_handle_digest_email([cordelia.id, prospero.id], cutoff) self.assertEqual(get_recent_topics.cache_info().hits, 7) - self.assertEqual(get_recent_topics.cache_info().currsize, 5) + self.assertEqual(get_recent_topics.cache_info().currsize, 7) # If we use a different cutoff, it clears the cache. with self.assert_database_query_count(12): @@ -241,7 +241,7 @@ class TestDigestEmailMessages(ZulipTestCase): digest_user_ids = [user.id for user in digest_users] get_recent_topics.cache_clear() - with self.assert_database_query_count(14): + with self.assert_database_query_count(16): with self.assert_memcached_count(0): bulk_handle_digest_email(digest_user_ids, cutoff) diff --git a/zerver/tests/test_import_export.py b/zerver/tests/test_import_export.py index 1e154e4318..b94b6077bb 100644 --- a/zerver/tests/test_import_export.py +++ b/zerver/tests/test_import_export.py @@ -448,7 +448,16 @@ class RealmImportExportTest(ExportFile): exported_streams = self.get_set(data["zerver_stream"], "name") self.assertEqual( exported_streams, - {"Denmark", "Rome", "Scotland", "Venice", "Verona", "core team"}, + { + "Denmark", + "Rome", + "Scotland", + "Venice", + "Verona", + "core team", + "Zulip", + "sandbox", + }, ) exported_alert_words = data["zerver_alertword"] @@ -648,6 +657,8 @@ class RealmImportExportTest(ExportFile): "Scotland", "Venice", "Verona", + "Zulip", + "sandbox", "Private A", "Private B", "Private C", @@ -668,7 +679,15 @@ class RealmImportExportTest(ExportFile): exported_message = self.find_by_id(data["zerver_message"], um.message_id) self.assertEqual(exported_message["content"], um.message.content) - public_stream_names = ["Denmark", "Rome", "Scotland", "Venice", "Verona"] + public_stream_names = [ + "Denmark", + "Rome", + "Scotland", + "Venice", + "Verona", + "Zulip", + "sandbox", + ] public_stream_ids = Stream.objects.filter(name__in=public_stream_names).values_list( "id", flat=True ) diff --git a/zerver/tests/test_invite.py b/zerver/tests/test_invite.py index 65e952b110..a1ee93afaa 100644 --- a/zerver/tests/test_invite.py +++ b/zerver/tests/test_invite.py @@ -793,7 +793,7 @@ class InviteUserTest(InviteUserBase): self.assertTrue(find_key_by_email(invitee)) default_streams = get_default_streams_for_realm_as_dicts(realm.id) - self.assert_length(default_streams, 1) + self.assert_length(default_streams, 3) self.submit_reg_form_for_user(invitee, "password") # If no streams are provided, user is not subscribed to @@ -2409,7 +2409,7 @@ class MultiuseInviteTest(ZulipTestCase): invite_link = self.generate_multiuse_invite_link(streams=streams) self.check_user_able_to_register(email3, invite_link) # User is not subscribed to default streams as well. - self.assert_length(get_default_streams_for_realm_as_dicts(self.realm.id), 1) + self.assert_length(get_default_streams_for_realm_as_dicts(self.realm.id), 3) self.check_user_subscribed_only_to_streams(name3, []) def test_multiuse_link_different_realms(self) -> None: @@ -2478,7 +2478,7 @@ class MultiuseInviteTest(ZulipTestCase): invite_link = self.assert_json_success(result)["invite_link"] self.check_user_able_to_register(self.nonreg_email("alice"), invite_link) # User is not subscribed to default streams as well. - self.assert_length(get_default_streams_for_realm_as_dicts(self.realm.id), 1) + self.assert_length(get_default_streams_for_realm_as_dicts(self.realm.id), 3) self.check_user_subscribed_only_to_streams("alice", []) def test_multiuse_invite_without_permission_to_subscribe_others(self) -> None: diff --git a/zerver/tests/test_signup.py b/zerver/tests/test_signup.py index 89aefa1db4..a705e399d4 100644 --- a/zerver/tests/test_signup.py +++ b/zerver/tests/test_signup.py @@ -1303,7 +1303,8 @@ class RealmCreationTest(ZulipTestCase): # Check welcome messages for stream_name, text, message_count in [ - (str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), "with the topic", 4), + (str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), "learn about new features", 3), + (str(Realm.ZULIP_SANDBOX_CHANNEL_NAME), "new conversation thread", 5), ]: stream = get_stream(stream_name, realm) recipient = stream.recipient @@ -1739,10 +1740,12 @@ class RealmCreationTest(ZulipTestCase): # TODO: When Italian translated strings are updated for changes # that are part of the stream -> channel rename, uncomment below. # # Check welcome messages - # with_the_topic_in_italian = "con l'argomento" + # learn_about_new_features_in_italian = "conoscere le nuove funzionalità" + # new_conversation_thread_in_italian = "nuovo thread di conversazione" # for stream_name, text, message_count in [ - # (str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), with_the_topic_in_italian, 4), + # (str(Realm.DEFAULT_NOTIFICATION_STREAM_NAME), learn_about_new_features_in_italian, 3), + # (str(Realm.ZULIP_SANDBOX_CHANNEL_NAME), new_conversation_thread_in_italian, 5), # ]: # stream = get_stream(stream_name, realm) # recipient = stream.recipient @@ -2560,9 +2563,11 @@ class UserSignUpTest(ZulipTestCase): default_streams = [] existing_default_streams = DefaultStream.objects.filter(realm=realm) - self.assert_length(existing_default_streams, 1) - self.assertEqual(existing_default_streams[0].stream.name, "Verona") - default_streams.append(existing_default_streams[0].stream) + self.assert_length(existing_default_streams, 3) + expected_default_streams = ["Zulip", "sandbox", "Verona"] + for i, expected_default_stream in enumerate(expected_default_streams): + self.assertEqual(existing_default_streams[i].stream.name, expected_default_stream) + default_streams.append(existing_default_streams[i].stream) for stream_name in ["venice", "rome"]: stream = get_stream(stream_name, realm) diff --git a/zerver/tests/test_subs.py b/zerver/tests/test_subs.py index 5356246748..d1c20b4856 100644 --- a/zerver/tests/test_subs.py +++ b/zerver/tests/test_subs.py @@ -5633,7 +5633,16 @@ class GetStreamsTest(ZulipTestCase): self.assertEqual( stream_names, - {"Venice", "Denmark", "Scotland", "Verona", "Rome", "core team"}, + { + "Venice", + "Denmark", + "Scotland", + "Verona", + "Rome", + "core team", + "Zulip", + "sandbox", + }, ) def test_public_streams_api(self) -> None: diff --git a/zerver/tests/test_users.py b/zerver/tests/test_users.py index f94a9beda4..3485ec8b6e 100644 --- a/zerver/tests/test_users.py +++ b/zerver/tests/test_users.py @@ -622,9 +622,9 @@ class PermissionTest(ZulipTestCase): if new_role in [UserProfile.ROLE_REALM_ADMINISTRATOR, UserProfile.ROLE_REALM_OWNER]: # If the new role is owner or admin, the peer_add event will be # sent for one private stream as well. - num_events += 5 + num_events += 7 else: - num_events += 4 + num_events += 6 elif new_role in [ UserProfile.ROLE_REALM_ADMINISTRATOR, UserProfile.ROLE_REALM_OWNER, diff --git a/zilencer/management/commands/populate_db.py b/zilencer/management/commands/populate_db.py index 2f5d5f718b..6d0c87ebd1 100644 --- a/zilencer/management/commands/populate_db.py +++ b/zilencer/management/commands/populate_db.py @@ -622,6 +622,9 @@ class Command(BaseCommand): create_if_missing_realm_internal_bots() # Create streams. + zulip_discussion_channel_name = str(Realm.ZULIP_DISCUSSION_CHANNEL_NAME) + zulip_sandbox_channel_name = str(Realm.ZULIP_SANDBOX_CHANNEL_NAME) + stream_list = [ "Verona", "Denmark", @@ -629,6 +632,8 @@ class Command(BaseCommand): "Venice", "Rome", "core team", + zulip_discussion_channel_name, + zulip_sandbox_channel_name, ] stream_dict: Dict[str, Dict[str, Any]] = { "Denmark": {"description": "A Scandinavian country"}, @@ -662,12 +667,20 @@ class Command(BaseCommand): subscriptions_map = { "AARON@zulip.com": ["Verona"], "cordelia@zulip.com": ["Verona"], - "hamlet@zulip.com": ["Verona", "Denmark", "core team"], + "hamlet@zulip.com": [ + "Verona", + "Denmark", + "core team", + zulip_discussion_channel_name, + zulip_sandbox_channel_name, + ], "iago@zulip.com": [ "Verona", "Denmark", "Scotland", "core team", + zulip_discussion_channel_name, + zulip_sandbox_channel_name, ], "othello@zulip.com": ["Verona", "Denmark", "Scotland"], "prospero@zulip.com": ["Verona", "Denmark", "Scotland", "Venice"], @@ -678,6 +691,8 @@ class Command(BaseCommand): "Denmark", "Venice", "core team", + zulip_discussion_channel_name, + zulip_sandbox_channel_name, ], "shiva@zulip.com": ["Verona", "Denmark", "Scotland"], }