Skip to content

Commit

Permalink
omit image tags if empty and add test
Browse files Browse the repository at this point in the history
  • Loading branch information
Artur authored and umputun committed Apr 10, 2022
1 parent 33f712a commit 67e4cba
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 35 deletions.
4 changes: 2 additions & 2 deletions app/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ func (s *Server) getFeedCtrl(w http.ResponseWriter, r *http.Request) {
baseURL := strings.TrimSuffix(s.Conf.System.BaseURL, "/")
rss.Link = baseURL + "/feed/" + feedName
imagesURL := baseURL + "/images/" + feedName
rss.ItunesImage = feed.ItunesImg{URL: imagesURL}
rss.MediaThumbnail = feed.MediaThumbnail{URL: imagesURL}
rss.ItunesImage = &feed.ItunesImg{URL: imagesURL}
rss.MediaThumbnail = &feed.MediaThumbnail{URL: imagesURL}
}

b, err := xml.MarshalIndent(&rss, "", " ")
Expand Down
111 changes: 94 additions & 17 deletions app/api/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,21 @@ func TestServer_getFeedCtrl(t *testing.T) {
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)

body, err := io.ReadAll(resp.Body)
respBody, err := io.ReadAll(resp.Body)
require.NoError(t, err)
t.Logf("resp body: %s", string(body))
assert.Contains(t, string(body), "<title>feed1</title>")
assert.Contains(t, string(body), "<language>ru-ru</language>")
assert.Contains(t, string(body), " <description>this is feed1</description>")
body := string(respBody)
t.Logf("resp body: %s", body)
assert.Contains(t, body, "<title>feed1</title>")
assert.Contains(t, body, "<language>ru-ru</language>")
assert.Contains(t, body, " <description>this is feed1</description>")

assert.Contains(t, string(body), "<guid>guid1</guid>")
assert.Contains(t, string(body), "<title>title1</title>")
assert.Contains(t, string(body), "<link>http://example.com/link1</link>")
assert.Contains(t, string(body), "<description>some description1</description>")
assert.Contains(t, string(body), `<enclosure url="http://example.com/enclosure1" length="12345" type="audio/mpeg"></enclosure>`)
assert.Contains(t, body, "<guid>guid1</guid>")
assert.Contains(t, body, "<title>title1</title>")
assert.Contains(t, body, "<link>http://example.com/link1</link>")
assert.Contains(t, body, "<description>some description1</description>")
assert.Contains(t, body, `<enclosure url="http://example.com/enclosure1" length="12345" type="audio/mpeg"></enclosure>`)
assert.NotContains(t, body, `<itunes:image href=""></itunes:image>`)
assert.NotContains(t, body, `<media:thumbnail url=""></media:thumbnail>`)

assert.Equal(t, 1, len(store.LoadCalls()))
assert.Equal(t, "feed1", store.LoadCalls()[0].FmFeed)
Expand Down Expand Up @@ -169,15 +172,89 @@ func TestServer_getFeedCtrlExtendDateTitle(t *testing.T) {
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)

body, err := io.ReadAll(resp.Body)
respBody, err := io.ReadAll(resp.Body)
require.NoError(t, err)
t.Logf("resp body: %s", string(body))
assert.Contains(t, string(body), "<title>feed1</title>")
assert.Contains(t, string(body), "<language>ru-ru</language>")
assert.Contains(t, string(body), " <description>this is feed1</description>")
body := string(respBody)
t.Logf("resp body: %s", body)
assert.Contains(t, body, "<title>feed1</title>")
assert.Contains(t, body, "<language>ru-ru</language>")
assert.Contains(t, body, " <description>this is feed1</description>")

assert.Contains(t, string(body), "<guid>guid1</guid>")
assert.Contains(t, string(body), "<title>title1 (2022-04-03)</title>")
assert.Contains(t, body, "<guid>guid1</guid>")
assert.Contains(t, body, "<title>title1 (2022-04-03)</title>")

assert.Equal(t, 1, len(store.LoadCalls()))
assert.Equal(t, "feed1", store.LoadCalls()[0].FmFeed)
}

func TestServer_getFeedCtrlFeedImage(t *testing.T) {

store := &mocks.StoreMock{
LoadFunc: func(fmFeed string, max int, skipJunk bool) ([]feed.Item, error) {
return []feed.Item{
{
GUID: "guid1",
Title: "title1",
Link: "http://example.com/link1",
Description: "some description1",
Enclosure: feed.Enclosure{
URL: "http://example.com/enclosure1",
Type: "audio/mpeg",
Length: 12345,
},
},
{
GUID: "guid2",
Title: "title2",
Link: "http://example.com/link2",
Description: "some description2",
Enclosure: feed.Enclosure{
URL: "http://example.com/enclosure2",
Type: "audio/mpeg",
Length: 12346,
},
},
}, nil
},
}

s := Server{
Version: "1.0",
TemplLocation: "../webapp/templates/*",
Store: store,
Conf: config.Conf{
Feeds: map[string]config.Feed{
"feed1": {
Title: "feed1",
Language: "ru-ru",
Description: "this is feed1",
Link: "http://example.com/feed1",
},
"feed2": {
Title: "feed2",
},
},
},
}
s.Conf.System.BaseURL = "http://example.com"

ts := httptest.NewServer(s.router())
defer ts.Close()

resp, err := ts.Client().Get(ts.URL + "/rss/feed1")
require.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)

respBody, err := io.ReadAll(resp.Body)
require.NoError(t, err)
body := string(respBody)
t.Logf("resp body: %s", body)
assert.Contains(t, body, "<title>feed1</title>")

assert.Contains(t, body, "<guid>guid1</guid>")
assert.Contains(t, body, `<itunes:image href="http://example.com/images/feed1"></itunes:image>`)
assert.Contains(t, body, `<media:thumbnail url="http://example.com/images/feed1"></media:thumbnail>`)

assert.Equal(t, 1, len(store.LoadCalls()))
assert.Equal(t, "feed1", store.LoadCalls()[0].FmFeed)
Expand Down
30 changes: 16 additions & 14 deletions app/feed/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,32 @@ import (

// Rss2 feed
type Rss2 struct {
XMLName xml.Name `xml:"rss"`
Version string `xml:"version,attr"`
NsItunes string `xml:"xmlns:itunes,attr"`
NsMedia string `xml:"xmlns:media,attr"`
Title string `xml:"channel>title"`
Language string `xml:"channel>language"`
Link string `xml:"channel>link"`
Description string `xml:"channel>description"`
PubDate string `xml:"channel>pubDate"`
LastBuildDate string `xml:"channel>lastBuildDate"`
ItunesImage ItunesImg `xml:"channel>itunes:image"`
MediaThumbnail MediaThumbnail `xml:"channel>media:thumbnail"`
XMLName xml.Name `xml:"rss"`
Version string `xml:"version,attr"`
NsItunes string `xml:"xmlns:itunes,attr"`
NsMedia string `xml:"xmlns:media,attr"`
Title string `xml:"channel>title"`
Language string `xml:"channel>language"`
Link string `xml:"channel>link"`
Description string `xml:"channel>description"`
PubDate string `xml:"channel>pubDate"`
LastBuildDate string `xml:"channel>lastBuildDate"`
ItunesImage *ItunesImg `xml:"channel>itunes:image"`
MediaThumbnail *MediaThumbnail `xml:"channel>media:thumbnail"`

ItemList []Item `xml:"channel>item"`
}

// ItunesImg image element for iTunes
type ItunesImg struct {
URL string `xml:"href,attr"`
XMLName xml.Name `xml:"itunes:image,omitempty"`
URL string `xml:"href,attr"`
}

// MediaThumbnail image element for media
type MediaThumbnail struct {
URL string `xml:"url,attr"`
XMLName xml.Name `xml:"media:thumbnail,omitempty"`
URL string `xml:"url,attr"`
}

// Enclosure element from item
Expand Down
4 changes: 2 additions & 2 deletions app/youtube/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ func (s *Service) RSSFeed(fi FeedInfo) (string, error) {
// set image from channel as rss thumbnail
// TODO: we may want to load it locally in case if youtube doesn't like such remote usage of images
if image := entries[0].Media.Thumbnail.URL; image != "" {
rss.ItunesImage.URL = image
rss.MediaThumbnail.URL = image
rss.ItunesImage = &rssfeed.ItunesImg{URL: image}
rss.MediaThumbnail = &rssfeed.MediaThumbnail{URL: image}
}

if fi.Type == ytfeed.FTPlaylist {
Expand Down

0 comments on commit 67e4cba

Please sign in to comment.