Skip to content
Snippets Groups Projects
test_views.py 8.77 KiB
Newer Older
  • Learn to ignore specific revisions
  • import uuid
    
    import pytest
    
    from django.urls import reverse
    
    from funkwhale_api.audio import serializers
    
    from funkwhale_api.audio import views
    
    
    
    def test_channel_create(logged_in_api_client):
        actor = logged_in_api_client.user.create_actor()
    
        data = {
            # TODO: cover
            "name": "My channel",
            "username": "mychannel",
    
            "description": {"text": "This is my channel", "content_type": "text/markdown"},
    
            "content_category": "podcast",
    
            "metadata": {"language": "en", "itunes_category": "Sports"},
    
        response = logged_in_api_client.post(url, data, format="json")
    
        channel = views.ChannelViewSet.queryset.get(attributed_to=actor)
        expected = serializers.ChannelSerializer(
            channel, context={"subscriptions_count": True}
        ).data
    
    
        assert response.data == expected
        assert channel.artist.name == data["name"]
        assert channel.artist.attributed_to == actor
        assert (
            sorted(channel.artist.tagged_items.values_list("tag__name", flat=True))
            == data["tags"]
        )
        assert channel.attributed_to == actor
    
        assert channel.actor.summary == channel.artist.description.rendered
    
        assert channel.actor.preferred_username == data["username"]
    
        assert channel.library.privacy_level == "everyone"
    
        assert channel.library.actor == actor
    
    
    def test_channel_detail(factories, logged_in_api_client):
    
        channel = factories["audio.Channel"](artist__description=None)
    
        url = reverse("api:v1:channels-detail", kwargs={"uuid": channel.uuid})
    
        setattr(channel.artist, "_tracks_count", 0)
        setattr(channel.artist, "_prefetched_tagged_items", [])
    
    
        expected = serializers.ChannelSerializer(
            channel, context={"subscriptions_count": True}
        ).data
    
        response = logged_in_api_client.get(url)
    
        assert response.status_code == 200
        assert response.data == expected
    
    
    def test_channel_list(factories, logged_in_api_client):
    
        channel = factories["audio.Channel"](artist__description=None)
    
        setattr(channel.artist, "_tracks_count", 0)
        setattr(channel.artist, "_prefetched_tagged_items", [])
    
        url = reverse("api:v1:channels-list")
        expected = serializers.ChannelSerializer(channel).data
        response = logged_in_api_client.get(url)
    
        assert response.status_code == 200
        assert response.data == {
            "results": [expected],
            "count": 1,
            "next": None,
            "previous": None,
        }
    
    
    def test_channel_update(logged_in_api_client, factories):
        actor = logged_in_api_client.user.create_actor()
        channel = factories["audio.Channel"](attributed_to=actor)
    
        data = {
            # TODO: cover
            "name": "new name"
        }
    
        url = reverse("api:v1:channels-detail", kwargs={"uuid": channel.uuid})
        response = logged_in_api_client.patch(url, data)
    
        assert response.status_code == 200
    
        channel.refresh_from_db()
    
        assert channel.artist.name == data["name"]
    
    
    def test_channel_update_permission(logged_in_api_client, factories):
        logged_in_api_client.user.create_actor()
        channel = factories["audio.Channel"]()
    
        data = {"name": "new name"}
    
        url = reverse("api:v1:channels-detail", kwargs={"uuid": channel.uuid})
        response = logged_in_api_client.patch(url, data)
    
        assert response.status_code == 403
    
    
    
    def test_channel_delete(logged_in_api_client, factories, mocker):
    
    
        actor = logged_in_api_client.user.create_actor()
        channel = factories["audio.Channel"](attributed_to=actor)
    
        url = reverse("api:v1:channels-detail", kwargs={"uuid": channel.uuid})
    
        dispatch = mocker.patch("funkwhale_api.federation.routes.outbox.dispatch")
    
        response = logged_in_api_client.delete(url)
    
        assert response.status_code == 204
    
        with pytest.raises(channel.DoesNotExist):
            channel.refresh_from_db()
    
    
        dispatch.assert_called_once_with(
            {"type": "Delete", "object": {"type": channel.actor.type}},
            context={"actor": channel.actor},
        )
    
    
    
    def test_channel_delete_permission(logged_in_api_client, factories):
        logged_in_api_client.user.create_actor()
        channel = factories["audio.Channel"]()
    
        url = reverse("api:v1:channels-detail", kwargs={"uuid": channel.uuid})
        response = logged_in_api_client.patch(url)
    
        assert response.status_code == 403
        channel.refresh_from_db()
    
    
    @pytest.mark.parametrize("url_name", ["api:v1:channels-list"])
    def test_channel_views_disabled_via_feature_flag(
        url_name, logged_in_api_client, preferences
    ):
        preferences["audio__channels_enabled"] = False
        url = reverse(url_name)
        response = logged_in_api_client.get(url)
        assert response.status_code == 405
    
    
    
    def test_channel_subscribe(factories, logged_in_api_client):
        actor = logged_in_api_client.user.create_actor()
        channel = factories["audio.Channel"](artist__description=None)
        url = reverse("api:v1:channels-subscribe", kwargs={"uuid": channel.uuid})
    
        response = logged_in_api_client.post(url)
    
        assert response.status_code == 201
    
        subscription = actor.emitted_follows.select_related(
    
            "target__channel__artist__description",
            "target__channel__artist__attachment_cover",
    
        setattr(subscription.target.channel.artist, "_tracks_count", 0)
        setattr(subscription.target.channel.artist, "_prefetched_tagged_items", [])
    
        assert subscription.fid == subscription.get_federation_id()
    
        expected = serializers.SubscriptionSerializer(subscription).data
        assert response.data == expected
        assert subscription.target == channel.actor
    
    
    def test_channel_unsubscribe(factories, logged_in_api_client):
        actor = logged_in_api_client.user.create_actor()
        channel = factories["audio.Channel"]()
        subscription = factories["audio.Subscription"](target=channel.actor, actor=actor)
        url = reverse("api:v1:channels-unsubscribe", kwargs={"uuid": channel.uuid})
    
        response = logged_in_api_client.post(url)
    
        assert response.status_code == 204
    
        with pytest.raises(subscription.DoesNotExist):
            subscription.refresh_from_db()
    
    
    
    def test_subscriptions_list(factories, logged_in_api_client):
        actor = logged_in_api_client.user.create_actor()
        channel = factories["audio.Channel"](artist__description=None)
        subscription = factories["audio.Subscription"](target=channel.actor, actor=actor)
    
        setattr(subscription.target.channel.artist, "_tracks_count", 0)
        setattr(subscription.target.channel.artist, "_prefetched_tagged_items", [])
    
        factories["audio.Subscription"](target=channel.actor)
        url = reverse("api:v1:subscriptions-list")
        expected = serializers.SubscriptionSerializer(subscription).data
        response = logged_in_api_client.get(url)
    
        assert response.status_code == 200
        assert response.data["results"][0] == expected
        assert response.data == {
            "results": [expected],
            "count": 1,
            "next": None,
            "previous": None,
        }
    
    
    def test_subscriptions_all(factories, logged_in_api_client):
        actor = logged_in_api_client.user.create_actor()
        channel = factories["audio.Channel"](artist__description=None)
        subscription = factories["audio.Subscription"](target=channel.actor, actor=actor)
        factories["audio.Subscription"](target=channel.actor)
        url = reverse("api:v1:subscriptions-all")
        response = logged_in_api_client.get(url)
    
        assert response.status_code == 200
    
        assert response.data == {
            "results": [{"uuid": subscription.uuid, "channel": uuid.UUID(channel.uuid)}],
            "count": 1,
        }
    
    def test_channel_rss_feed(factories, api_client, preferences):
        preferences["common__api_authentication_required"] = False
        channel = factories["audio.Channel"](local=True)
    
        upload1 = factories["music.Upload"](library=channel.library, playable=True)
        upload2 = factories["music.Upload"](library=channel.library, playable=True)
    
        expected = serializers.rss_serialize_channel_full(
            channel=channel, uploads=[upload2, upload1]
        )
    
        url = reverse("api:v1:channels-rss", kwargs={"uuid": channel.uuid})
    
        response = api_client.get(url)
    
        assert response.status_code == 200
        assert response.data == expected
        assert response["Content-Type"] == "application/rss+xml"
    
    
    
    def test_channel_rss_feed_remote(factories, api_client, preferences):
        preferences["common__api_authentication_required"] = False
        channel = factories["audio.Channel"]()
    
        url = reverse("api:v1:channels-rss", kwargs={"uuid": channel.uuid})
    
        response = api_client.get(url)
    
        assert response.status_code == 404
    
    
    def test_channel_rss_feed_authentication_required(factories, api_client, preferences):
        preferences["common__api_authentication_required"] = True
        channel = factories["audio.Channel"](local=True)
    
        url = reverse("api:v1:channels-rss", kwargs={"uuid": channel.uuid})
    
        response = api_client.get(url)
    
        assert response.status_code == 401