Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: return publishing information on get component endpoint [FC-0062] #35476

19 changes: 18 additions & 1 deletion openedx/core/djangoapps/content_libraries/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,12 @@ class LibraryXBlockMetadata:
modified = attr.ib(type=datetime)
display_name = attr.ib("")
last_published = attr.ib(default=None, type=datetime)
last_draft_created = attr.ib(default=None, type=datetime)
last_draft_created_by = attr.ib(default=None, type=datetime)
rpenido marked this conversation as resolved.
Show resolved Hide resolved
published_by = attr.ib("")
has_unpublished_changes = attr.ib(False)
tags_count = attr.ib(0)
created = attr.ib(default=None, type=datetime)

@classmethod
def from_component(cls, library_key, component):
Expand All @@ -228,6 +232,16 @@ def from_component(cls, library_key, component):
"""
last_publish_log = component.versioning.last_publish_log

published_by = None
if last_publish_log and last_publish_log.published_by:
published_by = last_publish_log.published_by.username

last_draft_log = authoring_api.get_entities_with_unpublished_changes(component.pk) \
.order_by('-created').first()
last_draft_created = last_draft_log.created if last_draft_log else None
last_draft_created_by = \
last_draft_log.created_by.username if last_draft_log and last_draft_log.created_by else None
rpenido marked this conversation as resolved.
Show resolved Hide resolved

return cls(
usage_key=LibraryUsageLocatorV2(
library_key,
Expand All @@ -238,7 +252,10 @@ def from_component(cls, library_key, component):
created=component.created,
modified=component.versioning.draft.created,
last_published=None if last_publish_log is None else last_publish_log.published_at,
has_unpublished_changes=component.versioning.has_unpublished_changes
published_by=published_by,
last_draft_created=last_draft_created,
last_draft_created_by=last_draft_created_by,
has_unpublished_changes=component.versioning.has_unpublished_changes,
)


Expand Down
5 changes: 5 additions & 0 deletions openedx/core/djangoapps/content_libraries/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,12 @@ class LibraryXBlockMetadataSerializer(serializers.Serializer):

block_type = serializers.CharField(source="usage_key.block_type")
display_name = serializers.CharField(read_only=True)
last_published = serializers.DateTimeField(format=DATETIME_FORMAT, read_only=True)
published_by = serializers.CharField(read_only=True)
last_draft_created = serializers.DateTimeField(format=DATETIME_FORMAT, read_only=True)
last_draft_created_by = serializers.CharField(read_only=True)
has_unpublished_changes = serializers.BooleanField(read_only=True)
created = serializers.DateTimeField(format=DATETIME_FORMAT, read_only=True)

# When creating a new XBlock in a library, the slug becomes the ID part of
# the definition key and usage key:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
from unittest import skip

import ddt
from datetime import datetime, timezone
from uuid import uuid4
from django.contrib.auth.models import Group
from django.test.client import Client
from freezegun import freeze_time
from organizations.models import Organization
from rest_framework.test import APITestCase

Expand Down Expand Up @@ -287,10 +289,14 @@ def test_library_blocks(self):
assert self._get_library(lib_id)['has_unpublished_changes'] is True

# Publish the changes:
self._commit_library_changes(lib_id)
updated_date = datetime(2024, 6, 7, 8, 9, 10, tzinfo=timezone.utc)
with freeze_time(updated_date):
self._commit_library_changes(lib_id)
assert self._get_library(lib_id)['has_unpublished_changes'] is False
# And now the block information should also show that block has no unpublished changes:
block_data["has_unpublished_changes"] = False
block_data["last_published"] = updated_date.isoformat().replace('+00:00', 'Z')
block_data["published_by"] = "Bob"
pomegranited marked this conversation as resolved.
Show resolved Hide resolved
self.assertDictContainsEntries(self._get_library_block(block_id), block_data)
assert self._get_library_blocks(lib_id)['results'] == [block_data]

Expand Down Expand Up @@ -372,10 +378,14 @@ def test_library_blocks_studio_view(self):
assert self._get_library(lib_id)['has_unpublished_changes'] is True

# Publish the changes:
self._commit_library_changes(lib_id)
updated_date = datetime(2024, 6, 7, 8, 9, 10, tzinfo=timezone.utc)
with freeze_time(updated_date):
self._commit_library_changes(lib_id)
assert self._get_library(lib_id)['has_unpublished_changes'] is False
# And now the block information should also show that block has no unpublished changes:
block_data["has_unpublished_changes"] = False
block_data["last_published"] = updated_date.isoformat().replace('+00:00', 'Z')
block_data["published_by"] = "Bob"
self.assertDictContainsEntries(self._get_library_block(block_id), block_data)
assert self._get_library_blocks(lib_id)['results'] == [block_data]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ def test_build_library_object_tree(self) -> None:
"""
Test if we can export a library
"""
with self.assertNumQueries(8):
with self.assertNumQueries(11):
pomegranited marked this conversation as resolved.
Show resolved Hide resolved
tagged_library = build_object_tree_with_objecttags(self.library.key, self.all_library_object_tags)

assert tagged_library == self.expected_library_tagged_xblock
Expand Down
Loading