channel-folders: Update unique name constraint.

This commit updates code to require unique names for only
non-archived folders in a realm, which means a folder can
use a name which is being used by an archived folder.
This commit is contained in:
Sahil Batra
2025-07-29 15:28:16 +05:30
committed by Tim Abbott
parent e70d8c7a80
commit 072516c2bb
4 changed files with 46 additions and 3 deletions

View File

@@ -32,7 +32,7 @@ def check_channel_folder_name(name: str, realm: Realm) -> None:
)
)
if ChannelFolder.objects.filter(name__iexact=name, realm=realm).exists():
if ChannelFolder.objects.filter(name__iexact=name, realm=realm, is_archived=False).exists():
raise JsonableError(_("Channel folder name already in use"))

View File

@@ -0,0 +1,26 @@
# Generated by Django 5.2.4 on 2025-07-29 09:55
import django.db.models.functions.text
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("zerver", "0745_usersetting_web_left_sidebar_show_channel_folders"),
]
operations = [
migrations.AlterUniqueTogether(
name="channelfolder",
unique_together=set(),
),
migrations.AddConstraint(
model_name="channelfolder",
constraint=models.UniqueConstraint(
django.db.models.functions.text.Lower("name"),
models.F("realm"),
condition=models.Q(("is_archived", False)),
name="unique_realm_folder_name_when_not_archived",
),
),
]

View File

@@ -1,4 +1,6 @@
from django.db import models
from django.db.models import Q
from django.db.models.functions import Lower
from django.utils.timezone import now as timezone_now
from zerver.models.realms import Realm
@@ -19,4 +21,11 @@ class ChannelFolder(models.Model):
is_archived = models.BooleanField(default=False)
class Meta:
unique_together = ("realm", "name")
constraints = [
models.UniqueConstraint(
Lower("name"),
"realm",
condition=Q(is_archived=False),
name="unique_realm_folder_name_when_not_archived",
),
]

View File

@@ -2,7 +2,7 @@ from typing import Any
import orjson
from zerver.actions.channel_folders import check_add_channel_folder
from zerver.actions.channel_folders import check_add_channel_folder, do_archive_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
@@ -41,6 +41,14 @@ class ChannelFolderCreationTest(ZulipTestCase):
result = self.client_post("/json/channel_folders/create", params)
self.assert_json_error(result, "Channel folder name already in use")
# Archived folder names can be reused.
folder = ChannelFolder.objects.get(name="Frontend", realm=realm)
do_archive_channel_folder(folder, acting_user=self.example_user("iago"))
result = self.client_post("/json/channel_folders/create", params)
self.assert_json_success(result)
self.assertTrue(ChannelFolder.objects.filter(realm=realm, name="Frontend").exists())
# Folder names should be unique case-insensitively.
params["name"] = "frontEND"
result = self.client_post("/json/channel_folders/create", params)