import asyncio import pytest import pytest_asyncio from conftest import ( TEST_YT_ASSET_ID, TEST_YT_CHANNEL_ID, TEST_YT_ISRC, TEST_YT_VIDEO_ID, ) from src.backend.connectors import youtube_apis from src.backend.constants import YtCid class Common: _class = None @pytest_asyncio.fixture(scope="class") async def instance(self): return self._class() @pytest.mark.asyncio async def test_init(self): uninitialized_instance = self._class() assert not uninitialized_instance._api await uninitialized_instance.init() assert uninitialized_instance._api class TestYouTubeCidClient(Common): _class = youtube_apis.YtCidClient @pytest.mark.asyncio async def test_concurrency(self): """Test that concurrent requests are handled correctly. For this purpose, three clients are created and each one makes a concurrent request. """ clients = (self._class() for _ in range(3)) async with asyncio.TaskGroup() as tg: client_tasks = [ tg.create_task(client.assets_list([TEST_YT_ASSET_ID])) for client in clients ] results = [client.result() for client in client_tasks] assert all(result[0].id == TEST_YT_ASSET_ID for result in results) assert (client.request_count == 1 for client in clients) @pytest.mark.asyncio async def test_asset_relationships_list(self, instance): response = await instance.asset_relationships_list(TEST_YT_ASSET_ID) assert response.id == TEST_YT_ASSET_ID assert isinstance(response.parents, list) assert isinstance(response.children, list) class TestAssetSearchList: @pytest.mark.asyncio async def test_asset_search_list(self, instance): response = await instance.asset_search_list(q=TEST_YT_ISRC) assert response[0].isrc == TEST_YT_ISRC @pytest.mark.asyncio async def test_asset_search_list_not_allowed_param(self, instance): with pytest.raises(ValueError): await instance.asset_search_list(isrcs=...) @pytest.mark.asyncio async def test_asset_search_list_isrc(self, instance): response = await instance.asset_search_list_isrc([TEST_YT_ISRC]) assert response[0].isrc == TEST_YT_ISRC @pytest.mark.asyncio async def test_assets_list(self, instance): response = await instance.assets_list([TEST_YT_ASSET_ID]) assert response[0].id == TEST_YT_ASSET_ID @pytest.mark.asyncio async def test_assets_list_not_found(self, instance): with pytest.raises(youtube_apis.exceptions.NotFound): await instance.assets_list( # noqa ["invalid-asset-id"] ), "Invalid asset IDs should raise NotFound." @pytest.mark.asyncio async def test_metadata_history_list(self, instance): response = await instance.metadata_history(TEST_YT_ASSET_ID) # noqa assert len(response) > 0 assert all( metadata_history.metadata[YtCid.ISRC] for metadata_history in response ) @pytest.mark.asyncio @pytest.mark.parametrize("asset_id", [TEST_YT_ASSET_ID, [TEST_YT_ASSET_ID]]) async def test_references_list(self, instance, asset_id): response = await instance.references_list(asset_id) # noqa assert all(reference.asset_id == TEST_YT_ASSET_ID for reference in response) @pytest.mark.asyncio async def test_claims_by_asset_id(self, instance): limit = 15 # At time of writing, there are > 15 claims for this asset. response = await instance.claims_by_asset_id(TEST_YT_ASSET_ID, limit=limit) assert response, "Expected claims to be returned." assert len(response) == limit, "Limit should be respected." assert all( claim.asset_id == TEST_YT_ASSET_ID for claim in response ), "Expected claims to be related to the asset." @pytest.mark.asyncio async def test_claims_by_video_id(self, instance): limit = 3 # At the time of writing, there are 3 claims for this video. response = await instance.claims_by_video_id(TEST_YT_VIDEO_ID, limit=limit) assert response, "Expected claims to be returned." assert len(response) == limit, "Limit should be respected." assert all( claim.video_id == TEST_YT_VIDEO_ID for claim in response ), "Expected claims to be related to the video." class TestYouTubeDataClient(Common): _class = youtube_apis.YtDataClient @pytest.fixture def instance(self): return self._class() @pytest.mark.asyncio async def test_channel_videos_list(self, instance): response = await instance.channel_videos_list(TEST_YT_CHANNEL_ID) assert response, "Expected videos to be returned." assert all( isinstance(video, youtube_apis.data.models.Video) for video in response ) "Expected all videos to be of type Video." assert all( video.channel_id == TEST_YT_CHANNEL_ID for video in response ), "Expected all videos to be related to the channel."