Skip to content

Commit

Permalink
Merge pull request #12763 from rtibbles/i_got_what_you_need
Browse files Browse the repository at this point in the history
Add learner_needs field to contentnode API
  • Loading branch information
rtibbles authored Nov 13, 2024
2 parents b9b1149 + b48f3ac commit f2c200c
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 2 deletions.
12 changes: 10 additions & 2 deletions kolibri/core/content/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,9 @@ def _get_response_headers(self, response):
return headers

def _cache_etag(self, baseurl, headers):
cache_key = REMOTE_ETAG_CACHE_KEY.format(baseurl)
cache.set(cache_key, headers["Etag"], 3600)
if "Etag" in headers:
cache_key = REMOTE_ETAG_CACHE_KEY.format(baseurl)
cache.set(cache_key, headers["Etag"], 3600)

def update_data(self, response_data, baseurl):
return response_data
Expand Down Expand Up @@ -648,6 +649,7 @@ class BaseContentNodeMixin(object):
"grade_levels",
"resource_types",
"accessibility_labels",
"learner_needs",
"categories",
"duration",
"ancestors",
Expand All @@ -659,6 +661,7 @@ class BaseContentNodeMixin(object):
"resource_types": lambda x: _split_text_field(x["resource_types"]),
"accessibility_labels": lambda x: _split_text_field(x["accessibility_labels"]),
"categories": lambda x: _split_text_field(x["categories"]),
"learner_needs": lambda x: _split_text_field(x["learner_needs"]),
}

def get_queryset(self):
Expand Down Expand Up @@ -790,6 +793,11 @@ def update_data(self, response_data, baseurl):
response_data["admin_imported"] = (
response_data["id"] in self.locally_admin_imported_ids
)
if "learner_needs" not in response_data:
# We accidentally omitted learner_needs from previous versions
# of the public API, so we add it back in here,
# so that remote data and local data have consistent structure.
response_data["learner_needs"] = []
if "children" in response_data:
response_data["children"] = self.update_data(
response_data["children"], baseurl
Expand Down
115 changes: 115 additions & 0 deletions kolibri/core/content/test/test_content_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ def _assert_node(self, actual, expected):
thumbnail = f.get_storage_url()
if self.baseurl and thumbnail:
thumbnail += "?baseurl={}".format(self.baseurl)
files = sorted(files, key=lambda x: x["id"])
actual["files"] = sorted(actual["files"], key=lambda x: x["id"])
self.assertEqual(
actual,
{
Expand All @@ -334,6 +336,9 @@ def _assert_node(self, actual, expected):
"learning_activities": expected.learning_activities.split(",")
if expected.learning_activities
else [],
"learner_needs": expected.learner_needs.split(",")
if expected.learner_needs
else [],
"grade_levels": expected.grade_levels.split(",")
if expected.grade_levels
else [],
Expand Down Expand Up @@ -1889,6 +1894,116 @@ def test_lesson_filter_multiple_assignment(self):
self.assertEqual(len(response.data), 1)
self.assertEqual(response.data[0]["content_id"], node.content_id)

def test_remote_content_node_missing_learner_needs(self):
with mock.patch("kolibri.core.content.api.NetworkClient") as nc:
mock_response = mock.Mock()
mock_response.headers = {}
mock_response.status_code = 200
expected = content.ContentNode.objects.get(title="c2c2")
assessmentmetadata = (
expected.assessmentmetadata.all()
.values(
"assessment_item_ids",
"number_of_assessments",
"mastery_model",
"randomize",
"is_manipulable",
"contentnode",
)
.first()
)
thumbnail = None
files = []
for f in expected.files.all():
"local_file__id",
"local_file__available",
"local_file__file_size",
"local_file__extension",
"lang_id",
file = {}
for field in [
"id",
"priority",
"preset",
"supplementary",
"thumbnail",
]:
file[field] = getattr(f, field)
file["checksum"] = f.local_file_id
for field in [
"available",
"file_size",
"extension",
]:
file[field] = getattr(f.local_file, field)
file["lang"] = self.map_language(f.lang)
file["storage_url"] = f.get_storage_url()
if self.baseurl and file["storage_url"]:
file["storage_url"] += "?baseurl={}".format(self.baseurl)
files.append(file)
if f.thumbnail:
thumbnail = f.get_storage_url()
if self.baseurl and thumbnail:
thumbnail += "?baseurl={}".format(self.baseurl)
expected_old_data = {
"id": expected.id,
"available": expected.available,
"author": expected.author,
"channel_id": expected.channel_id,
"coach_content": expected.coach_content,
"content_id": expected.content_id,
"description": expected.description,
"duration": expected.duration,
"learning_activities": expected.learning_activities.split(",")
if expected.learning_activities
else [],
"grade_levels": expected.grade_levels.split(",")
if expected.grade_levels
else [],
"resource_types": expected.resource_types.split(",")
if expected.resource_types
else [],
"accessibility_labels": expected.accessibility_labels.split(",")
if expected.accessibility_labels
else [],
"categories": expected.categories.split(",")
if expected.categories
else [],
"kind": expected.kind,
"lang": self.map_language(expected.lang),
"license_description": expected.license_description,
"license_name": expected.license_name,
"license_owner": expected.license_owner,
"num_coach_contents": expected.num_coach_contents,
"options": expected.options,
"parent": expected.parent_id,
"sort_order": expected.sort_order,
"title": expected.title,
"lft": expected.lft,
"rght": expected.rght,
"tree_id": expected.tree_id,
"ancestors": [],
"tags": list(
expected.tags.all()
.order_by("tag_name")
.values_list("tag_name", flat=True)
),
"thumbnail": thumbnail,
"assessmentmetadata": assessmentmetadata,
"is_leaf": expected.kind != "topic",
"files": files,
"admin_imported": bool(expected.admin_imported),
}
mock_response.json.return_value = expected_old_data
mock_client = mock.MagicMock()
mock_client.get.return_value = mock_response
nc.build_for_address.return_value = mock_client
response = self.client.get(
reverse("kolibri:core:contentnode-detail", kwargs={"pk": expected.id}),
data={"baseurl": "http://example.com/"},
)
self.assertEqual(response.data["learner_needs"], [])

def tearDown(self):
"""
clean up files/folders created during the test
Expand Down

0 comments on commit f2c200c

Please sign in to comment.