diff --git a/src/database/model/serializers.py b/src/database/model/serializers.py index 693cc218d..79ef48cf6 100644 --- a/src/database/model/serializers.py +++ b/src/database/model/serializers.py @@ -200,6 +200,9 @@ def deserialize( raise ValueError( "Expected a single value. Do you need to use FindByNameDeserializerList instead?" ) + if not name.strip(): + # Silently reject empty values instead of storing them as a term. + return None name = name.lower() query = select(self.clazz).where(self.clazz.name == name) item = session.scalars(query).first() @@ -232,7 +235,8 @@ def deserialize( return [] if not isinstance(name, list): raise ValueError("Expected a list. Do you need to use FindByNameDeserializer instead?") - names = {n if self.case_sensitive else n.casefold() for n in name} + # Empty values are silently rejected instead of being stored as a term. + names = {n if self.case_sensitive else n.casefold() for n in name if n.strip()} query = select(self.clazz).where(self.clazz.name.in_(names)) # type: ignore[attr-defined] existing = list(session.scalars(query).all()) if self.case_sensitive: diff --git a/src/tests/routers/generic/test_router_relations.py b/src/tests/routers/generic/test_router_relations.py index d3ca3c648..b744ee0e7 100644 --- a/src/tests/routers/generic/test_router_relations.py +++ b/src/tests/routers/generic/test_router_relations.py @@ -227,6 +227,26 @@ def test_post_happy_path(client_with_testobject: TestClient, auto_publish: None) assert related_objects[1]["field2"] == "val2.2" +def test_post_empty_enum_values_are_rejected( + client_with_testobject: TestClient, auto_publish: None +): + with logged_in_user(): + response = client_with_testobject.post( + "/test_resources", + json={ + "title": "title", + "named_string": "", + "named_string_list": ["", "1", " ", ""], + "related_objects": [], + }, + headers={"Authorization": "Fake token"}, + ) + assert response.status_code == 200, response.json() + obj = client_with_testobject.get("/test_resources?direction=asc").json()[-1] + assert "named_string" not in obj + assert obj["named_string_list"] == ["1"] + + def test_put_happy_path(test_objects: list[TestObject], client_with_testobject: TestClient, auto_publish: None): identifier = test_objects[3].identifier with logged_in_user(kc_user_with_roles("update_test_resources")):