Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion openedx_learning/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Open edX Learning ("Learning Core").
"""

__version__ = "0.16.3"
__version__ = "0.17.0"
40 changes: 38 additions & 2 deletions openedx_learning/apps/authoring/collections/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
from django.db.models import QuerySet

from ..publishing import api as publishing_api
from ..publishing.models import PublishableEntity
from .models import Collection
from ..publishing.models import PublishableEntity, Published
from .models import Collection, CollectionPublishableEntity

# The public API that will be re-exported by openedx_learning.apps.authoring.api
# is listed in the __all__ entries below. Internal helper functions that are
Expand All @@ -27,6 +27,7 @@
"remove_from_collection",
"restore_collection",
"update_collection",
"remove_unpublished_from_collections",
]


Expand Down Expand Up @@ -204,3 +205,38 @@ def get_collections(learning_package_id: int, enabled: bool | None = True) -> Qu
if enabled is not None:
qs = qs.filter(enabled=enabled)
return qs.select_related("learning_package").order_by('pk')


def remove_unpublished_from_collections(learning_package_id: int) -> None:
"""
Removes all unpublished entities from collections for a
given learning package.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChrisChV Can you please add an explanation/example of why we need this API, and what it's used for?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also as part of the PR and commit message please :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


One use case for this function is when reverting a library to published version.
If a collection of a library has unpublished entities and the library is reverted
to the published version, the unpublished entities need to be removed
to reflect the published state of the library.
"""
collections = get_collections(learning_package_id)

all_entities = CollectionPublishableEntity.objects.filter(
collection__learning_package__id=learning_package_id
).values_list('entity_id', flat=True)

entities_with_version = Published.objects.select_related("version").filter(
entity_id__in=all_entities
).values_list('entity_id', flat=True)

for collection in collections:
entities_for_remove = []

for entity in collection.entities.all():
if entity.id not in entities_with_version:
entities_for_remove.append(entity.id)

if entities_for_remove:
remove_from_collection(
learning_package_id,
collection.key,
PublishableEntity.objects.filter(id__in=entities_for_remove)
)
16 changes: 16 additions & 0 deletions tests/openedx_learning/apps/authoring/collections/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,22 @@ def test_get_collection_components(self):
self.collection3.key,
))

def test_remove_unpublished_components(self):
api.remove_unpublished_from_collections(self.learning_package.id)

assert list(api.get_collection_components(
self.learning_package.id,
self.collection1.key,
)) == [self.published_component]
assert list(api.get_collection_components(
self.learning_package.id,
self.collection2.key,
)) == [self.published_component]
assert not list(api.get_collection_components(
self.learning_package.id,
self.collection3.key,
))


class UpdateCollectionTestCase(CollectionTestCase):
"""
Expand Down