package rss import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) const testRSS = ` Example Blog https://example.com An example blog feed en-us Mon, 01 Jan 2024 00:00:00 GMT First Post https://example.com/first A short summary Full content of the first post

]]>
Alice Sun, 31 Dec 2023 12:00:00 GMT https://example.com/first Tech Go
Second Post https://example.com/second Another summary bob@example.com Mon, 01 Jan 2024 00:00:00 GMT https://example.com/second
` func TestParseRSS_Basic(t *testing.T) { feed, err := parseRSS([]byte(testRSS)) require.NoError(t, err) assert.Equal(t, "rss2.0", feed.Format) assert.Equal(t, "Example Blog", feed.Title) assert.Equal(t, "https://example.com", feed.Link) assert.Equal(t, "An example blog feed", feed.Description) assert.Equal(t, "en-us", feed.Language) assert.Equal(t, "Mon, 01 Jan 2024 00:00:00 GMT", feed.Updated) assert.Nil(t, feed.Podcast, "non-podcast feed should have nil Podcast") require.Len(t, feed.Items, 2) // First item item0 := feed.Items[0] assert.Equal(t, "First Post", item0.Title) assert.Equal(t, "https://example.com/first", item0.Link) assert.Equal(t, "A short summary", item0.Description) assert.Equal(t, "

Full content of the first post

", item0.Content) assert.Equal(t, "Alice", item0.Author) // dc:creator preferred assert.Equal(t, "Sun, 31 Dec 2023 12:00:00 GMT", item0.Published) assert.Equal(t, "https://example.com/first", item0.GUID) assert.Equal(t, []string{"Tech", "Go"}, item0.Categories) require.Len(t, item0.Enclosures, 1) assert.Equal(t, "https://example.com/audio.mp3", item0.Enclosures[0].URL) assert.Equal(t, "audio/mpeg", item0.Enclosures[0].Type) assert.Equal(t, "12345678", item0.Enclosures[0].Length) assert.Nil(t, item0.Episode) // Second item item1 := feed.Items[1] assert.Equal(t, "Second Post", item1.Title) assert.Equal(t, "bob@example.com", item1.Author) // fallback to assert.Empty(t, item1.Categories) assert.Empty(t, item1.Enclosures) } const testPodcast = ` My Awesome Podcast https://podcast.example.com A podcast about technology en Jane Doe Weekly tech discussions Jane Doe jane@example.com no episodic Episode 1: Getting Started https://podcast.example.com/ep1 Our first episode Wed, 15 Nov 2023 08:00:00 GMT https://podcast.example.com/ep1 01:23:45 1 1 full no In this episode we discuss getting started with podcasting Trailer https://podcast.example.com/trailer Preview of the show 120 trailer yes ` func TestParseRSS_Podcast(t *testing.T) { feed, err := parseRSS([]byte(testPodcast)) require.NoError(t, err) assert.Equal(t, "rss2.0", feed.Format) assert.Equal(t, "My Awesome Podcast", feed.Title) // Podcast metadata require.NotNil(t, feed.Podcast) p := feed.Podcast assert.Equal(t, "Jane Doe", p.Author) assert.Equal(t, "Weekly tech discussions", p.Summary) assert.Equal(t, "https://podcast.example.com/cover.jpg", p.Image) assert.Equal(t, false, p.Explicit) assert.Equal(t, "episodic", p.Type) require.NotNil(t, p.Owner) assert.Equal(t, "Jane Doe", p.Owner.Name) assert.Equal(t, "jane@example.com", p.Owner.Email) // Categories: "Technology", "Technology > Podcasting", "Education" require.Len(t, p.Category, 3) assert.Equal(t, "Technology", p.Category[0]) assert.Equal(t, "Technology > Podcasting", p.Category[1]) assert.Equal(t, "Education", p.Category[2]) // Episodes require.Len(t, feed.Items, 2) ep0 := feed.Items[0] require.NotNil(t, ep0.Episode) assert.Equal(t, "01:23:45", ep0.Episode.Duration) assert.Equal(t, 1, ep0.Episode.Season) assert.Equal(t, 1, ep0.Episode.Number) assert.Equal(t, "full", ep0.Episode.Type) assert.Equal(t, false, ep0.Episode.Explicit) assert.Equal(t, "https://podcast.example.com/ep1-cover.jpg", ep0.Episode.Image) assert.Equal(t, "In this episode we discuss getting started with podcasting", ep0.Episode.Summary) ep1 := feed.Items[1] require.NotNil(t, ep1.Episode) assert.Equal(t, "120", ep1.Episode.Duration) assert.Equal(t, "trailer", ep1.Episode.Type) assert.Equal(t, true, ep1.Episode.Explicit) assert.Equal(t, 0, ep1.Episode.Season) // not set assert.Equal(t, 0, ep1.Episode.Number) // not set } func TestParseRSS_MinimalFeed(t *testing.T) { xml := ` Minimal https://example.com Bare minimum ` feed, err := parseRSS([]byte(xml)) require.NoError(t, err) assert.Equal(t, "Minimal", feed.Title) assert.Empty(t, feed.Items) assert.Nil(t, feed.Podcast) } func TestParseRSS_InvalidXML(t *testing.T) { _, err := parseRSS([]byte(`broken`)) assert.Error(t, err) } func TestIsExplicit(t *testing.T) { assert.True(t, isExplicit("yes")) assert.True(t, isExplicit("Yes")) assert.True(t, isExplicit("true")) assert.True(t, isExplicit("explicit")) assert.False(t, isExplicit("no")) assert.False(t, isExplicit("false")) assert.False(t, isExplicit("clean")) assert.False(t, isExplicit("")) } func TestFirstNonEmpty(t *testing.T) { assert.Equal(t, "a", firstNonEmpty("a", "b")) assert.Equal(t, "b", firstNonEmpty("", "b")) assert.Equal(t, "c", firstNonEmpty("", "", "c")) assert.Equal(t, "", firstNonEmpty("", "")) assert.Equal(t, "x", firstNonEmpty(" ", " x ")) } func TestFlattenCategories(t *testing.T) { cats := []itunesCategory{ {Text: "Technology", Sub: []itunesCategory{{Text: "Podcasting"}}}, {Text: "Education"}, } result := flattenCategories(cats) assert.Equal(t, []string{"Technology", "Technology > Podcasting", "Education"}, result) } func TestFlattenCategories_Empty(t *testing.T) { result := flattenCategories(nil) assert.Nil(t, result) }