diff --git a/api/features/multivariate/serializers.py b/api/features/multivariate/serializers.py index abb09e0823ec..bf965cab4813 100644 --- a/api/features/multivariate/serializers.py +++ b/api/features/multivariate/serializers.py @@ -61,6 +61,14 @@ def get_control_value(self, obj: dict[str, typing.Any]) -> str | int | bool | No class MultivariateFeatureOptionSerializer(NestedMultivariateFeatureOptionSerializer): + # The model field has `default=100`, which only makes DRF mark this field + # `required=False` — it does not carry the default into `validated_data`. + # Declare it explicitly so omitting it from the request does not raise a + # `KeyError` in `validate()` below. + default_percentage_allocation = serializers.FloatField( + default=100, min_value=0, max_value=100 + ) + class Meta(NestedMultivariateFeatureOptionSerializer.Meta): fields = NestedMultivariateFeatureOptionSerializer.Meta.fields + ("feature",) # type: ignore[assignment] read_only_fields = ("uuid",) # type: ignore[assignment] diff --git a/api/tests/integration/features/multivariate/test_integration_multivariate.py b/api/tests/integration/features/multivariate/test_integration_multivariate.py index 5067d8f8c697..cde3c424a4a4 100644 --- a/api/tests/integration/features/multivariate/test_integration_multivariate.py +++ b/api/tests/integration/features/multivariate/test_integration_multivariate.py @@ -44,6 +44,32 @@ def test_create_mv_option__valid_data__returns_created( # type: ignore[no-untyp assert set(data.items()).issubset(set(response.json().items())) +def test_create_mv_option__no_default_percentage_allocation__defaults_to_100( + admin_client_new: APIClient, + project: int, + feature: int, +) -> None: + # Given - the request omits `default_percentage_allocation` entirely + url = reverse( + "api-v1:projects:feature-mv-options-list", + args=[project, feature], + ) + data = { + "type": "unicode", + "feature": feature, + "string_value": "bigger", + } + # When + response = admin_client_new.post( + url, + data=json.dumps(data), + content_type="application/json", + ) + # Then - it defaults to the model's default instead of a 500 KeyError + assert response.status_code == status.HTTP_201_CREATED + assert response.json()["default_percentage_allocation"] == 100 + + def test_create_mv_option__with_key__returns_created_with_key( admin_client_new: APIClient, project: int,