From db902abd3ababfbfcce8bf9f33d2ec4f1fbd9036 Mon Sep 17 00:00:00 2001 From: Jillian Vogel Date: Fri, 23 Aug 2024 19:28:31 +0930 Subject: [PATCH] feat: adds get_collection_components which returns the Components associated with a given Collection. Also updates the CollectionContents tests to use Components instead of PublishableEntities, to better test against our actual use case. --- .../apps/authoring/collections/api.py | 12 +++ .../apps/authoring/collections/test_api.py | 92 +++++++++---------- 2 files changed, 58 insertions(+), 46 deletions(-) diff --git a/openedx_learning/apps/authoring/collections/api.py b/openedx_learning/apps/authoring/collections/api.py index 29764735..e5f72f58 100644 --- a/openedx_learning/apps/authoring/collections/api.py +++ b/openedx_learning/apps/authoring/collections/api.py @@ -6,6 +6,7 @@ from django.db.models import QuerySet from django.db.transaction import atomic +from ..components.models import Component from ..publishing.models import PublishableEntity from .models import Collection, CollectionObject @@ -19,6 +20,7 @@ "create_collection", "get_collection", "get_learning_package_collections", + "get_collection_components", "get_object_collections", "remove_from_collections", "update_collection", @@ -139,6 +141,16 @@ def remove_from_collections( return total_deleted +def get_collection_components(collection_id: int, component_qset: QuerySet[Component]) -> QuerySet[Component]: + """ + Returns the Components associated with a given Collection. + + Filters matching Components from the given components queryset. + """ + coll_obj_ids = CollectionObject.objects.filter(collection_id=collection_id).values_list("object_id", flat=True) + return component_qset.filter(publishable_entity_id__in=coll_obj_ids).order_by("pk") + + def get_object_collections(object_id: int) -> QuerySet[Collection]: """ Get all collections associated with a given PublishableEntity. diff --git a/tests/openedx_learning/apps/authoring/collections/test_api.py b/tests/openedx_learning/apps/authoring/collections/test_api.py index 526c2cba..fb9ff358 100644 --- a/tests/openedx_learning/apps/authoring/collections/test_api.py +++ b/tests/openedx_learning/apps/authoring/collections/test_api.py @@ -9,12 +9,10 @@ from openedx_learning.apps.authoring.collections import api as collection_api from openedx_learning.apps.authoring.collections.models import Collection +from openedx_learning.apps.authoring.components import api as components_api +from openedx_learning.apps.authoring.components.models import Component from openedx_learning.apps.authoring.publishing import api as publishing_api -from openedx_learning.apps.authoring.publishing.models import ( - LearningPackage, - PublishableEntity, - PublishableEntityVersion, -) +from openedx_learning.apps.authoring.publishing.models import LearningPackage, PublishableEntity from openedx_learning.lib.test_utils import TestCase User = get_user_model() @@ -150,10 +148,8 @@ class CollectionContentsTestCase(CollectionTestCase): """ Test collections that contain publishable entitites. """ - published_entity: PublishableEntity - pe_version: PublishableEntityVersion - draft_entity: PublishableEntity - de_version: PublishableEntityVersion + published_component: Component + draft_component: Component collection0: Collection collection1: Collection collection2: Collection @@ -166,17 +162,12 @@ def setUpTestData(cls) -> None: """ super().setUpTestData() - # Make and Publish one PublishableEntity - cls.published_entity = publishing_api.create_publishable_entity( + # Make and Publish one Component + html_type = components_api.get_or_create_component_type("xblock.v1", "html") + cls.published_component = components_api.create_component( cls.learning_package.id, - key="my_entity_published_example", - created=cls.now, - created_by=None, - ) - cls.pe_version = publishing_api.create_publishable_entity_version( - cls.published_entity.id, - version_num=1, - title="An Entity that we'll Publish 🌴", + component_type=html_type, + local_key="my_entity_published_example", created=cls.now, created_by=None, ) @@ -186,17 +177,12 @@ def setUpTestData(cls) -> None: published_at=cls.now, ) - # Leave another PublishableEntity in Draft. - cls.draft_entity = publishing_api.create_publishable_entity( + # Leave another Component in Draft. + problem_type = components_api.get_or_create_component_type("xblock.v1", "problem") + cls.draft_component = components_api.create_component( cls.learning_package.id, - key="my_entity_draft_example", - created=cls.now, - created_by=None, - ) - cls.de_version = publishing_api.create_publishable_entity_version( - cls.draft_entity.id, - version_num=1, - title="An Entity that we'll keep in Draft 🌴", + component_type=problem_type, + local_key="my_entity_draft_example", created=cls.now, created_by=None, ) @@ -214,7 +200,7 @@ def setUpTestData(cls) -> None: created_by=None, description="This collection contains 1 object", contents_qset=PublishableEntity.objects.filter(id__in=[ - cls.published_entity.id, + cls.published_component.pk, ]), ) cls.collection2 = collection_api.create_collection( @@ -223,8 +209,8 @@ def setUpTestData(cls) -> None: created_by=None, description="This collection contains 2 objects", contents_qset=PublishableEntity.objects.filter(id__in=[ - cls.published_entity.id, - cls.draft_entity.id, + cls.published_component.pk, + cls.draft_component.pk, ]), ) cls.disabled_collection = collection_api.create_collection( @@ -233,7 +219,7 @@ def setUpTestData(cls) -> None: created_by=None, description="This disabled collection contains 1 object", contents_qset=PublishableEntity.objects.filter(id__in=[ - cls.published_entity.id, + cls.published_component.pk, ]), ) cls.disabled_collection.enabled = False @@ -245,11 +231,11 @@ def test_create_collection_contents(self): """ assert not list(self.collection0.contents.all()) assert list(self.collection1.contents.all()) == [ - self.published_entity, + self.published_component.publishable_entity, ] assert list(self.collection2.contents.all()) == [ - self.published_entity, - self.draft_entity, + self.published_component.publishable_entity, + self.draft_component.publishable_entity, ] def test_add_to_collections(self): @@ -261,13 +247,13 @@ def test_add_to_collections(self): self.collection1.id, ]), PublishableEntity.objects.filter(id__in=[ - self.draft_entity.id, + self.draft_component.pk, ]), ) assert count == 1 assert list(self.collection1.contents.all()) == [ - self.published_entity, - self.draft_entity, + self.published_component.publishable_entity, + self.draft_component.publishable_entity, ] def test_add_to_collections_again(self): @@ -280,16 +266,16 @@ def test_add_to_collections_again(self): self.collection2.id, ]), PublishableEntity.objects.filter(id__in=[ - self.published_entity.id, + self.published_component.pk, ]), ) assert count == 2 assert list(self.collection1.contents.all()) == [ - self.published_entity, + self.published_component.publishable_entity, ] assert list(self.collection2.contents.all()) == [ - self.published_entity, - self.draft_entity, + self.published_component.publishable_entity, + self.draft_component.publishable_entity, ] def test_remove_from_collections(self): @@ -303,14 +289,14 @@ def test_remove_from_collections(self): self.collection2.id, ]), PublishableEntity.objects.filter(id__in=[ - self.published_entity.id, + self.published_component.pk, ]), ) assert count == 2 assert not list(self.collection0.contents.all()) assert not list(self.collection1.contents.all()) assert list(self.collection2.contents.all()) == [ - self.draft_entity, + self.draft_component.publishable_entity, ] def test_get_object_collections(self): @@ -318,13 +304,27 @@ def test_get_object_collections(self): Tests fetching the enabled collections which contain a given object. """ collections = collection_api.get_object_collections( - self.published_entity.id, + self.published_component.pk, ) assert list(collections) == [ self.collection1, self.collection2, ] + def test_get_collection_components(self): + """ + Tests fetching the components which are members of a collection. + """ + object_ids = collection_api.get_collection_components( + self.collection2.id, + components_api.get_components(self.learning_package.id), + ) + + assert list(object_ids) == [ + self.published_component, + self.draft_component, + ] + class UpdateCollectionTestCase(CollectionTestCase): """