fix: select feed thumbnail from most recently published episode #81

Merged
joezombie merged 2 commits from fix/feed-thumbnail-uses-latest-publish-date into main 2026-02-20 22:24:01 +00:00
joezombie commented 2026-02-20 22:17:37 +00:00 (Migrated from github.com)

Root Cause

The thumbnail fallback was selecting the wrong episode. DisplayOrder maps to the YouTube playlist position, and for playlists ordered newest-first (the common case), low indices = recent episodes. The previous code used LastOrDefault on an ascending DisplayOrder sort, which picked the episode with the highest playlist index — the oldest episode.

Fix

Order by PublishDate descending before selecting, so the most recently uploaded episode's thumbnail is always used — independent of playlist ordering. Applied to both the thumbnail URL and embedded-art fallback paths.

Test plan

  • Updated multi-episode test to explicitly model a newest-first playlist (episode with lower DisplayOrder but higher PublishDate should win)
  • Replaced fragile string-split assertion with proper XML parsing via XDocument
  • All 18 PodcastFeedServiceTests pass

🤖 Generated with Claude Code

## Root Cause The thumbnail fallback was selecting the wrong episode. `DisplayOrder` maps to the YouTube playlist position, and for playlists ordered newest-first (the common case), low indices = recent episodes. The previous code used `LastOrDefault` on an ascending `DisplayOrder` sort, which picked the episode with the **highest playlist index** — the oldest episode. ## Fix Order by `PublishDate` descending before selecting, so the most recently uploaded episode's thumbnail is always used — independent of playlist ordering. Applied to both the thumbnail URL and embedded-art fallback paths. ## Test plan - [x] Updated multi-episode test to explicitly model a newest-first playlist (episode with lower `DisplayOrder` but higher `PublishDate` should win) - [x] Replaced fragile string-split assertion with proper XML parsing via `XDocument` - [x] All 18 `PodcastFeedServiceTests` pass 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No description provided.