diff --git a/kolibri/core/content/api.py b/kolibri/core/content/api.py index af7a8f18099..26df2d674e4 100644 --- a/kolibri/core/content/api.py +++ b/kolibri/core/content/api.py @@ -1533,15 +1533,15 @@ class UserContentNodeFilter(ContentNodeFilter): popular = BooleanFilter(method="filter_by_popular") def filter_by_lesson(self, queryset, name, value): - try: - lesson = Lesson.objects.filter( - lesson_assignments__collection__membership__user=self.request.user, - is_active=True, - ).get(pk=value) - node_ids = list(map(lambda x: x["contentnode_id"], lesson.resources)) - return queryset.filter(pk__in=node_ids) - except Lesson.DoesNotExist: + lesson = Lesson.objects.filter( + lesson_assignments__collection__membership__user=self.request.user, + is_active=True, + pk=value, + ).first() + if lesson is None: return queryset.none() + node_ids = list(map(lambda x: x["contentnode_id"], lesson.resources)) + return queryset.filter(pk__in=node_ids) def filter_by_resume(self, queryset, name, value): user = self.request.user diff --git a/kolibri/core/content/test/test_content_app.py b/kolibri/core/content/test/test_content_app.py index 5ebfc958c65..e3b99cef2ad 100644 --- a/kolibri/core/content/test/test_content_app.py +++ b/kolibri/core/content/test/test_content_app.py @@ -18,14 +18,18 @@ from rest_framework import status from rest_framework.test import APITestCase +from kolibri.core.auth.models import Classroom from kolibri.core.auth.models import Facility from kolibri.core.auth.models import FacilityUser +from kolibri.core.auth.models import LearnerGroup from kolibri.core.auth.test.helpers import provision_device from kolibri.core.content import models as content from kolibri.core.content.test.test_channel_upgrade import ChannelBuilder from kolibri.core.device.models import ContentCacheKey from kolibri.core.device.models import DevicePermissions from kolibri.core.device.models import DeviceSettings +from kolibri.core.lessons.models import Lesson +from kolibri.core.lessons.models import LessonAssignment from kolibri.core.logger.models import ContentSessionLog from kolibri.core.logger.models import ContentSummaryLog from kolibri.utils.tests.helpers import override_option @@ -1819,6 +1823,118 @@ def test_next_steps_sibling_coach_content_coach(self): response_content_ids = {node["content_id"] for node in response.json()} self.assertSetEqual(set(expected_content_ids), response_content_ids) + def test_lesson_filter(self): + classroom = Classroom.objects.create(name="classroom", parent=self.facility) + user = FacilityUser.objects.create(username="user", facility=self.facility) + classroom.add_member(user) + node = content.ContentNode.objects.get( + content_id="ce603df7c46b424b934348995e1b05fb" + ) + + resources = [ + { + "contentnode_id": node.id, + "content_id": node.content_id, + "channel_id": node.channel_id, + } + ] + + own_lesson = Lesson.objects.create( + title="Lesson", + collection=classroom, + created_by=self.admin, + is_active=True, + resources=resources, + ) + LessonAssignment.objects.create( + lesson=own_lesson, assigned_by=self.admin, collection=classroom + ) + user.set_password(DUMMY_PASSWORD) + user.save() + self.client.login(username=user.username, password=DUMMY_PASSWORD) + response = self.client.get( + reverse("kolibri:core:usercontentnode-list"), data={"lesson": own_lesson.id} + ) + self.assertEqual(response.status_code, 200) + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]["content_id"], node.content_id) + + def test_lesson_filter_not_own_lesson(self): + classroom = Classroom.objects.create(name="classroom", parent=self.facility) + user = FacilityUser.objects.create(username="user", facility=self.facility) + node = content.ContentNode.objects.get( + content_id="ce603df7c46b424b934348995e1b05fb" + ) + + resources = [ + { + "contentnode_id": node.id, + "content_id": node.content_id, + "channel_id": node.channel_id, + } + ] + + own_lesson = Lesson.objects.create( + title="Lesson", + collection=classroom, + created_by=self.admin, + is_active=True, + resources=resources, + ) + LessonAssignment.objects.create( + lesson=own_lesson, assigned_by=self.admin, collection=classroom + ) + user.set_password(DUMMY_PASSWORD) + user.save() + self.client.login(username=user.username, password=DUMMY_PASSWORD) + response = self.client.get( + reverse("kolibri:core:usercontentnode-list"), data={"lesson": own_lesson.id} + ) + self.assertEqual(response.status_code, 200) + self.assertEqual(len(response.data), 0) + + def test_lesson_filter_multiple_assignment(self): + classroom = Classroom.objects.create(name="classroom", parent=self.facility) + user = FacilityUser.objects.create(username="user", facility=self.facility) + classroom.add_member(user) + node = content.ContentNode.objects.get( + content_id="ce603df7c46b424b934348995e1b05fb" + ) + + resources = [ + { + "contentnode_id": node.id, + "content_id": node.content_id, + "channel_id": node.channel_id, + } + ] + + own_lesson = Lesson.objects.create( + title="Lesson", + collection=classroom, + created_by=self.admin, + is_active=True, + resources=resources, + ) + LessonAssignment.objects.create( + lesson=own_lesson, assigned_by=self.admin, collection=classroom + ) + user.set_password(DUMMY_PASSWORD) + user.save() + self.client.login(username=user.username, password=DUMMY_PASSWORD) + group = LearnerGroup.objects.create(name="Own Group", parent=classroom) + group.add_member(user) + LessonAssignment.objects.create( + lesson=own_lesson, assigned_by=self.admin, collection=group + ) + self.client.login(username=user.username, password=DUMMY_PASSWORD) + response = self.client.get( + reverse("kolibri:core:usercontentnode-list"), data={"lesson": own_lesson.id} + ) + self.assertEqual(response.status_code, 200) + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]["content_id"], node.content_id) + def tearDown(self): """ clean up files/folders created during the test