Skip to content

Commit 18230bf

Browse files
authored
feat: added type filter on get feature endpoint (#7598)
1 parent bf287b0 commit 18230bf

3 files changed

Lines changed: 46 additions & 0 deletions

File tree

api/features/serializers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
from .feature_segments.serializers import (
5454
CustomCreateSegmentOverrideFeatureSegmentSerializer,
5555
)
56+
from .feature_types import FEATURE_TYPE_CHOICES
5657
from .models import Feature, FeatureState
5758
from .multivariate.serializers import NestedMultivariateFeatureOptionSerializer
5859

@@ -95,6 +96,11 @@ class FeatureQuerySerializer(serializers.Serializer): # type: ignore[type-arg]
9596
)
9697

9798
is_archived = serializers.BooleanField(required=False)
99+
type = serializers.ChoiceField(
100+
choices=FEATURE_TYPE_CHOICES,
101+
required=False,
102+
help_text="Feature type to filter on (STANDARD or MULTIVARIATE).",
103+
)
98104
environment = serializers.IntegerField(
99105
required=False,
100106
help_text="Integer ID of the environment to view features in the context of.",

api/features/views.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,9 @@ def _filter_queryset(
612612
if "is_archived" in query_serializer.initial_data:
613613
queryset = queryset.filter(is_archived=query_data["is_archived"])
614614

615+
if query_data.get("type"):
616+
queryset = queryset.filter(type=query_data["type"])
617+
615618
queryset = self.filter_owners_and_group_owners(queryset, query_data)
616619

617620
return queryset

api/tests/integration/features/test_integration_features.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22

3+
import pytest
34
from django.urls import reverse
45
from rest_framework import status
56

@@ -203,3 +204,39 @@ def test_list_features__filter_by_archived_status__returns_matching_features( #
203204
list_features_is_archived_true_response.json()["results"][0]["id"]
204205
== archived_feature_id
205206
)
207+
208+
209+
@pytest.mark.parametrize(
210+
"type_filter, expected_feature_name",
211+
[
212+
("STANDARD", "standard_feature"),
213+
("MULTIVARIATE", "multivariate_feature"),
214+
],
215+
)
216+
def test_list_features__filter_by_type__returns_matching_features( # type: ignore[no-untyped-def]
217+
admin_client, project, type_filter, expected_feature_name
218+
):
219+
# Given
220+
features_url = reverse("api-v1:projects:project-features-list", args=[project])
221+
admin_client.post(
222+
features_url,
223+
data={"name": "standard_feature", "project": project},
224+
)
225+
admin_client.post(
226+
features_url,
227+
data={
228+
"name": "multivariate_feature",
229+
"project": project,
230+
"type": "MULTIVARIATE",
231+
"initial_value": "control",
232+
},
233+
)
234+
235+
# When
236+
response = admin_client.get(f"{features_url}?type={type_filter}")
237+
238+
# Then
239+
assert response.status_code == status.HTTP_200_OK
240+
response_json = response.json()
241+
assert response_json["count"] == 1
242+
assert response_json["results"][0]["name"] == expected_feature_name

0 commit comments

Comments
 (0)