From 679863c46cc7d79c81a2252ed940e36fb7026933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B4mulo=20Penido?= Date: Thu, 12 Sep 2024 10:56:42 -0300 Subject: [PATCH] feat: return publishing information on get component endpoint --- .../core/djangoapps/content_libraries/api.py | 19 ++++++++++++++++++- .../content_libraries/serializers.py | 5 +++++ .../tests/test_content_libraries.py | 14 ++++++++++++-- .../tests/test_objecttag_export_helpers.py | 2 +- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index 00110143456a..0448ee9cc6ac 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -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) + 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): @@ -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 + return cls( usage_key=LibraryUsageLocatorV2( library_key, @@ -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, ) diff --git a/openedx/core/djangoapps/content_libraries/serializers.py b/openedx/core/djangoapps/content_libraries/serializers.py index 2062f96d93ae..e9e04646ace4 100644 --- a/openedx/core/djangoapps/content_libraries/serializers.py +++ b/openedx/core/djangoapps/content_libraries/serializers.py @@ -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: diff --git a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py index 95b7309b3cd1..08f777c68e57 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py @@ -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 @@ -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" self.assertDictContainsEntries(self._get_library_block(block_id), block_data) assert self._get_library_blocks(lib_id)['results'] == [block_data] @@ -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] diff --git a/openedx/core/djangoapps/content_tagging/tests/test_objecttag_export_helpers.py b/openedx/core/djangoapps/content_tagging/tests/test_objecttag_export_helpers.py index d3306844ac40..f84ad4e6df72 100644 --- a/openedx/core/djangoapps/content_tagging/tests/test_objecttag_export_helpers.py +++ b/openedx/core/djangoapps/content_tagging/tests/test_objecttag_export_helpers.py @@ -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): tagged_library = build_object_tree_with_objecttags(self.library.key, self.all_library_object_tags) assert tagged_library == self.expected_library_tagged_xblock