mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-05-17 15:27:31 -04:00
fix: return HTTP 400 for duplicate tag and label creation (#7638)
Co-authored-by: voidborne-d <voidborne-d@users.noreply.github.com>
This commit is contained in:
@@ -54,7 +54,11 @@ class MultiPurposeLabelsController(BaseCrudController):
|
||||
|
||||
@router.post("", response_model=MultiPurposeLabelOut)
|
||||
def create_one(self, data: MultiPurposeLabelCreate):
|
||||
try:
|
||||
new_label = self.service.create_one(data)
|
||||
except Exception as ex:
|
||||
self.mixins.handle_exception(ex)
|
||||
raise # handle_exception always raises; this satisfies static analysis
|
||||
self.publish_event(
|
||||
event_type=EventTypes.label_created,
|
||||
document_data=EventLabelData(operation=EventOperation.create, label_id=new_label.id),
|
||||
|
||||
@@ -52,7 +52,7 @@ class TagController(BaseCrudController):
|
||||
def create_one(self, tag: TagIn):
|
||||
"""Creates a Tag in the database"""
|
||||
save_data = mapper.cast(tag, TagSave, group_id=self.group_id)
|
||||
new_tag = self.repo.create(save_data)
|
||||
new_tag = self.mixins.create_one(save_data)
|
||||
|
||||
if new_tag:
|
||||
self.publish_event(
|
||||
|
||||
@@ -191,6 +191,24 @@ def test_organizer_association(
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.parametrize("route", organizer_routes, ids=test_ids)
|
||||
def test_organizer_create_duplicate_name_returns_400(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
route: RoutesBase,
|
||||
):
|
||||
# Regression test for #7582: POSTing a duplicate name to organizer endpoints
|
||||
# leaked the sqlalchemy IntegrityError as an HTTP 500. The expected behavior,
|
||||
# matching other organizer endpoints (foods, units, tools), is HTTP 400.
|
||||
data = {"name": random_string(10)}
|
||||
|
||||
response = api_client.post(route.base, json=data, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
response = api_client.post(route.base, json=data, headers=unique_user.token)
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
@pytest.mark.parametrize("route, recipe_key", association_data, ids=test_ids)
|
||||
def test_organizer_get_by_slug(
|
||||
api_client: TestClient,
|
||||
|
||||
@@ -20,6 +20,21 @@ def create_labels(api_client: TestClient, unique_user: TestUser, count: int = 10
|
||||
return labels
|
||||
|
||||
|
||||
def test_label_create_duplicate_name_returns_400(api_client: TestClient, unique_user_fn_scoped: TestUser):
|
||||
# Regression test for #7582: POSTing a duplicate label name leaked the
|
||||
# sqlalchemy IntegrityError as an HTTP 500. The expected behavior, matching
|
||||
# the other organizer endpoints (foods, units, tools, tags, categories),
|
||||
# is HTTP 400. The function-scoped fixture avoids leaking the created label
|
||||
# into the module-scoped `unique_user` group state used by sibling tests.
|
||||
payload = {"name": random_string(), "color": "#ff0000"}
|
||||
|
||||
response = api_client.post(api_routes.groups_labels, json=payload, headers=unique_user_fn_scoped.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.post(api_routes.groups_labels, json=payload, headers=unique_user_fn_scoped.token)
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
def test_new_list_creates_list_labels(api_client: TestClient, unique_user: TestUser):
|
||||
labels = create_labels(api_client, unique_user)
|
||||
response = api_client.post(
|
||||
|
||||
Reference in New Issue
Block a user