Skip to content
Snippets Groups Projects
test_api.py 9.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • Eliot Berriot's avatar
    Eliot Berriot committed
    import os
    
    import pytest
    from django.urls import reverse
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    from funkwhale_api.music import models, tasks
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    DATA_DIR = os.path.dirname(os.path.abspath(__file__))
    
    
    def test_can_submit_youtube_url_for_track_import(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        settings, artists, albums, tracks, mocker, superuser_client
    ):
        mocker.patch("funkwhale_api.music.tasks.import_job_run.delay")
    
        mocker.patch(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            "funkwhale_api.musicbrainz.api.artists.get",
            return_value=artists["get"]["adhesive_wombat"],
        )
    
        mocker.patch(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            "funkwhale_api.musicbrainz.api.releases.get",
            return_value=albums["get"]["marsupial"],
        )
    
        mocker.patch(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            "funkwhale_api.musicbrainz.api.recordings.get",
            return_value=tracks["get"]["8bitadventures"],
        )
    
        mocker.patch(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            "funkwhale_api.music.models.TrackFile.download_file", return_value=None
        )
        mbid = "9968a9d6-8d92-4051-8f76-674e157b6eed"
        video_id = "tPEE9ZwTmy0"
        url = reverse("api:v1:submit-single")
        video_url = "https://www.youtube.com/watch?v={0}".format(video_id)
        response = superuser_client.post(url, {"import_url": video_url, "mbid": mbid})
    
    
        assert response.status_code == 201
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        batch = superuser_client.user.imports.latest("id")
        job = batch.jobs.latest("id")
        assert job.status == "pending"
    
        assert str(job.mbid) == mbid
        assert job.source == video_url
    
    def test_import_creates_an_import_with_correct_data(mocker, superuser_client):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        mocker.patch("funkwhale_api.music.tasks.import_job_run")
        mbid = "9968a9d6-8d92-4051-8f76-674e157b6eed"
        video_id = "tPEE9ZwTmy0"
        url = reverse("api:v1:submit-single")
    
        superuser_client.post(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            {
                "import_url": "https://www.youtube.com/watch?v={0}".format(video_id),
                "mbid": mbid,
            },
        )
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        batch = models.ImportBatch.objects.latest("id")
    
        assert batch.jobs.count() == 1
        assert batch.submitted_by == superuser_client.user
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        assert batch.status == "pending"
    
        job = batch.jobs.first()
        assert str(job.mbid) == mbid
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        assert job.status == "pending"
        assert job.source == "https://www.youtube.com/watch?v={0}".format(video_id)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    def test_can_import_whole_album(artists, albums, mocker, superuser_client):
        mocker.patch("funkwhale_api.music.tasks.import_job_run")
    
        mocker.patch(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            "funkwhale_api.musicbrainz.api.artists.get", return_value=artists["get"]["soad"]
        )
        mocker.patch("funkwhale_api.musicbrainz.api.images.get_front", return_value=b"")
    
        mocker.patch(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            "funkwhale_api.musicbrainz.api.releases.get",
            return_value=albums["get_with_includes"]["hypnotize"],
        )
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            "releaseId": "47ae093f-1607-49a3-be11-a15d335ccc94",
            "tracks": [
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                    "mbid": "1968a9d6-8d92-4051-8f76-674e157b6eed",
                    "source": "https://www.youtube.com/watch?v=1111111111",
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                    "mbid": "2968a9d6-8d92-4051-8f76-674e157b6eed",
                    "source": "https://www.youtube.com/watch?v=2222222222",
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                    "mbid": "3968a9d6-8d92-4051-8f76-674e157b6eed",
                    "source": "https://www.youtube.com/watch?v=3333333333",
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            ],
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        url = reverse("api:v1:submit-album")
    
        superuser_client.post(url, json.dumps(payload), content_type="application/json")
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        batch = models.ImportBatch.objects.latest("id")
    
        assert batch.jobs.count() == 3
        assert batch.submitted_by == superuser_client.user
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        assert batch.status == "pending"
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        album = models.Album.objects.latest("id")
        assert str(album.mbid) == "47ae093f-1607-49a3-be11-a15d335ccc94"
        medium_data = albums["get_with_includes"]["hypnotize"]["release"]["medium-list"][0]
        assert int(medium_data["track-count"]) == album.tracks.all().count()
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        for track in medium_data["track-list"]:
            instance = models.Track.objects.get(mbid=track["recording"]["id"])
            assert instance.title == track["recording"]["title"]
            assert instance.position == int(track["position"])
            assert instance.title == track["recording"]["title"]
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        for row in payload["tracks"]:
            job = models.ImportJob.objects.get(mbid=row["mbid"])
            assert str(job.mbid) == row["mbid"]
            assert job.status == "pending"
            assert job.source == row["source"]
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    def test_can_import_whole_artist(artists, albums, mocker, superuser_client):
        mocker.patch("funkwhale_api.music.tasks.import_job_run")
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            "funkwhale_api.musicbrainz.api.artists.get", return_value=artists["get"]["soad"]
        )
        mocker.patch("funkwhale_api.musicbrainz.api.images.get_front", return_value=b"")
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            "funkwhale_api.musicbrainz.api.releases.get",
            return_value=albums["get_with_includes"]["hypnotize"],
        )
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            "artistId": "mbid",
            "albums": [
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                    "releaseId": "47ae093f-1607-49a3-be11-a15d335ccc94",
                    "tracks": [
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                            "mbid": "1968a9d6-8d92-4051-8f76-674e157b6eed",
                            "source": "https://www.youtube.com/watch?v=1111111111",
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                            "mbid": "2968a9d6-8d92-4051-8f76-674e157b6eed",
                            "source": "https://www.youtube.com/watch?v=2222222222",
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                            "mbid": "3968a9d6-8d92-4051-8f76-674e157b6eed",
                            "source": "https://www.youtube.com/watch?v=3333333333",
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                    ],
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            ],
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        url = reverse("api:v1:submit-artist")
    
        superuser_client.post(url, json.dumps(payload), content_type="application/json")
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        batch = models.ImportBatch.objects.latest("id")
    
        assert batch.jobs.count() == 3
        assert batch.submitted_by == superuser_client.user
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        assert batch.status == "pending"
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        album = models.Album.objects.latest("id")
        assert str(album.mbid) == "47ae093f-1607-49a3-be11-a15d335ccc94"
        medium_data = albums["get_with_includes"]["hypnotize"]["release"]["medium-list"][0]
        assert int(medium_data["track-count"]) == album.tracks.all().count()
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        for track in medium_data["track-list"]:
            instance = models.Track.objects.get(mbid=track["recording"]["id"])
            assert instance.title == track["recording"]["title"]
            assert instance.position == int(track["position"])
            assert instance.title == track["recording"]["title"]
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        for row in payload["albums"][0]["tracks"]:
            job = models.ImportJob.objects.get(mbid=row["mbid"])
            assert str(job.mbid) == row["mbid"]
            assert job.status == "pending"
            assert job.source == row["source"]
    
    def test_user_can_create_an_empty_batch(superuser_api_client, factories):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        url = reverse("api:v1:import-batches-list")
    
        response = superuser_api_client.post(url)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    
        assert response.status_code == 201
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        batch = superuser_api_client.user.imports.latest("id")
    
        assert batch.submitted_by == superuser_api_client.user
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        assert batch.source == "api"
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    def test_user_can_create_import_job_with_file(superuser_api_client, factories, mocker):
        path = os.path.join(DATA_DIR, "test.ogg")
        m = mocker.patch("funkwhale_api.common.utils.on_commit")
        batch = factories["music.ImportBatch"](submitted_by=superuser_api_client.user)
        url = reverse("api:v1:import-jobs-list")
        with open(path, "rb") as f:
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            content = f.read()
            f.seek(0)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            response = superuser_api_client.post(
                url, {"batch": batch.pk, "audio_file": f, "source": "file://"}
            )
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    
        assert response.status_code == 201
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        job = batch.jobs.latest("id")
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        assert job.status == "pending"
        assert job.source.startswith("file://")
        assert "test.ogg" in job.source
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        assert job.audio_file.read() == content
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        m.assert_called_once_with(tasks.import_job_run.delay, import_job_id=job.pk)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    @pytest.mark.parametrize(
        "route,method",
        [
            ("api:v1:tags-list", "get"),
            ("api:v1:tracks-list", "get"),
            ("api:v1:artists-list", "get"),
            ("api:v1:albums-list", "get"),
        ],
    )
    
    def test_can_restrict_api_views_to_authenticated_users(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        db, route, method, preferences, client
    ):
    
        url = reverse(route)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        preferences["common__api_authentication_required"] = True
    
        response = getattr(client, method)(url)
        assert response.status_code == 401
    
    
    
    def test_track_file_url_is_restricted_to_authenticated_users(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        api_client, factories, preferences
    ):
        preferences["common__api_authentication_required"] = True
        f = factories["music.TrackFile"]()
    
        assert f.audio_file is not None
        url = f.path
    
        response = api_client.get(url)
    
        assert response.status_code == 401
    
    
    
    def test_track_file_url_is_accessible_to_authenticated_users(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        logged_in_api_client, factories, preferences
    ):
        preferences["common__api_authentication_required"] = True
        f = factories["music.TrackFile"]()
    
        assert f.audio_file is not None
        url = f.path
        response = logged_in_api_client.get(url)
    
    
        assert response.status_code == 200
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        assert response["X-Accel-Redirect"] == "/_protected{}".format(f.audio_file.url)