Skip to content
Closed
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 src/openedx_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
"""

# The version for the entire repository
__version__ = "1.0.0"
__version__ = "1.0.1"
10 changes: 4 additions & 6 deletions src/openedx_tagging/signal_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,10 @@ def _is_explicit_tag_delete(
if isinstance(origin, Tag):
return origin.pk == instance.pk

# Fail fast if origin has an unexpected type so callsites don't silently
# skip event emission logic.
if not isinstance(origin, QuerySet):
raise TypeError(f"Expected origin to be Tag, QuerySet[Tag], or None; got {type(origin).__name__}")
if origin.model is not Tag:
raise TypeError(f"Expected origin queryset model Tag; got {origin.model.__name__}")
# This is needed to prevent unit test failures where this is called when origin
# is not a Tag or QuerySet.
Comment on lines +37 to +38
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# This is needed to prevent unit test failures where this is called when origin
# is not a Tag or QuerySet.
# In the event of a CASCADE deletion (e.g. from Taxonomy), emit no events.

if not isinstance(origin, QuerySet) or origin.model is not Tag:
return False

# Check if this instance is in the set of explicitly-targeted tags. If not, it's being deleted
# as a CASCADE side-effect, so it's not explicit.
Expand Down
4 changes: 1 addition & 3 deletions tests/openedx_tagging/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from __future__ import annotations

from typing import Any
from unittest.mock import patch

import ddt # type: ignore[import]
import pytest
Expand Down Expand Up @@ -742,8 +741,7 @@ def get_object_tags():
# Now delete and disable things:
disabled_taxonomy.enabled = False
disabled_taxonomy.save()
with patch("openedx_tagging.signal_handlers._is_explicit_tag_delete", return_value=False):
self.free_text_taxonomy.delete()
self.free_text_taxonomy.delete()
tagging_api.delete_tags_from_taxonomy(self.taxonomy, ["DPANN"], with_subtags=False)

# Now retrieve the tags again:
Expand Down
27 changes: 10 additions & 17 deletions tests/openedx_tagging/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from __future__ import annotations

from typing import Any, cast
from unittest.mock import MagicMock, patch

import ddt # type: ignore[import]
Expand Down Expand Up @@ -668,20 +667,17 @@ def test_object_tag_export_id(self):
self.object_tag.save()
assert self.object_tag.export_id == self.taxonomy.export_id

# But if the taxonomy is deleted, then the object_tag's export_id reverts to our cached export_id.
# Patch explicit-delete detection because this test is about ObjectTag fallback behavior,
# not tag deletion event-origins.
with patch("openedx_tagging.signal_handlers._is_explicit_tag_delete", return_value=False):
self.taxonomy.delete()
# But if the taxonomy is deleted, then the object_tag's export_id reverts to our cached export_id
self.taxonomy.delete()
self.object_tag.refresh_from_db()
assert self.object_tag.export_id == "another-taxonomy"

def test_is_explicit_tag_delete_raises_for_unexpected_origin_type(self):
with pytest.raises(
TypeError,
match=r"Expected origin to be Tag, QuerySet\[Tag\], or None; got Taxonomy",
):
_is_explicit_tag_delete(instance=self.tag, origin=cast(Any, self.taxonomy), using="default")
def test_is_explicit_tag_delete_returns_false_for_unexpected_origin_type(self):
assert _is_explicit_tag_delete(
instance=self.tag,
origin=self.taxonomy,
using="default",
) is False

def test_object_tag_value(self):
# ObjectTag's value defaults to its tag's value
Expand Down Expand Up @@ -839,11 +835,8 @@ def test_is_deleted(self):
(self.bacteria.value, True), # <--- deleted! But the value is preserved.
]

# Then delete the whole free text taxonomy.
# Patch explicit-delete detection because this
# test validates ObjectTag deleted-state behavior, not tag deletion event-origins.
with patch("openedx_tagging.signal_handlers._is_explicit_tag_delete", return_value=False):
self.free_text_taxonomy.delete()
# Then delete the whole free text taxonomy
self.free_text_taxonomy.delete()

assert [(t.value, t.is_deleted) for t in api.get_object_tags(object_id, include_deleted=True)] == [
("bar", True), # <--- Deleted, but the value is preserved
Expand Down