folders: Don't allow archiving a folder if it contains channels.

This commit is contained in:
Sahil Batra
2025-05-21 15:09:51 +05:30
committed by Tim Abbott
parent 677390d3f6
commit d8ae21a4f4
3 changed files with 41 additions and 2 deletions

View File

@@ -7,7 +7,7 @@ from zerver.lib.markdown import markdown_convert
from zerver.lib.streams import get_web_public_streams_queryset
from zerver.lib.string_validation import check_string_is_printable
from zerver.lib.timestamp import datetime_to_timestamp
from zerver.models import ChannelFolder, Realm, UserProfile
from zerver.models import ChannelFolder, Realm, Stream, UserProfile
class ChannelFolderDict(TypedDict):
@@ -81,3 +81,9 @@ def get_channel_folders_for_spectators(realm: Realm) -> list[ChannelFolderDict]:
folders = ChannelFolder.objects.filter(id__in=folder_ids_for_web_public_streams)
channel_folders = [get_channel_folder_dict(channel_folder) for channel_folder in folders]
return sorted(channel_folders, key=lambda folder: folder["id"])
def check_channel_folder_in_use(channel_folder: ChannelFolder) -> bool:
if Stream.objects.filter(folder=channel_folder).exists():
return True
return False

View File

@@ -3,9 +3,11 @@ from typing import Any
import orjson
from zerver.actions.channel_folders import check_add_channel_folder
from zerver.actions.streams import do_change_stream_folder, do_deactivate_stream
from zerver.lib.test_classes import ZulipTestCase
from zerver.models import ChannelFolder
from zerver.models.realms import get_realm
from zerver.models.streams import get_stream
class ChannelFolderCreationTest(ZulipTestCase):
@@ -260,8 +262,10 @@ class UpdateChannelFoldersTest(ZulipTestCase):
self.assertEqual(channel_folder.rendered_description, "")
def test_archiving_and_unarchiving_channel_folder(self) -> None:
desdemona = self.example_user("desdemona")
realm = get_realm("zulip")
channel_folder = check_add_channel_folder(
get_realm("zulip"),
realm,
"Frontend",
"Channels for frontend discussions",
acting_user=self.example_user("desdemona"),
@@ -290,3 +294,24 @@ class UpdateChannelFoldersTest(ZulipTestCase):
self.assert_json_success(result)
channel_folder = ChannelFolder.objects.get(id=channel_folder_id)
self.assertFalse(channel_folder.is_archived)
# Folder containing channels cannot be archived.
stream = get_stream("Verona", realm)
do_change_stream_folder(stream, channel_folder, acting_user=desdemona)
params = {"is_archived": orjson.dumps(True).decode()}
result = self.client_patch(f"/json/channel_folders/{channel_folder_id}", params)
self.assert_json_error(
result, "You need to remove all the channels from this folder to archive it."
)
do_deactivate_stream(stream, acting_user=desdemona)
result = self.client_patch(f"/json/channel_folders/{channel_folder_id}", params)
self.assert_json_error(
result, "You need to remove all the channels from this folder to archive it."
)
do_change_stream_folder(stream, None, acting_user=desdemona)
result = self.client_patch(f"/json/channel_folders/{channel_folder_id}", params)
self.assert_json_success(result)
channel_folder = ChannelFolder.objects.get(id=channel_folder_id)
self.assertTrue(channel_folder.is_archived)

View File

@@ -1,6 +1,7 @@
from typing import Annotated
from django.http import HttpRequest, HttpResponse
from django.utils.translation import gettext as _
from pydantic import Json, StringConstraints
from zerver.actions.channel_folders import (
@@ -12,10 +13,12 @@ from zerver.actions.channel_folders import (
)
from zerver.decorator import require_realm_admin
from zerver.lib.channel_folders import (
check_channel_folder_in_use,
check_channel_folder_name,
get_channel_folder_by_id,
get_channel_folders_in_realm,
)
from zerver.lib.exceptions import JsonableError
from zerver.lib.response import json_success
from zerver.lib.typed_endpoint import PathOnly, typed_endpoint
from zerver.models.channel_folders import ChannelFolder
@@ -71,6 +74,11 @@ def update_channel_folder(
if is_archived is not None and channel_folder.is_archived != is_archived:
if is_archived:
if check_channel_folder_in_use(channel_folder):
raise JsonableError(
_("You need to remove all the channels from this folder to archive it.")
)
do_archive_channel_folder(channel_folder, acting_user=user_profile)
else:
do_unarchive_channel_folder(channel_folder, acting_user=user_profile)