Repository: learningequality/ricecooker

Issue:
Ensure topic/channel extra fields are added as 'options' in their extra_fields property to make sure options for topics are set during publishing
It appears that currently extra fields on topics are not annotated onto the exported topics during publishing.

This is required in order to properly export the modality extra field and expose `CUSTOM_NAVIGATION` modality to Kolibri for determining if a topic has this modality.

Discussion:

Patch:
diff --git a/ricecooker/classes/nodes.py b/ricecooker/classes/nodes.py
index 4b5e49f..0a7efe6 100644
--- a/ricecooker/classes/nodes.py
+++ b/ricecooker/classes/nodes.py
@@ -1069,7 +1069,9 @@ class CustomNavigationNode(ContentNode):
     required_file_format = file_formats.HTML5
 
     def __init__(self, *args, **kwargs):
-        kwargs["extra_fields"] = {'modality': "CUSTOM_NAVIGATION"}
+        kwargs["extra_fields"] = kwargs.get("extra_fields", {})
+        kwargs["extra_fields"]["options"] = kwargs["extra_fields"].get("options", {})
+        kwargs["extra_fields"]["options"].update({'modality': "CUSTOM_NAVIGATION"})
         super(CustomNavigationNode, self).__init__(*args, **kwargs)
 
     def generate_thumbnail(self):
@@ -1102,7 +1104,9 @@ class CustomNavigationChannelNode(ChannelNode):
     required_file_format = file_formats.HTML5
 
     def __init__(self, *args, **kwargs):
-        kwargs["extra_fields"] = {'modality': "CUSTOM_NAVIGATION"}
+        kwargs["extra_fields"] = kwargs.get("extra_fields", {})
+        kwargs["extra_fields"]["options"] = kwargs["extra_fields"].get("options", {})
+        kwargs["extra_fields"]["options"].update({'modality': "CUSTOM_NAVIGATION"})
         super(CustomNavigationChannelNode, self).__init__(*args, **kwargs)
 
     def validate(self):


Test patch:
diff --git a/tests/test_tree.py b/tests/test_tree.py
index eda8f60..1ba438d 100644
--- a/tests/test_tree.py
+++ b/tests/test_tree.py
@@ -290,7 +290,7 @@ def test_custom_navigation_node_via_files(channel):
     assert custom_navigation_node.kind == 'topic'
     assert len(custom_navigation_node.files) == 2, 'missing files'
     assert custom_navigation_node.extra_fields, 'missing extra_fields'
-    assert 'modality' in custom_navigation_node.extra_fields and custom_navigation_node.extra_fields["modality"] == "CUSTOM_NAVIGATION", 'missing custom navigation modality'
+    assert "options" in custom_navigation_node.extra_fields and 'modality' in custom_navigation_node.extra_fields["options"] and custom_navigation_node.extra_fields["options"]["modality"] == "CUSTOM_NAVIGATION", 'missing custom navigation modality'
     custom_navigation_node.process_files()
     channel.add_child(custom_navigation_node)
     assert channel.validate_tree()
@@ -327,7 +327,7 @@ def test_custom_navigation_node_via_add_file(channel):
     assert custom_navigation_node.kind == 'topic'
     assert len(custom_navigation_node.files) == 2, 'missing files'
     assert custom_navigation_node.extra_fields, 'missing extra_fields'
-    assert 'modality' in custom_navigation_node.extra_fields and custom_navigation_node.extra_fields["modality"] == "CUSTOM_NAVIGATION", 'missing custom navigation modality'
+    assert "options" in custom_navigation_node.extra_fields and 'modality' in custom_navigation_node.extra_fields["options"] and custom_navigation_node.extra_fields["options"]["modality"] == "CUSTOM_NAVIGATION", 'missing custom navigation modality'
     custom_navigation_node.process_files()
     channel.add_child(custom_navigation_node)
     assert channel.validate_tree()
@@ -365,7 +365,7 @@ def test_custom_navigation_channel_node_via_files():
     assert custom_navigation_channel_node.kind == 'Channel'
     assert len(custom_navigation_channel_node.files) == 2, 'missing files'
     assert custom_navigation_channel_node.extra_fields, 'missing extra_fields'
-    assert 'modality' in custom_navigation_channel_node.extra_fields and custom_navigation_channel_node.extra_fields["modality"] == "CUSTOM_NAVIGATION", 'missing custom navigation modality'
+    assert 'options' in custom_navigation_channel_node.extra_fields and 'modality' in custom_navigation_channel_node.extra_fields["options"] and custom_navigation_channel_node.extra_fields["options"]["modality"] == "CUSTOM_NAVIGATION", 'missing custom navigation modality'
     custom_navigation_channel_node.set_thumbnail(thumbimg1)
     custom_navigation_channel_node.process_files()
     assert custom_navigation_channel_node.validate_tree()
@@ -403,7 +403,7 @@ def test_custom_navigation_channel_node_via_add_file():
     assert custom_navigation_channel_node.kind == 'Channel'
     assert len(custom_navigation_channel_node.files) == 2, 'missing files'
     assert custom_navigation_channel_node.extra_fields, 'missing extra_fields'
-    assert 'modality' in custom_navigation_channel_node.extra_fields and custom_navigation_channel_node.extra_fields["modality"] == "CUSTOM_NAVIGATION", 'missing custom navigation modality'
+    assert 'options' in custom_navigation_channel_node.extra_fields and 'modality' in custom_navigation_channel_node.extra_fields["options"] and custom_navigation_channel_node.extra_fields["options"]["modality"] == "CUSTOM_NAVIGATION", 'missing custom navigation modality'
     custom_navigation_channel_node.set_thumbnail(thumbimg1)
     custom_navigation_channel_node.process_files()
     assert custom_navigation_channel_node.validate_tree()