Skip to content

Commit 550fe78

Browse files
committed
Represent categories as a list after passing from changes
1 parent 9152aeb commit 550fe78

8 files changed

Lines changed: 29 additions & 19 deletions

File tree

contentcuration/contentcuration/tests/viewsets/test_channel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ def test_process_added_to_community_library_change(self, mock_export_func):
615615
)
616616
self.assertEqual(call_kwargs["channel_id"], channel.id)
617617
self.assertEqual(call_kwargs["channel_version"], 2)
618-
self.assertEqual(call_kwargs["categories"], categories)
618+
self.assertCountEqual(call_kwargs["categories"], categories.keys())
619619

620620
# The countries argument used when creating the mapper is in fact
621621
# not a list, but a QuerySet, but it contains the same elements

contentcuration/contentcuration/viewsets/channel.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,10 @@ def add_to_community_library_from_changes(self, changes):
795795
def add_to_community_library(
796796
self, channel_id, channel_version, categories, country_codes
797797
):
798+
# Note: The `categories` field should contain a _dict_, with the category IDs as keys
799+
# and `True` as a value. This is to match the representation
800+
# of sets in the changes architecture.
801+
798802
# The change to add a channel to the community library can only
799803
# be created server-side, so in theory we should not be getting
800804
# malformed requests here. However, just to be safe, we still
@@ -810,11 +814,17 @@ def add_to_community_library(
810814
if channel_version <= 0 or channel_version > channel.version:
811815
raise ValidationError("Invalid channel version")
812816

817+
# Because of changes architecture, the categories are passed as a dict
818+
# with the category IDs as keys and `True` as a value. At this point,
819+
# we are no longer working with changes, so we switch to the more
820+
# convenient representation as a list.
821+
categories_list = [key for key, val in categories.items() if val]
822+
813823
export_channel_to_kolibri_public(
814824
channel_id=channel_id,
815825
channel_version=channel_version,
816826
public=False, # Community library
817-
categories=categories,
827+
categories=categories_list,
818828
countries=countries,
819829
)
820830

contentcuration/kolibri_public/models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class AssessmentMetaData(base_models.AssessmentMetaData):
9797

9898

9999
class ChannelMetadata(base_models.ChannelMetadata):
100+
# Note: The `categories` field should contain a _list_, NOT a _dict_.
101+
100102
# precalculated fields during annotation/migration
101103
published_size = models.BigIntegerField(default=0, null=True, blank=True)
102104
total_resource_count = models.IntegerField(default=0, null=True, blank=True)

contentcuration/kolibri_public/tests/test_export_channels_to_kolibri_public.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,7 @@ def tearDown(self):
102102
def test_export_channel_to_kolibri_public__existing_version(
103103
self, mock_channel_mapper
104104
):
105-
categories = {
106-
"Category1": True,
107-
"Category2": True,
108-
}
105+
categories = ["Category1", "Category2"]
109106
country1 = Country.objects.create(code="C1", name="Country 1")
110107
country2 = Country.objects.create(code="C2", name="Country 2")
111108
countries = [country1, country2]

contentcuration/kolibri_public/tests/test_mapper.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,15 @@ def test_categories__none_provided(self):
181181
mapper = ChannelMapper(self.channel)
182182
mapper.run()
183183

184-
self.assertEqual(mapper.mapped_channel.categories, {})
184+
self.assertEqual(mapper.mapped_channel.categories, [])
185185

186186
def test_categories__only_provided(self):
187187
with using_content_database(self.tempdb):
188188
kolibri_content_models.ContentNode.objects.filter(
189189
channel_id=self.channel.id,
190190
).update(categories=None)
191191

192-
categories = {"Category1": True, "Category2": True}
192+
categories = ["Category1", "Category2"]
193193
mapper = ChannelMapper(self.channel, categories=categories)
194194
mapper.run()
195195

@@ -216,7 +216,7 @@ def test_categories__only_on_content_nodes(self):
216216

217217
self.assertEqual(
218218
mapper.mapped_channel.categories,
219-
{"Category1": True, "Category2": True, "Category3": True},
219+
["Category1", "Category2", "Category3"],
220220
)
221221

222222
def test_categories__both_provided_and_on_content_nodes(self):
@@ -235,18 +235,13 @@ def test_categories__both_provided_and_on_content_nodes(self):
235235
contentnode1.save()
236236
contentnode2.save()
237237

238-
categories = {"Category3": True, "Category4": True}
238+
categories = ["Category3", "Category4"]
239239
mapper = ChannelMapper(self.channel, categories=categories)
240240
mapper.run()
241241

242242
self.assertEqual(
243243
mapper.mapped_channel.categories,
244-
{
245-
"Category1": True,
246-
"Category2": True,
247-
"Category3": True,
248-
"Category4": True,
249-
},
244+
["Category1", "Category2", "Category3", "Category4"],
250245
)
251246

252247
def test_countries__none_provided(self):

contentcuration/kolibri_public/utils/annotation.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ def set_channel_metadata_fields(
2121
categories=None,
2222
countries=None,
2323
):
24+
# Note: The `categories` argument should be a _list_, NOT a _dict_.
25+
2426
# Remove unneeded db_lock
2527
channel = ChannelMetadata.objects.get(id=channel_id)
2628
calculate_published_size(channel)
@@ -92,9 +94,9 @@ def calculate_included_categories(channel, categories):
9294
)
9395
)
9496
)
95-
categories_dict = {category: True for category in contentnode_categories}
96-
categories_dict.update(categories or {})
97-
channel.categories = categories_dict
97+
98+
all_categories = sorted(set(categories or []).union(contentnode_categories))
99+
channel.categories = all_categories
98100
channel.save()
99101

100102

contentcuration/kolibri_public/utils/export_channel_to_kolibri_public.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def export_channel_to_kolibri_public(
2323
categories=None,
2424
countries=None,
2525
):
26+
# Note: The `categories` argument should be a _list_, NOT a _dict_.
2627
logger.info("Putting channel {} into kolibri_public".format(channel_id))
2728

2829
if channel_version is not None:

contentcuration/kolibri_public/utils/mapper.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ def __init__(
2929
# Note: The argument `channel` is an instance of `kolibri_content.models.ChannelMetadata,`
3030
# which belongs to a specific channel version to be exported. Therefore, we do not
3131
# need to explicitly pass the channel version as an argument here.
32+
33+
# Note: The `categories` argument should be a _list_, NOT a _dict_.
34+
3235
self.channel = channel
3336
self.public = public
3437
self.categories = categories

0 commit comments

Comments
 (0)