Skip to content

Commit 2c92e7c

Browse files
committed
Countries filter for ChannelMetadataViewSet
1 parent 6ba852a commit 2c92e7c

2 files changed

Lines changed: 52 additions & 9 deletions

File tree

contentcuration/kolibri_public/tests/test_channelmetadata_viewset.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ def setUp(self):
4949
8,
5050
]
5151

52+
mixer.blend(Country, code="C1")
53+
mixer.blend(Country, code="C2")
54+
mixer.blend(Country, code="C3")
55+
5256
self.user = testdata.user("[email protected]")
5357

5458
# Manually set the bitmasks for testing
@@ -59,6 +63,7 @@ def setUp(self):
5963
| self.category_bitmasks[1]
6064
| self.category_bitmasks[3]
6165
),
66+
countries=["C1", "C3"],
6267
)
6368
self.metadata2 = mixer.blend(
6469
ChannelMetadata,
@@ -67,6 +72,7 @@ def setUp(self):
6772
| self.category_bitmasks[2]
6873
| self.category_bitmasks[3]
6974
),
75+
countries=["C1", "C2", "C3"],
7076
)
7177
self.metadata3 = mixer.blend(
7278
ChannelMetadata,
@@ -75,6 +81,7 @@ def setUp(self):
7581
| self.category_bitmasks[1]
7682
| self.category_bitmasks[2]
7783
),
84+
countries=["C3"],
7885
)
7986

8087
def test_filter_by_categories_bitmask__provided(self):
@@ -105,3 +112,34 @@ def test_filter_by_categories_bitmask__not_provided(self):
105112
[UUID(item["id"]) for item in response.data],
106113
[UUID(self.metadata1.id), UUID(self.metadata2.id), UUID(self.metadata3.id)],
107114
)
115+
116+
def test_filter_by_countries(self):
117+
self.client.force_authenticate(self.user)
118+
119+
filter_query = {"countries": "C1,C2"}
120+
121+
response = self.client.get(
122+
reverse_with_query(
123+
"publicchannel-list",
124+
query=filter_query,
125+
),
126+
)
127+
self.assertEqual(response.status_code, 200, response.content)
128+
self.assertCountEqual(
129+
[UUID(item["id"]) for item in response.data],
130+
[UUID(self.metadata1.id), UUID(self.metadata2.id)],
131+
)
132+
133+
response1 = next(
134+
filter(
135+
lambda item: UUID(item["id"]) == UUID(self.metadata1.id), response.data
136+
)
137+
)
138+
response2 = next(
139+
filter(
140+
lambda item: UUID(item["id"]) == UUID(self.metadata2.id), response.data
141+
)
142+
)
143+
144+
self.assertCountEqual(response1["countries"], ["C1", "C3"])
145+
self.assertCountEqual(response2["countries"], ["C1", "C2", "C3"])

contentcuration/kolibri_public/views.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,23 @@ def bitmask_contains_and(queryset, name, value):
9191
return queryset.has_all_labels(name, value.split(","))
9292

9393

94+
class UUIDInFilter(BaseInFilter, UUIDFilter):
95+
pass
96+
97+
98+
class CharInFilter(BaseInFilter, CharFilter):
99+
pass
100+
101+
94102
class ChannelMetadataFilter(FilterSet):
95103
available = BooleanFilter(method="filter_available", label="Available")
96104
has_exercise = BooleanFilter(method="filter_has_exercise", label="Has exercises")
97105
categories = CharFilter(method=bitmask_contains_and, label="Categories")
106+
countries = CharInFilter(field_name="countries", label="Countries")
98107

99108
class Meta:
100109
model = models.ChannelMetadata
101-
fields = ("available", "has_exercise", "categories")
110+
fields = ("available", "has_exercise", "categories", "countries")
102111

103112
def filter_has_exercise(self, queryset, name, value):
104113
queryset = queryset.annotate(
@@ -159,6 +168,10 @@ def get_queryset(self):
159168
return models.ChannelMetadata.objects.all()
160169

161170
def consolidate(self, items, queryset):
171+
# Only keep a single item for every channel ID, to get rid of possible
172+
# duplicates caused by filtering
173+
items = list(OrderedDict((item["id"], item) for item in items).values())
174+
162175
included_languages = {}
163176
for (
164177
channel_id,
@@ -189,14 +202,6 @@ def consolidate(self, items, queryset):
189202
return items
190203

191204

192-
class UUIDInFilter(BaseInFilter, UUIDFilter):
193-
pass
194-
195-
196-
class CharInFilter(BaseInFilter, CharFilter):
197-
pass
198-
199-
200205
contentnode_filter_fields = [
201206
"parent",
202207
"parent__isnull",

0 commit comments

Comments
 (0)