Skip to content

Commit

Permalink
chore: updates for compatibility with master changes
Browse files Browse the repository at this point in the history
  • Loading branch information
bradenmacdonald committed Oct 25, 2023
1 parent 72e782b commit 7cbaaf6
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 31 deletions.
4 changes: 2 additions & 2 deletions openedx_tagging/core/tagging/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"""
from __future__ import annotations

from typing import TYPE_CHECKING, Any, TypedDict, NotRequired
from typing import TYPE_CHECKING, Any, TypedDict

from django.db.models import QuerySet
from typing_extensions import TypeAlias
from typing_extensions import NotRequired, TypeAlias


class TagData(TypedDict):
Expand Down
22 changes: 15 additions & 7 deletions openedx_tagging/core/tagging/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,16 @@ def get_lineage(self) -> Lineage:
return lineage

@cached_property
def num_ancestors(self) -> int:
def depth(self) -> int:
"""
How many ancestors this Tag has. Equivalent to its "depth" in the tree.
Zero for root tags.
How many ancestors this Tag has. Zero for root tags.
"""
num_ancestors = 0
depth = 0
tag = self
while tag.parent:
num_ancestors += 1
depth += 1
tag = tag.parent
return num_ancestors
return depth

@staticmethod
def annotate_depth(qs: models.QuerySet) -> models.QuerySet:
Expand All @@ -141,6 +140,15 @@ def annotate_depth(qs: models.QuerySet) -> models.QuerySet:
default=4,
))

@cached_property
def child_count(self) -> int:
"""
How many child tags this tag has in the taxonomy.
"""
if self.taxonomy and not self.taxonomy.allow_free_text:
return self.taxonomy.tag_set.filter(parent=self).count()
return 0


class Taxonomy(models.Model):
"""
Expand Down Expand Up @@ -394,7 +402,7 @@ def _get_filtered_tags_one_level(
if parent_tag_value:
parent_tag = self.tag_for_value(parent_tag_value)
qs: models.QuerySet = self.tag_set.filter(parent_id=parent_tag.pk)
qs = qs.annotate(depth=Value(parent_tag.num_ancestors + 1))
qs = qs.annotate(depth=Value(parent_tag.depth + 1))
# Use parent_tag.value not parent_tag_value because they may differ in case
qs = qs.annotate(parent_value=Value(parent_tag.value))
else:
Expand Down
22 changes: 17 additions & 5 deletions openedx_tagging/core/tagging/rest_api/v1/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from rest_framework.reverse import reverse

from openedx_tagging.core.tagging.data import TagData
from openedx_tagging.core.tagging.models import ObjectTag, Taxonomy
from openedx_tagging.core.tagging.models import ObjectTag, Tag, Taxonomy


class TaxonomyListQueryParamsSerializer(serializers.Serializer): # pylint: disable=abstract-method
Expand Down Expand Up @@ -95,7 +95,7 @@ class ObjectTagUpdateQueryParamsSerializer(serializers.Serializer): # pylint: d

class TagDataSerializer(serializers.Serializer):
"""
Serializer for TagData
Serializer for TagData dicts. Also can serialize Tag instances.
Adds a link to get the sub tags
"""
Expand All @@ -111,12 +111,14 @@ class TagDataSerializer(serializers.Serializer):

sub_tags_url = serializers.SerializerMethodField()

def get_sub_tags_url(self, obj: TagData):
def get_sub_tags_url(self, obj: TagData | Tag):
"""
Returns URL for the list of child tags of the current tag.
"""
if obj["child_count"] > 0 and "taxonomy_id" in self.context:
query_params = f"?parent_tag={obj['value']}"
child_count = obj.child_count if isinstance(obj, Tag) else obj["child_count"]
if child_count > 0 and "taxonomy_id" in self.context:
value = obj.value if isinstance(obj, Tag) else obj["value"]
query_params = f"?parent_tag={value}"
request = self.context["request"]
url_namespace = request.resolver_match.namespace # get the namespace, usually "oel_tagging"
url = (
Expand All @@ -125,6 +127,16 @@ def get_sub_tags_url(self, obj: TagData):
)
return request.build_absolute_uri(url)
return None

def to_representation(self, value: TagData | Tag):
"""
Convert this TagData (or Tag model instance) to the serialized dictionary
"""
data = super().to_representation(value)
if isinstance(value, Tag):
data["_id"] = value.pk # The ID field won't otherwise be detected.
data["parent_value"] = value.parent.value if value.parent else None
return data

def update(self, instance, validated_data):
raise RuntimeError('`update()` is not supported by the TagData serializer.')
Expand Down
29 changes: 12 additions & 17 deletions tests/openedx_tagging/core/tagging/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1365,13 +1365,12 @@ def test_create_tag_in_taxonomy(self):

data = response.data

self.assertIsNotNone(data.get("id"))
self.assertIsNotNone(data.get("_id"))
self.assertEqual(data.get("value"), new_tag_value)
self.assertEqual(data.get("taxonomy_id"), self.small_taxonomy.pk)
self.assertIsNone(data.get("parent_id"))
self.assertIsNone(data.get("parent_value"))
self.assertIsNone(data.get("external_id"))
self.assertIsNone(data.get("sub_tags_link"))
self.assertEqual(data.get("children_count"), 0)
self.assertEqual(data.get("child_count"), 0)

def test_create_tag_in_taxonomy_with_parent(self):
self.client.force_authenticate(user=self.staff)
Expand All @@ -1393,13 +1392,12 @@ def test_create_tag_in_taxonomy_with_parent(self):

data = response.data

self.assertIsNotNone(data.get("id"))
self.assertIsNotNone(data.get("_id"))
self.assertEqual(data.get("value"), new_tag_value)
self.assertEqual(data.get("taxonomy_id"), self.small_taxonomy.pk)
self.assertEqual(data.get("parent_id"), parent_tag.id)
self.assertEqual(data.get("parent_value"), parent_tag.value)
self.assertEqual(data.get("external_id"), new_external_id)
self.assertIsNone(data.get("sub_tags_link"))
self.assertEqual(data.get("children_count"), 0)
self.assertEqual(data.get("child_count"), 0)

def test_create_tag_in_invalid_taxonomy(self):
self.client.force_authenticate(user=self.staff)
Expand Down Expand Up @@ -1565,10 +1563,9 @@ def test_update_tag_in_taxonomy_with_different_methods(self):
data = response.data

# Check that Tag value got updated
self.assertEqual(data.get("id"), existing_tag.id)
self.assertEqual(data.get("_id"), existing_tag.id)
self.assertEqual(data.get("value"), updated_tag_value)
self.assertEqual(data.get("taxonomy_id"), self.small_taxonomy.pk)
self.assertEqual(data.get("parent_id"), existing_tag.parent)
self.assertEqual(data.get("parent_value"), existing_tag.parent)
self.assertEqual(data.get("external_id"), existing_tag.external_id)

# Test updating using the PATCH method
Expand All @@ -1583,10 +1580,9 @@ def test_update_tag_in_taxonomy_with_different_methods(self):
data = response.data

# Check the Tag value got updated again
self.assertEqual(data.get("id"), existing_tag.id)
self.assertEqual(data.get("_id"), existing_tag.id)
self.assertEqual(data.get("value"), updated_tag_value_2)
self.assertEqual(data.get("taxonomy_id"), self.small_taxonomy.pk)
self.assertEqual(data.get("parent_id"), existing_tag.parent)
self.assertEqual(data.get("parent_value"), existing_tag.parent)
self.assertEqual(data.get("external_id"), existing_tag.external_id)

def test_update_tag_in_taxonomy_reflects_changes_in_object_tags(self):
Expand Down Expand Up @@ -1626,10 +1622,9 @@ def test_update_tag_in_taxonomy_reflects_changes_in_object_tags(self):
data = response.data

# Check that Tag value got updated
self.assertEqual(data.get("id"), existing_tag.id)
self.assertEqual(data.get("_id"), existing_tag.id)
self.assertEqual(data.get("value"), updated_tag_value)
self.assertEqual(data.get("taxonomy_id"), self.small_taxonomy.pk)
self.assertEqual(data.get("parent_id"), existing_tag.parent)
self.assertEqual(data.get("parent_value"), None)
self.assertEqual(data.get("external_id"), existing_tag.external_id)

# Check that the ObjectTags got updated as well
Expand Down

0 comments on commit 7cbaaf6

Please sign in to comment.