diff --git a/frontend/pages/admin/manage/groups/_id.vue b/frontend/pages/admin/manage/groups/_id.vue index 98afca06d..7afa27235 100644 --- a/frontend/pages/admin/manage/groups/_id.vue +++ b/frontend/pages/admin/manage/groups/_id.vue @@ -74,7 +74,13 @@ export default defineComponent({ const { response, data } = await adminApi.groups.updateOne(group.value.id, group.value); if (response?.status === 200 && data) { + if (group.value.slug !== data.slug) { + // the slug updated, which invalidates the nav URLs + window.location.reload(); + } group.value = data; + } else { + alert.error(i18n.tc("settings.settings-update-failed")); } } diff --git a/mealie/repos/repository_group.py b/mealie/repos/repository_group.py index d153f6749..0d8a2dd06 100644 --- a/mealie/repos/repository_group.py +++ b/mealie/repos/repository_group.py @@ -14,7 +14,7 @@ from mealie.db.models.recipe.tag import Tag from mealie.db.models.recipe.tool import Tool from mealie.db.models.users.users import User from mealie.schema.group.group_statistics import GroupStatistics -from mealie.schema.user.user import GroupBase, GroupInDB +from mealie.schema.user.user import GroupBase, GroupInDB, UpdateGroup from ..db.models._model_base import SqlAlchemyBase from .repository_generic import RepositoryGeneric @@ -45,6 +45,18 @@ class RepositoryGroup(RepositoryGeneric[GroupInDB, Group]): # since create uses special logic for resolving slugs, we don't want to use the standard create_many method return [self.create(new_group) for new_group in data] + def update(self, match_value: str | int | UUID4, new_data: UpdateGroup | dict) -> GroupInDB: + if isinstance(new_data, GroupBase): + new_data.slug = slugify(new_data.name) + else: + new_data["slug"] = slugify(new_data["name"]) + + return super().update(match_value, new_data) + + def update_many(self, data: Iterable[UpdateGroup | dict]) -> list[GroupInDB]: + # since update uses special logic for resolving slugs, we don't want to use the standard update_many method + return [self.update(group["id"] if isinstance(group, dict) else group.id, group) for group in data] + def get_by_name(self, name: str) -> GroupInDB | None: dbgroup = self.session.execute(select(self.model).filter_by(name=name)).scalars().one_or_none() if dbgroup is None: diff --git a/tests/unit_tests/repository_tests/test_group_repository.py b/tests/unit_tests/repository_tests/test_group_repository.py index 2f6c9ffc4..a9252db90 100644 --- a/tests/unit_tests/repository_tests/test_group_repository.py +++ b/tests/unit_tests/repository_tests/test_group_repository.py @@ -1,8 +1,10 @@ +from slugify import slugify + from mealie.repos.repository_factory import AllRepositories from tests.utils.factories import random_int, random_string -def test_group_resolve_similar_names(database: AllRepositories): +def test_create_group_resolve_similar_names(database: AllRepositories): base_group_name = random_string() groups = database.groups.create_many({"name": base_group_name} for _ in range(random_int(3, 10))) @@ -22,3 +24,12 @@ def test_group_get_by_slug_or_id(database: AllRepositories): for group in groups: assert database.groups.get_by_slug_or_id(group.id) == group assert database.groups.get_by_slug_or_id(group.slug) == group + + +def test_update_group_updates_slug(database: AllRepositories): + group = database.groups.create({"name": random_string()}) + assert group.slug == slugify(group.name) + + new_name = random_string() + group = database.groups.update(group.id, {"name": new_name}) + assert group.slug == slugify(new_name)