From 875d4d2ba10cc2d4126c2e9252cb20526e86a19b Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Tue, 3 Nov 2026 00:05:23 +0000 Subject: [PATCH] fix(projects): return an empty list for blank allowed domains --- .../api/serializers/rest_framework/list.py | 4 +- .../rest_framework/test_project.py | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/sentry/api/serializers/rest_framework/list.py b/src/sentry/api/serializers/rest_framework/list.py index 666a5d165a12..ea9f8c5c75ba 100644 --- a/src/sentry/api/serializers/rest_framework/list.py +++ b/src/sentry/api/serializers/rest_framework/list.py @@ -4,7 +4,7 @@ class EmptyListField(ListField): - def to_internal_value(self, data: Any) -> Any: + def to_internal_value(self, data: Any) -> list[Any]: if data == "": - return "" + return [] return super().to_internal_value(data) diff --git a/tests/sentry/api/serializers/rest_framework/test_project.py b/tests/sentry/api/serializers/rest_framework/test_project.py index a2d36cfb9299..8d0afaa60c98 100644 --- a/tests/sentry/api/serializers/rest_framework/test_project.py +++ b/tests/sentry/api/serializers/rest_framework/test_project.py @@ -1,7 +1,9 @@ from unittest.mock import Mock +import pytest from rest_framework import serializers +from sentry.api.serializers.rest_framework.list import EmptyListField from sentry.api.serializers.rest_framework.project import ProjectField from sentry.testutils.cases import TestCase @@ -38,3 +40,40 @@ class ProjectSerializer(serializers.Serializer): assert not serializer.is_valid() assert serializer.errors == {"project": ["Invalid project"]} + + +class EmptyListFieldTest(TestCase): + def test_empty_string_is_an_empty_list(self) -> None: + field = EmptyListField(child=serializers.CharField(allow_blank=True)) + + assert field.to_internal_value("") == [] + + def test_default_child_preserves_arbitrary_items(self) -> None: + field = EmptyListField() + + assert field.to_internal_value([1, "value"]) == [1, "value"] + + def test_integer_child_converts_values(self) -> None: + field = EmptyListField(child=serializers.IntegerField()) + + assert field.to_internal_value(["1"]) == [1] + + def test_string_child_validates_values(self) -> None: + field = EmptyListField(child=serializers.CharField()) + + assert field.to_internal_value([1]) == ["1"] + + def test_invalid_values_keep_list_field_validation(self) -> None: + field = EmptyListField(child=serializers.IntegerField()) + + with pytest.raises(serializers.ValidationError): + field.to_internal_value(["invalid"]) + + with pytest.raises(serializers.ValidationError): + field.to_internal_value("invalid") + + def test_non_empty_string_is_not_split_into_items(self) -> None: + field = EmptyListField(child=serializers.CharField()) + + with pytest.raises(serializers.ValidationError): + field.to_internal_value("abc")