Skip to content

Commit

Permalink
feat: option to include deleted drafts while fetching unpublished ent…
Browse files Browse the repository at this point in the history
…ities [FC-0062] (#207)

By default, this is set to False.
  • Loading branch information
navinkarkera authored Aug 16, 2024
1 parent eb34c15 commit 534316b
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
34 changes: 30 additions & 4 deletions openedx_learning/apps/authoring/publishing/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,36 @@ def get_all_drafts(learning_package_id: int, /) -> QuerySet[Draft]:
)


def get_entities_with_unpublished_changes(learning_package_id: int, /) -> QuerySet[PublishableEntity]:
return PublishableEntity.objects \
.filter(learning_package_id=learning_package_id) \
.exclude(draft__version=F('published__version'))
def get_entities_with_unpublished_changes(
learning_package_id: int,
/,
include_deleted_drafts: bool = False
) -> QuerySet[PublishableEntity]:
"""
Fetch entities that have unpublished changes.
By default, this excludes soft-deleted drafts but can be included using include_deleted_drafts option.
"""
entities_qs = (
PublishableEntity.objects
.filter(learning_package_id=learning_package_id)
.exclude(draft__version=F('published__version'))
)

if include_deleted_drafts:
# This means that we should also return PublishableEntities where the draft
# has been soft-deleted, but that deletion has not been published yet. Just
# excluding records where the Draft and Published versions don't match won't
# be enough here, because that will return soft-deletes that have already
# been published (since NULL != NULL in SQL).
#
# So we explicitly exclude already-published soft-deletes:
return entities_qs.exclude(
Q(draft__version__isnull=True) & Q(published__version__isnull=True)
)

# Simple case: exclude all entities that have been soft-deleted.
return entities_qs.exclude(draft__version__isnull=True)


def get_entities_with_unpublished_deletes(learning_package_id: int, /) -> QuerySet[PublishableEntity]:
Expand Down
41 changes: 41 additions & 0 deletions tests/openedx_learning/apps/authoring/publishing/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,47 @@ def test_reset_drafts_to_published(self) -> None:
pub_version_num
)

def test_get_entities_with_unpublished_changes(self) -> None:
"""Test fetching entities with unpublished changes after soft deletes."""
entity = publishing_api.create_publishable_entity(
self.learning_package.id,
"my_entity",
created=self.now,
created_by=None,
)
publishing_api.create_publishable_entity_version(
entity.id,
version_num=1,
title="An Entity 🌴",
created=self.now,
created_by=None,
)

# Fetch unpublished entities
entities = publishing_api.get_entities_with_unpublished_changes(self.learning_package.id)
records = list(entities.all())
assert len(records) == 1
record = records[0]
assert record.id == entity.id

# Initial publish
publishing_api.publish_all_drafts(self.learning_package.id)

# soft-delete entity
publishing_api.soft_delete_draft(entity.id)
entities = publishing_api.get_entities_with_unpublished_changes(self.learning_package.id)
assert len(entities) == 0
entities = publishing_api.get_entities_with_unpublished_changes(self.learning_package.id,
include_deleted_drafts=True)
assert len(entities) == 1

# publish soft-delete
publishing_api.publish_all_drafts(self.learning_package.id)
entities = publishing_api.get_entities_with_unpublished_changes(self.learning_package.id,
include_deleted_drafts=True)
# should not return published soft-deleted entities.
assert len(entities) == 0

def _get_published_version_num(self, entity: PublishableEntity) -> int | None:
published_version = publishing_api.get_published_version(entity.id)
if published_version is not None:
Expand Down

0 comments on commit 534316b

Please sign in to comment.