/
/
/
1"""Tests for Zvuk Music lyrics feature (get_track_metadata)."""
2
3from __future__ import annotations
4
5from typing import cast
6from unittest.mock import AsyncMock, MagicMock, Mock
7
8import pytest
9
10from music_assistant.providers.zvuk_music.provider import ZvukMusicProvider
11
12
13def _make_provider(lyrics_result: MagicMock | None) -> ZvukMusicProvider:
14 """Create a ZvukMusicProvider mock with a preset lyrics result."""
15 provider = Mock(spec=ZvukMusicProvider)
16 provider.client = Mock()
17 provider.client.get_lyrics = AsyncMock(return_value=lyrics_result)
18 provider.get_track_metadata = ZvukMusicProvider.get_track_metadata.__get__(
19 provider, ZvukMusicProvider
20 )
21 return provider
22
23
24def _make_track(item_id: str = "173663389") -> Mock:
25 """Create a minimal MA Track mock."""
26 track = MagicMock()
27 track.item_id = item_id
28 return track
29
30
31class TestGetTrackMetadata:
32 """Tests for ZvukMusicProvider.get_track_metadata()."""
33
34 @pytest.mark.asyncio
35 async def test_synced_lyrics_returned_as_lrc(self) -> None:
36 """LRC synced lyrics (is_synced=True) go into metadata.lrc_lyrics."""
37 lrc_text = "[00:00.68]ЧеÑÑное Ñлово Ð¼Ñ Ñ Ñобой лиÑние\n[00:04.71]РмиÑе веÑÑлÑÑ
ÑеÑей\n" # noqa: RUF001
38 provider = _make_provider(MagicMock(lyrics=lrc_text, is_synced=True))
39
40 result = await provider.get_track_metadata(_make_track("173663389"))
41
42 assert result is not None
43 assert result.lrc_lyrics == lrc_text
44 assert result.lyrics is None
45
46 @pytest.mark.asyncio
47 async def test_plain_lyrics_returned_as_lyrics(self) -> None:
48 """Plain lyrics (is_synced=False) go into metadata.lyrics."""
49 plain_text = "Some plain lyrics text\nSecond line\n"
50 provider = _make_provider(MagicMock(lyrics=plain_text, is_synced=False))
51
52 result = await provider.get_track_metadata(_make_track("99999"))
53
54 assert result is not None
55 assert result.lyrics == plain_text
56 assert result.lrc_lyrics is None
57
58 @pytest.mark.asyncio
59 async def test_no_lyrics_returns_none(self) -> None:
60 """When API returns None (track has no lyrics), return None."""
61 provider = _make_provider(None)
62
63 result = await provider.get_track_metadata(_make_track("174649396"))
64
65 assert result is None
66
67 @pytest.mark.asyncio
68 async def test_empty_lyrics_text_returns_none(self) -> None:
69 """When lyrics object has empty/falsy lyrics text, return None."""
70 provider = _make_provider(MagicMock(lyrics="", is_synced=False))
71
72 result = await provider.get_track_metadata(_make_track("999"))
73
74 assert result is None
75
76 @pytest.mark.asyncio
77 async def test_correct_track_id_passed_to_client(self) -> None:
78 """The correct track item_id is forwarded to the API client."""
79 provider = _make_provider(None)
80 track = _make_track("12345678")
81
82 await provider.get_track_metadata(track)
83
84 cast("AsyncMock", provider.client.get_lyrics).assert_awaited_once_with("12345678")
85