from typing import Any, Coroutine import pytest import pytest_asyncio from fastapi.testclient import TestClient from pydantic import ValidationError from sqlalchemy.sql import text from syrupy.assertion import SnapshotAssertion from delivery_metadata.api.app import app from delivery_metadata.clients.art_relations import get_tracks from delivery_metadata.clients.art_relations.track import ArtRelationsTrack @pytest_asyncio.fixture async def create_language_table( art_relations_tracks_mock: list[ArtRelationsTrack], test_client: TestClient, ) -> None: async with app.state.art_relations_connector.db_session( transaction=True, turn_off_foreign_key_checks=True ) as session: await session.execute(text("TRUNCATE TABLE language")) await session.execute( text(""" INSERT INTO language ( language_code, iso_639_1_code, iso_code_639_3_code ) VALUES ( :language_code, :iso_639_1_code, :iso_code_639_3_code ) """), [ { "language_code": "zh", "iso_639_1_code": "zh", "iso_code_639_3_code": "yue", }, { "language_code": "BGC", "iso_639_1_code": None, "iso_code_639_3_code": "BGC", }, ], ) @pytest.mark.asyncio async def test_get_tracks( create_language_table: Coroutine[Any, Any, None], create_track_table: Coroutine[Any, Any, None], snapshot: SnapshotAssertion, ) -> None: result = await get_tracks(75679660923) assert result == snapshot @pytest.mark.asyncio async def test_get_tracks_track_too_long_preview( create_language_table: Coroutine[Any, Any, None], create_track_table: Coroutine[Any, Any, None], snapshot: SnapshotAssertion, ) -> None: async with app.state.art_relations_connector.db_session( transaction=True ) as session: await session.execute( text( """ UPDATE track SET preview_start_time = 15000 WHERE id = 12345 """ ) ) with pytest.raises(ValidationError) as e: await get_tracks(75679660923) assert e.value.title == "ArtRelationsTrack" assert e.value.errors() == snapshot @pytest.mark.asyncio async def test_get_tracks_multiple_tracks_too_long_preview( create_language_table: Coroutine[Any, Any, None], create_track_table: Coroutine[Any, Any, None], snapshot: SnapshotAssertion, ) -> None: async with app.state.art_relations_connector.db_session( transaction=True ) as session: await session.execute( text( """ UPDATE track SET preview_start_time = 15000 WHERE id = 12345 """ ) ) await session.execute( text( """ UPDATE track SET preview_start_time = 130000 WHERE id = 12347 """ ) ) with pytest.raises(ValidationError) as e: await get_tracks(75679660923) assert e.value.title == "ArtRelationsTrack" assert e.value.errors() == snapshot @pytest.mark.asyncio async def test_get_tracks_track_missing_duration_fields( create_language_table: Coroutine[Any, Any, None], create_track_table: Coroutine[Any, Any, None], snapshot: SnapshotAssertion, ) -> None: async with app.state.art_relations_connector.db_session( transaction=True ) as session: await session.execute( text( """ UPDATE track SET length_minute = NULL, length_seconds = NULL WHERE id = 12345 """ ) ) with pytest.raises(ValidationError) as e: await get_tracks(75679660923) assert e.value.title == "ArtRelationsTrack" assert e.value.errors() == snapshot @pytest.mark.asyncio async def test_get_tracks_excludes_soft_deleted_spatial( create_language_table: Coroutine[Any, Any, None], create_track_table: Coroutine[Any, Any, None], ) -> None: async with app.state.art_relations_connector.db_session( transaction=True ) as session: await session.execute( text( """ UPDATE track_additional_isrc SET deleted_at = NOW() WHERE track_id = 12345 AND type = 'atmos' """ ) ) result = await get_tracks(75679660923) spatial_track = next(track for track in result if track.track_id == 12345) assert spatial_track.spatial_isrc is None