Skip to content

Commit

Permalink
fix: allows taxonomy list to "filter by org" even if org does not exi…
Browse files Browse the repository at this point in the history
…st (#33686)

If the user requests the taxonomies linked to a non-existent org, then
we still want to see the non-org taxonomies.
  • Loading branch information
pomegranited authored Nov 9, 2023
1 parent cca1e9e commit dad31a3
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from __future__ import annotations

from django.core.exceptions import ObjectDoesNotExist
from rest_framework import serializers, fields

from openedx_tagging.core.tagging.rest_api.v1.serializers import (
Expand All @@ -14,12 +15,33 @@
from organizations.models import Organization


class OptionalSlugRelatedField(serializers.SlugRelatedField):
"""
Modifies the DRF serializer SlugRelatedField.
Non-existent slug values are represented internally as an empty queryset, instead of throwing a validation error.
"""

def to_internal_value(self, data):
"""
Returns the object related to the given slug value, or an empty queryset if not found.
"""

queryset = self.get_queryset()
try:
return queryset.get(**{self.slug_field: data})
except ObjectDoesNotExist:
return queryset.none()
except (TypeError, ValueError):
self.fail('invalid')


class TaxonomyOrgListQueryParamsSerializer(TaxonomyListQueryParamsSerializer):
"""
Serializer for the query params for the GET view
"""

org: fields.Field = serializers.SlugRelatedField(
org: fields.Field = OptionalSlugRelatedField(
slug_field="short_name",
queryset=Organization.objects.all(),
required=False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ def test_list_taxonomy_enabled_filter(self, enabled_parameter: bool, expected_ta
("orgA", ["st1", "st2", "t1", "t2", "tA1", "tA2", "tBA1", "tBA2"]),
("orgB", ["st1", "st2", "t1", "t2", "tB1", "tB2", "tBA1", "tBA2"]),
("orgX", ["st1", "st2", "t1", "t2"]),
# Non-existent orgs are ignored
("invalidOrg", ["st1", "st2", "t1", "t2"]),
)
@ddt.unpack
def test_list_taxonomy_org_filter(self, org_parameter: str, expected_taxonomies: list[str]) -> None:
Expand All @@ -355,20 +357,6 @@ def test_list_taxonomy_org_filter(self, org_parameter: str, expected_taxonomies:
expected_taxonomies=expected_taxonomies,
)

def test_list_taxonomy_invalid_org(self) -> None:
"""
Tests that using an invalid org in the filter will raise BAD_REQUEST
"""
url = TAXONOMY_ORG_LIST_URL

self.client.force_authenticate(user=self.staff)

query_params = {"org": "invalidOrg"}

response = self.client.get(url, query_params, format="json")

assert response.status_code == status.HTTP_400_BAD_REQUEST

@ddt.data(
("user", (), None),
("staffA", ["tA2", "tBA1", "tBA2"], None),
Expand Down
4 changes: 3 additions & 1 deletion openedx/core/djangoapps/content_tagging/rest_api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ def get_queryset(self):
query_params = TaxonomyOrgListQueryParamsSerializer(data=self.request.query_params.dict())
query_params.is_valid(raise_exception=True)
enabled = query_params.validated_data.get("enabled", None)

# If org filtering was requested, then use it, even if the org is invalid/None
org = query_params.validated_data.get("org", None)
if org:
if "org" in query_params.validated_data:
queryset = get_taxonomies_for_org(enabled, org)
else:
queryset = get_taxonomies(enabled)
Expand Down

0 comments on commit dad31a3

Please sign in to comment.