diff --git a/django/thunderstore/api/cyberstorm/tests/test_package_listing.py b/django/thunderstore/api/cyberstorm/tests/test_package_listing.py index 3047f62a8..6918795a5 100644 --- a/django/thunderstore/api/cyberstorm/tests/test_package_listing.py +++ b/django/thunderstore/api/cyberstorm/tests/test_package_listing.py @@ -312,5 +312,25 @@ def test_dependency_serializer__reads_is_active_from_correct_field( assert actual["is_active"] == (package_is_active and version_is_active) +@pytest.mark.django_db +def test_dependency_serializer__when_dependency_is_not_active__censors_icon_and_description() -> None: + # community_identifier is normally added using annotations, but + # it's irrelavant for this test case. + dependency = PackageVersionFactory() + dependency.community_identifier = "greendale" + + actual = DependencySerializer(dependency).data + + assert actual["description"].startswith("Desc_") + assert actual["icon_url"].startswith("http") + + dependency.is_active = False + del dependency.is_effectively_active # Clear cached property + actual = DependencySerializer(dependency).data + + assert actual["description"] == "This package has been removed." + assert actual["icon_url"] is None + + def _date_to_z(value: datetime) -> str: return value.strftime("%Y-%m-%dT%H:%M:%S.%fZ") diff --git a/django/thunderstore/api/cyberstorm/views/package_listing.py b/django/thunderstore/api/cyberstorm/views/package_listing.py index 56a4550af..5a8722cde 100644 --- a/django/thunderstore/api/cyberstorm/views/package_listing.py +++ b/django/thunderstore/api/cyberstorm/views/package_listing.py @@ -1,3 +1,5 @@ +from typing import Optional + from django.db.models import ( BooleanField, CharField, @@ -27,18 +29,32 @@ class DependencySerializer(serializers.Serializer): """ Dependencies of a given PackageVersion, listed in a given Community. - community_identifier and namespace are not present by default and - need to be annotated to the object. + community_identifier is not present by default and needs to be + annotated to the object. + + Description and icon is not shown to clients if the dependency is + deactivated, since the fields may contain the very reason for the + deactivation. """ community_identifier = serializers.CharField() - description = serializers.CharField() - icon_url = serializers.CharField(source="icon.url") + description = serializers.SerializerMethodField() + icon_url = serializers.SerializerMethodField() is_active = serializers.BooleanField(source="is_effectively_active") name = serializers.CharField() namespace = serializers.CharField(source="package.namespace.name") version_number = serializers.CharField() + def get_description(self, obj: PackageVersion) -> str: + return ( + obj.description + if obj.is_effectively_active + else "This package has been removed." + ) + + def get_icon_url(self, obj: PackageVersion) -> Optional[str]: + return obj.icon.url if obj.is_effectively_active else None + class TeamSerializer(serializers.Serializer): """