From 7ff1506d3291d2fab2f81f24e76ab28155260abf Mon Sep 17 00:00:00 2001 From: Jillian Date: Wed, 29 Nov 2023 04:07:26 +1030 Subject: [PATCH] fix: allows viewing an ObjectTag even if no taxonomy is provided (#33757) --- .../rest_api/v1/tests/test_views.py | 38 +++++++++++++++++-- .../core/djangoapps/content_tagging/rules.py | 4 +- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py b/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py index 9a8147464be0..bfaf9760c4a1 100644 --- a/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py +++ b/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py @@ -44,6 +44,7 @@ TAXONOMY_ORG_DETAIL_URL = "/api/content_tagging/v1/taxonomies/{pk}/" TAXONOMY_ORG_UPDATE_ORG_URL = "/api/content_tagging/v1/taxonomies/{pk}/orgs/" OBJECT_TAG_UPDATE_URL = "/api/content_tagging/v1/object_tags/{object_id}/?taxonomy={taxonomy_id}" +OBJECT_TAGS_URL = "/api/content_tagging/v1/object_tags/{object_id}/" TAXONOMY_TEMPLATE_URL = "/api/content_tagging/v1/taxonomies/import/{filename}" TAXONOMY_CREATE_IMPORT_URL = "/api/content_tagging/v1/taxonomies/import/" TAXONOMY_TAGS_IMPORT_URL = "/api/content_tagging/v1/taxonomies/{pk}/tags/import/" @@ -1298,9 +1299,6 @@ class TestObjectTagViewSet(TestObjectTagMixin, APITestCase): Testing various cases for the ObjectTagView. """ - def test_get_tags(self): - pass - @ddt.data( # userA and userS are staff in courseA and can tag using enabled taxonomies ("user", "tA1", ["Tag 1"], status.HTTP_403_FORBIDDEN), @@ -1503,6 +1501,40 @@ def test_tag_unauthorized(self, objectid_attr): assert response.status_code == status.HTTP_401_UNAUTHORIZED + def test_get_tags(self): + self.client.force_authenticate(user=self.staffA) + taxonomy = self.multiple_taxonomy + tag_values = ["Tag 1", "Tag 2"] + put_url = OBJECT_TAG_UPDATE_URL.format(object_id=self.courseA, taxonomy_id=taxonomy.pk) + + # Tag an object + response1 = self.client.put(put_url, {"tags": tag_values}, format="json") + assert status.is_success(response1.status_code) + + # Fetch this object's tags for a single taxonomy + expected_tags = [{ + 'editable': True, + 'name': 'Multiple Taxonomy', + 'taxonomy_id': taxonomy.pk, + 'tags': [ + {'value': 'Tag 1', 'lineage': ['Tag 1']}, + {'value': 'Tag 2', 'lineage': ['Tag 2']}, + ], + }] + + # Fetch tags for a single taxonomy + get_url = OBJECT_TAGS_URL.format(object_id=self.courseA) + get_url += f"?taxonomy={taxonomy.pk}" + response2 = self.client.get(get_url, format="json") + assert status.is_success(response2.status_code) + assert response2.data[str(self.courseA)]["taxonomies"] == expected_tags + + # Fetch all of this object's tags, for all taxonomies + get_all_url = OBJECT_TAGS_URL.format(object_id=self.courseA) + response3 = self.client.get(get_all_url, format="json") + assert status.is_success(response3.status_code) + assert response3.data[str(self.courseA)]["taxonomies"] == expected_tags + @skip_unless_cms @ddt.ddt diff --git a/openedx/core/djangoapps/content_tagging/rules.py b/openedx/core/djangoapps/content_tagging/rules.py index 348ab52c6aeb..f3d0b70c3093 100644 --- a/openedx/core/djangoapps/content_tagging/rules.py +++ b/openedx/core/djangoapps/content_tagging/rules.py @@ -239,7 +239,9 @@ def can_view_object_tag_taxonomy(user: UserType, taxonomy: oel_tagging.Taxonomy) This rule is different from can_view_taxonomy because it checks if the taxonomy is enabled. """ - return taxonomy.cast().enabled and can_view_taxonomy(user, taxonomy) + # Note: in the REST API, where we're dealing with multiple taxonomies at once, permissions + # are also enforced by ObjectTagTaxonomyOrgFilterBackend. + return not taxonomy or (taxonomy.cast().enabled and can_view_taxonomy(user, taxonomy)) @rules.predicate