navidrome/tests
Jiho Andrew Lee 152a032ae1 feat(podcast): implement Podcasting 2.0 namespace support (Tier 1–3)
Adds full support for the Podcasting 2.0 namespace
(https://podcastindex.org/namespace/1.0) across RSS parsing, persistence,
Subsonic API responses, and OpenSubsonic extensions.

- podcast:guid: channel-level UUIDv5 for stable identity across feed URL changes
- podcast:chapters: per-episode chapters URL + MIME type (chaptersUrl in API)
- podcast:transcript: multiple transcripts per episode stored in a dedicated
  podcast_transcript table; attributes: url, type, language, rel
- podcast:season: season number + optional name per episode
- podcast:episode: episode number (decimal string) + optional display label

- podcast:person: host/guest entries at both channel and episode level stored in
  a dedicated podcast_person table; attributes: name, role, group, img, href;
  role defaults to "host" and group defaults to "cast" per spec
- podcast:locked: feed lock flag + optional owner email on channel
- podcast:funding: first funding entry URL + display text on channel
- podcast:medium: content type classification on channel
- podcast:soundbite: startTime (float), duration (float), title per episode
- podcast:updateFrequency: display text + rrule + complete flag on channel

- podcast:podroll: creator-recommended feed list stored in podcast_podroll table
  (feedGuid, feedUrl, title, sort_order); returned as podroll[] in GetPodcasts
- podcast:liveItem: live stream detection stored in podcast_live_item table
  (one row per channel, unique index); stores status, start/end times,
  enclosure URL/type, and contentLink for fallback playback; returned as
  liveItem object in GetPodcasts; Upsert preserves created_at on updates
- podcast:podping: usesPodping boolean on channel; RefreshChannels skips
  channels with usesPodping=true (they receive updates via Podping WebSocket)

- 20260428000000_add_podcast20.go: ALTER TABLE adds 9 columns to
  podcast_channel, 9 columns to podcast_episode; CREATE TABLE
  podcast_transcript (episode_id FK, url, mime_type, language, rel) and
  podcast_person (no FK constraints — put() serialises "" not NULL)
- 20260428120000_add_podcast_tier3.go: ALTER TABLE adds uses_podping to
  podcast_channel; CREATE TABLE podcast_podroll and podcast_live_item
  (UNIQUE INDEX on channel_id)

GetPodcasts response (PodcastChannel) gains:
  podcastGuid, locked, medium, fundingUrl, fundingText, updateFrequency,
  complete, usesPodping, person[], podroll[], liveItem{}

GetPodcastEpisode response (PodcastEpisode) gains:
  season, seasonName, episode, episodeDisplay, chaptersUrl, soundbiteStart,
  soundbiteDur, transcript[], person[]

GetPodcastEpisode now loads transcripts and persons from their repositories
(previously only read the base episode row).

New OpenSubsonic extensions declared:
  podcastChapters, podcastTranscripts, podcastSeason, podcastPerson,
  podcastFunding, podcastMedium, podcastPodroll, podcastLiveItem, podcastPodping

- core/podcasts/rss_test.go: 41 new specs covering all namespace tags,
  default value handling (role→"host", group→"cast"), backward compatibility
- core/podcasts/podcasts_test.go: 26 new service specs covering AddChannel
  field persistence, transcript/person saving, podroll/liveItem saving,
  RefreshChannels podping skip behaviour
- persistence/podcast_transcript_repository_test.go: 10 specs
- persistence/podcast_person_repository_test.go: 12 specs
- persistence/podcast_podroll_repository_test.go: 10 specs
- persistence/podcast_live_item_repository_test.go: 8 specs
- server/subsonic/podcasts_test.go: 15 new handler specs for Tier 2 and
  Tier 3 fields in GetPodcasts and GetPodcastEpisode responses
2026-09-19 21:07:17 +09:00
..
fixtures refactor(lyrics): single ParseLyrics entry point + all-format plugin lyrics (#5632) 2026-06-19 18:25:35 -04:00
harness feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
fake_http_client.go Retry calls to Last.FM without MBIDs when if returns artist invalid (#1138) 2021-05-27 20:53:24 -04:00
init_tests.go fix: assorted scanner, plugin, and server fixes from the Go 1.27 work (#6050) 2026-08-30 21:24:50 -04:00
mock_album_repo.go fix(artwork): never retry absent artwork on its own (#6054) 2026-09-01 20:48:41 -04:00
mock_artist_repo.go fix(artwork): never retry absent artwork on its own (#6054) 2026-09-01 20:48:41 -04:00
mock_artwork_queue_repo.go fix(artwork): never retry absent artwork on its own (#6054) 2026-09-01 20:48:41 -04:00
mock_artwork_repo.go feat(artwork): store the resolution trace so artwork explain works offline (#5980) 2026-08-21 10:24:01 -04:00
mock_data_store.go feat(podcast): implement Podcasting 2.0 namespace support (Tier 1–3) 2026-09-19 21:07:17 +09:00
mock_ffmpeg.go fix(transcoding): include ffprobe in MSI and fall back gracefully when absent (#5326) 2026-04-07 20:11:38 -04:00
mock_genre_repo.go fix(jellyfin): resolve genre id as a MusicGenre item 2026-08-10 21:37:57 -04:00
mock_library_repo.go fix(server): return 404 instead of 500 for missing native API resources (#6131) 2026-09-14 22:46:21 -04:00
mock_library_service.go feat(plugins): New Plugin System with multi-language PDK support (#4833) 2026-01-14 19:22:48 -05:00
mock_mediafile_repo.go fix(server): return 404 instead of 500 for missing native API resources (#6131) 2026-09-14 22:46:21 -04:00
mock_playlist_repo.go fix(artwork): never retry absent artwork on its own (#6054) 2026-09-01 20:48:41 -04:00
mock_playlist_track_repo.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
mock_playqueue_repo.go feat(server): add update and clear play queue endpoints to native API (#4215) 2025-06-11 12:02:31 -04:00
mock_plugin_manager.go feat(plugins): allow mounting library directories as read-write (#5122) 2026-02-28 10:59:13 -05:00
mock_plugin_repo.go fix(server): return 404 instead of 500 for missing native API resources (#6131) 2026-09-14 22:46:21 -04:00
mock_podcast_channel_repo.go test(podcast): fix test failures after API changes 2026-09-19 21:07:17 +09:00
mock_podcast_episode_repo.go fix(podcast): address code review feedback 2026-09-19 21:07:17 +09:00
mock_podcast_live_item_repo.go feat(podcast): implement Podcasting 2.0 namespace support (Tier 1–3) 2026-09-19 21:07:17 +09:00
mock_podcast_person_repo.go feat(podcast): implement Podcasting 2.0 namespace support (Tier 1–3) 2026-09-19 21:07:17 +09:00
mock_podcast_podroll_repo.go feat(podcast): implement Podcasting 2.0 namespace support (Tier 1–3) 2026-09-19 21:07:17 +09:00
mock_podcast_transcript_repo.go feat(podcast): implement Podcasting 2.0 namespace support (Tier 1–3) 2026-09-19 21:07:17 +09:00
mock_property_repo.go refactor: external_metadata -> external.Provider (#3903) 2025-04-08 21:11:09 -04:00
mock_radio_repository.go fix(artwork): never retry absent artwork on its own (#6054) 2026-09-01 20:48:41 -04:00
mock_scanner.go fix(server): return correct scanType in startScan response (#5159) 2026-03-09 14:19:53 -04:00
mock_scrobble_buffer_repo.go fix(plugins): discard buffered scrobbles when a plugin is removed (#5737) 2026-07-08 12:37:17 -04:00
mock_scrobble_repo.go feat(server): add scrobble history Native API (#5761) 2026-07-13 11:32:03 -04:00
mock_share_repo.go fix(sharing): validate JWT expiration and share existence on stream endpoint (#5426) 2026-04-27 19:36:57 -04:00
mock_tag_repo.go feat(jellyfin): filter items by year and record label (#5817) 2026-07-19 12:39:31 -04:00
mock_transcoding_repo.go fix(transcoding): place -ss before -i for fast input seeking (#5492) 2026-05-13 17:17:20 -03:00
mock_user_props_repo.go refactor: external_metadata -> external.Provider (#3903) 2025-04-08 21:11:09 -04:00
mock_user_repo.go fix(scanner): import playlists skipped when no admin existed yet (#5609) 2026-06-14 13:39:16 -04:00
mock_user_service.go feat(plugins): New Plugin System with multi-language PDK support (#4833) 2026-01-14 19:22:48 -05:00
navidrome-test.toml feat(plugins): experimental support for plugins (#3998) 2025-06-22 20:45:38 -04:00
test_helpers.go ci: run Go tests on Windows (#5380) 2026-04-19 13:16:47 -04:00