diff --git a/openedx_learning/__init__.py b/openedx_learning/__init__.py index f2c501ee..387eb560 100644 --- a/openedx_learning/__init__.py +++ b/openedx_learning/__init__.py @@ -2,4 +2,4 @@ Open edX Learning ("Learning Core"). """ -__version__ = "0.19.0" +__version__ = "0.19.1" diff --git a/openedx_learning/apps/authoring/publishing/api.py b/openedx_learning/apps/authoring/publishing/api.py index 30f9ec5c..1f24ca67 100644 --- a/openedx_learning/apps/authoring/publishing/api.py +++ b/openedx_learning/apps/authoring/publishing/api.py @@ -71,6 +71,8 @@ "create_container_version", "create_next_container_version", "get_container", + "get_container_by_key", + "get_containers", "ContainerEntityListEntry", "get_entities_in_container", "contains_unpublished_changes", @@ -847,6 +849,43 @@ def get_container(pk: int) -> Container: return Container.objects.get(pk=pk) +def get_container_by_key(learning_package_id: int, /, key: str) -> Container: + """ + [ 🛑 UNSTABLE ] + Get a container by its learning package and primary key. + + Args: + learning_package_id: The ID of the learning package that contains the container. + key: The primary key of the container. + + Returns: + The container with the given primary key. + """ + return Container.objects.get( + publishable_entity__learning_package_id=learning_package_id, + publishable_entity__key=key, + ) + + +def get_containers( + learning_package_id: int, + container_cls: type[ContainerModel] = Container, # type: ignore[assignment] +) -> QuerySet[ContainerModel]: + """ + [ 🛑 UNSTABLE ] + Get all containers in the given learning package. + + Args: + learning_package_id: The primary key of the learning package + container_cls: The subclass of Container to use, if applicable + + Returns: + A queryset containing the container associated with the given learning package. + """ + assert issubclass(container_cls, Container) + return container_cls.objects.filter(publishable_entity__learning_package=learning_package_id) + + @dataclass(frozen=True) class ContainerEntityListEntry: """ diff --git a/tests/openedx_learning/apps/authoring/units/test_api.py b/tests/openedx_learning/apps/authoring/units/test_api.py index 103de163..35b59d81 100644 --- a/tests/openedx_learning/apps/authoring/units/test_api.py +++ b/tests/openedx_learning/apps/authoring/units/test_api.py @@ -90,6 +90,38 @@ def test_get_unit(self): with self.assertNumQueries(0): assert result.versioning.has_unpublished_changes + def test_get_unit_version(self): + """ + Test get_unit_version() + """ + unit = self.create_unit_with_components([]) + draft = unit.versioning.draft + with self.assertNumQueries(1): + result = authoring_api.get_unit_version(draft.pk) + assert result == draft + + def test_get_latest_unit_version(self): + """ + Test test_get_latest_unit_version() + """ + unit = self.create_unit_with_components([]) + draft = unit.versioning.draft + with self.assertNumQueries(2): + result = authoring_api.get_latest_unit_version(unit.pk) + assert result == draft + + def test_get_containers(self): + """ + Test get_containers() + """ + unit = self.create_unit_with_components([]) + with self.assertNumQueries(1): + result = list(authoring_api.get_containers(self.learning_package.id)) + assert result == [unit.container] + # Versioning data should be pre-loaded via select_related() + with self.assertNumQueries(0): + assert result[0].versioning.has_unpublished_changes + def test_get_container(self): """ Test get_container() @@ -102,6 +134,21 @@ def test_get_container(self): with self.assertNumQueries(0): assert result.versioning.has_unpublished_changes + def test_get_container_by_key(self): + """ + Test get_container_by_key() + """ + unit = self.create_unit_with_components([]) + with self.assertNumQueries(1): + result = authoring_api.get_container_by_key( + self.learning_package.id, + key=unit.publishable_entity.key, + ) + assert result == unit.container + # Versioning data should be pre-loaded via select_related() + with self.assertNumQueries(0): + assert result.versioning.has_unpublished_changes + def test_unit_container_versioning(self): """ Test that the .versioning helper of a Unit returns a UnitVersion, and @@ -807,6 +854,8 @@ def test_snapshots_of_published_unit(self): # At first the unit has one component (unpinned): unit = self.create_unit_with_components([self.component_1]) self.modify_component(self.component_1, title="Component 1 as of checkpoint 1") + before_publish = authoring_api.get_components_in_published_unit_as_of(unit, 0) + assert before_publish is None # Publish everything, creating Checkpoint 1 checkpoint_1 = authoring_api.publish_all_drafts(self.learning_package.id, message="checkpoint 1")