Skip to content
Merged
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
@@ -1,4 +1,4 @@
"""
Open edX Learning ("Learning Core").
"""
__version__ = "0.10.0"
__version__ = "0.10.1"
2 changes: 2 additions & 0 deletions openedx_learning/apps/authoring/components/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ class Component(PublishableEntityMixin): # type: ignore[django-manager-missing]
'publishable_entity__draft__version__componentversion',
'publishable_entity__published__version',
'publishable_entity__published__version__componentversion',
'publishable_entity__published__publish_log_record',
'publishable_entity__published__publish_log_record__publish_log',
)

# This foreign key is technically redundant because we're already locked to
Expand Down
12 changes: 12 additions & 0 deletions openedx_learning/apps/authoring/publishing/model_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,18 @@ def has_unpublished_changes(self):

return draft_version_id != published_version_id

@property
def last_publish_log(self):
"""
Return the most recent PublishLog for this component.

Return None if the component is not published.
"""
pub_entity = self.content_obj.publishable_entity
if hasattr(pub_entity, 'published'):
return pub_entity.published.publish_log_record.publish_log
return None

@property
def versions(self):
"""
Expand Down
3 changes: 3 additions & 0 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ filelock==3.15.4
# -r requirements/ci.txt
# tox
# virtualenv
freezegun==1.5.1
# via -r requirements/quality.txt
grimp==3.4.1
# via
# -r requirements/ci.txt
Expand Down Expand Up @@ -391,6 +393,7 @@ python-dateutil==2.9.0.post0
# via
# -r requirements/quality.txt
# celery
# freezegun
python-slugify==8.0.4
# via
# -r requirements/quality.txt
Expand Down
3 changes: 3 additions & 0 deletions requirements/doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ edx-opaque-keys==2.10.0
# via
# -r requirements/test.txt
# edx-drf-extensions
freezegun==1.5.1
# via -r requirements/test.txt
grimp==3.4.1
# via
# -r requirements/test.txt
Expand Down Expand Up @@ -253,6 +255,7 @@ python-dateutil==2.9.0.post0
# via
# -r requirements/test.txt
# celery
# freezegun
python-slugify==8.0.4
# via
# -r requirements/test.txt
Expand Down
3 changes: 3 additions & 0 deletions requirements/quality.txt
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ edx-opaque-keys==2.10.0
# via
# -r requirements/test.txt
# edx-drf-extensions
freezegun==1.5.1
# via -r requirements/test.txt
grimp==3.4.1
# via
# -r requirements/test.txt
Expand Down Expand Up @@ -292,6 +294,7 @@ python-dateutil==2.9.0.post0
# via
# -r requirements/test.txt
# celery
# freezegun
python-slugify==8.0.4
# via
# -r requirements/test.txt
Expand Down
1 change: 1 addition & 0 deletions requirements/test.in
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ mypy # static type checking
django-stubs # Typing stubs for Django, so it works with mypy
djangorestframework-stubs # Typing stubs for DRF
django-debug-toolbar # provides a debug toolbar for Django
freezegun # Allows tests to mock the output of assorted datetime module functions
3 changes: 3 additions & 0 deletions requirements/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ edx-opaque-keys==2.10.0
# via
# -r requirements/base.txt
# edx-drf-extensions
freezegun==1.5.1
# via -r requirements/test.in
grimp==3.4.1
# via import-linter
idna==3.7
Expand Down Expand Up @@ -198,6 +200,7 @@ python-dateutil==2.9.0.post0
# via
# -r requirements/base.txt
# celery
# freezegun
python-slugify==8.0.4
# via code-annotations
pyyaml==6.0.1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def test_component_num_queries(self) -> None:
draft = component.versioning.draft
published = component.versioning.published
assert draft.title == published.title
assert component.versioning.last_publish_log.published_at == self.now


class GetComponentsTestCase(ComponentTestCase):
Expand Down
86 changes: 85 additions & 1 deletion tests/openedx_learning/apps/authoring/components/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@
"""
from datetime import datetime, timezone

from freezegun import freeze_time

from openedx_learning.apps.authoring.components.api import (
create_component_and_version,
get_component,
get_or_create_component_type,
)
from openedx_learning.apps.authoring.components.models import ComponentType
from openedx_learning.apps.authoring.publishing.api import LearningPackage, create_learning_package, publish_all_drafts
from openedx_learning.apps.authoring.publishing.api import (
LearningPackage,
create_learning_package,
create_publishable_entity_version,
publish_all_drafts,
)
from openedx_learning.lib.test_utils import TestCase


Expand Down Expand Up @@ -53,3 +60,80 @@ def test_latest_version(self) -> None:

# Grabbing the list of versions for this component
assert list(component.versioning.versions) == [component_version]

def test_last_publish_log(self):
"""
Test last_publish_log versioning property for published Components.
"""
# This Component will get a couple of Published versions
component_with_changes, _ = create_component_and_version(
self.learning_package.id,
component_type=self.problem_type,
local_key="with_changes",
title="Component with changes v1",
created=self.now,
created_by=None,
)

# This Component will only be Published once.
component_with_no_changes, _ = create_component_and_version(
self.learning_package.id,
component_type=self.problem_type,
local_key="with_no_changes",
title="Component with no changes v1",
created=self.now,
created_by=None,
)

# Publish first time.
published_first_time = datetime(2024, 5, 6, 7, 8, 9, tzinfo=timezone.utc)
with freeze_time(published_first_time):
publish_all_drafts(self.learning_package.id)

# Refetch the entities to get latest versions
component_with_changes = get_component(component_with_changes.pk)
component_with_no_changes = get_component(component_with_no_changes.pk)

# Fetch the most recent PublishLog for these components
first_publish_log_for_component_with_changes = component_with_changes.versioning.last_publish_log
first_publish_log_for_component_with_no_changes = component_with_no_changes.versioning.last_publish_log

# PublishLog for library + both entities should match each other
assert (
published_first_time ==
first_publish_log_for_component_with_changes.published_at ==
first_publish_log_for_component_with_no_changes.published_at
)

# Modify component_with_changes
create_publishable_entity_version(
component_with_changes.publishable_entity.id,
version_num=2,
title="Component with changes v2",
created=self.now,
created_by=None,
)

# Publish second time
published_second_time = datetime(2024, 5, 6, 7, 8, 9, tzinfo=timezone.utc)
with freeze_time(published_second_time):
publish_all_drafts(self.learning_package.id)

# Refetch the entities to get latest versions
component_with_changes = get_component(component_with_changes.pk)
component_with_no_changes = get_component(component_with_no_changes.pk)

# Re-fetch the most recent PublishLog for these components
next_publish_log_for_component_with_changes = component_with_changes.versioning.last_publish_log
next_publish_log_for_component_with_no_changes = component_with_no_changes.versioning.last_publish_log

# PublishLog for component_with_changes should have been updated
assert (
published_second_time ==
next_publish_log_for_component_with_changes.published_at
)
# But the component_with_no_changes should still be on the original publish log
assert (
first_publish_log_for_component_with_no_changes ==
next_publish_log_for_component_with_no_changes
)