/
/
/
1"""Test the episode ordering of the Podcast RSS Feed provider."""
2
3from typing import Any
4from unittest.mock import Mock
5
6from music_assistant.providers.podcastfeed import SUPPORTED_FEATURES, PodcastMusicprovider
7
8
9def _episode(guid: str, published: int) -> dict[str, Any]:
10 """Return a minimal podcastparser episode dict with a valid enclosure."""
11 return {
12 "guid": guid,
13 "title": f"Episode {guid}",
14 "published": published,
15 "enclosures": [{"url": f"https://example.com/{guid}.mp3"}],
16 }
17
18
19def _provider(episodes: list[dict[str, Any]]) -> PodcastMusicprovider:
20 """Return a provider serving the given episodes, bypassing the feed fetch."""
21 mass = Mock()
22 manifest = Mock(domain="podcastfeed")
23 config = Mock(instance_id="podcastfeed--test", enabled=True)
24 config.get_value.side_effect = lambda key, default=None: (
25 "INFO" if key == "log_level" else default
26 )
27 provider = PodcastMusicprovider(mass, manifest, config, SUPPORTED_FEATURES)
28 provider.feed_url = "https://example.com/feed.xml"
29 provider.podcast_id = "testpodcast"
30 provider.parsed_podcast = {"title": "My Show", "episodes": episodes}
31 return provider
32
33
34async def test_episodes_are_yielded_newest_first() -> None:
35 """The newest episode comes first, so callers after the latest one take the first."""
36 provider = _provider([_episode("b", 200), _episode("c", 300), _episode("a", 100)])
37 episodes = [ep async for ep in provider.get_podcast_episodes("testpodcast")]
38 assert [ep.item_id for ep in episodes] == ["c", "b", "a"]
39
40
41async def test_episode_positions_run_oldest_to_newest() -> None:
42 """The newest episode still carries the highest position."""
43 provider = _provider([_episode("b", 200), _episode("c", 300), _episode("a", 100)])
44 episodes = [ep async for ep in provider.get_podcast_episodes("testpodcast")]
45 assert {ep.item_id: ep.position for ep in episodes} == {"a": 1, "b": 2, "c": 3}
46