2023-06-19 23:42:47 +02:00
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
2017-11-20 06:10:04 +01:00
2023-08-11 04:46:45 +02:00
package rss // import "miniflux.app/v2/internal/reader/rss"
2017-11-20 06:10:04 +01:00
import (
"bytes"
"testing"
"time"
)
func TestParseRss2Sample ( t * testing . T ) {
data := `
< ? xml version = "1.0" ? >
< rss version = "2.0" >
< channel >
< title > Liftoff News < / title >
< link > http : //liftoff.msfc.nasa.gov/</link>
< description > Liftoff to Space Exploration . < / description >
2023-06-05 00:01:59 +02:00
< image >
< url > http : //liftoff.msfc.nasa.gov/HomePageXtra/MeatBall.gif</url>
< title > NASA < / title >
< link > http : //liftoff.msfc.nasa.gov/</link>
< / image >
2017-11-20 06:10:04 +01:00
< language > en - us < / language >
< pubDate > Tue , 10 Jun 2003 04 : 00 : 00 GMT < / pubDate >
< lastBuildDate > Tue , 10 Jun 2003 0 9 : 41 : 01 GMT < / lastBuildDate >
< docs > http : //blogs.law.harvard.edu/tech/rss</docs>
< generator > Weblog Editor 2.0 < / generator >
< managingEditor > editor @ example . com < / managingEditor >
< webMaster > webmaster @ example . com < / webMaster >
< item >
< title > Star City < / title >
< link > http : //liftoff.msfc.nasa.gov/news/2003/news-starcity.asp</link>
< description > How do Americans get ready to work with Russians aboard the International Space Station ? They take a crash course in culture , language and protocol at Russia ' s & lt ; a href = "http://howe.iki.rssi.ru/GCTC/gctc_e.htm" & gt ; Star City & lt ; / a & gt ; . < / description >
< pubDate > Tue , 03 Jun 2003 0 9 : 39 : 21 GMT < / pubDate >
< guid > http : //liftoff.msfc.nasa.gov/2003/06/03.html#item573</guid>
< / item >
< item >
< description > Sky watchers in Europe , Asia , and parts of Alaska and Canada will experience a & lt ; a href = "http://science.nasa.gov/headlines/y2003/30may_solareclipse.htm" & gt ; partial eclipse of the Sun & lt ; / a & gt ; on Saturday , May 31 st . < / description >
< pubDate > Fri , 30 May 2003 11 : 06 : 42 GMT < / pubDate >
< guid > http : //liftoff.msfc.nasa.gov/2003/05/30.html#item572</guid>
< / item >
< item >
< title > The Engine That Does More < / title >
< link > http : //liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp</link>
< description > Before man travels to Mars , NASA hopes to design new engines that will let us fly through the Solar System more quickly . The proposed VASIMR engine would do that . < / description >
< pubDate > Tue , 27 May 2003 0 8 : 37 : 32 GMT < / pubDate >
< guid > http : //liftoff.msfc.nasa.gov/2003/05/27.html#item571</guid>
< / item >
< item >
< title > Astronauts ' Dirty Laundry < / title >
< link > http : //liftoff.msfc.nasa.gov/news/2003/news-laundry.asp</link>
< description > Compared to earlier spacecraft , the International Space Station has many luxuries , but laundry facilities are not one of them . Instead , astronauts have other options . < / description >
< pubDate > Tue , 20 May 2003 0 8 : 56 : 02 GMT < / pubDate >
< guid > http : //liftoff.msfc.nasa.gov/2003/05/20.html#item570</guid>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "http://liftoff.msfc.nasa.gov/rss.xml" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
if feed . Title != "Liftoff News" {
t . Errorf ( "Incorrect title, got: %s" , feed . Title )
}
2020-12-03 05:47:11 +01:00
if feed . FeedURL != "http://liftoff.msfc.nasa.gov/rss.xml" {
2017-11-20 06:10:04 +01:00
t . Errorf ( "Incorrect feed URL, got: %s" , feed . FeedURL )
}
if feed . SiteURL != "http://liftoff.msfc.nasa.gov/" {
t . Errorf ( "Incorrect site URL, got: %s" , feed . SiteURL )
}
2023-06-05 00:01:59 +02:00
if feed . IconURL != "http://liftoff.msfc.nasa.gov/HomePageXtra/MeatBall.gif" {
t . Errorf ( "Incorrect image URL, got: %s" , feed . IconURL )
}
2017-11-20 06:10:04 +01:00
if len ( feed . Entries ) != 4 {
t . Errorf ( "Incorrect number of entries, got: %d" , len ( feed . Entries ) )
}
expectedDate := time . Date ( 2003 , time . June , 3 , 9 , 39 , 21 , 0 , time . UTC )
if ! feed . Entries [ 0 ] . Date . Equal ( expectedDate ) {
t . Errorf ( "Incorrect entry date, got: %v, want: %v" , feed . Entries [ 0 ] . Date , expectedDate )
}
if feed . Entries [ 0 ] . Hash != "5b2b4ac2fe1786ddf0fd2da2f1b07f64e691264f41f2db3ea360f31bb6d9152b" {
t . Errorf ( "Incorrect entry hash, got: %s" , feed . Entries [ 0 ] . Hash )
}
if feed . Entries [ 0 ] . URL != "http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp" {
t . Errorf ( "Incorrect entry URL, got: %s" , feed . Entries [ 0 ] . URL )
}
if feed . Entries [ 0 ] . Title != "Star City" {
t . Errorf ( "Incorrect entry title, got: %s" , feed . Entries [ 0 ] . Title )
}
2017-12-12 07:16:32 +01:00
if feed . Entries [ 0 ] . Content != ` How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia's <a href="http://howe.iki.rssi.ru/GCTC/gctc_e.htm">Star City</a>. ` {
2017-11-20 06:10:04 +01:00
t . Errorf ( "Incorrect entry content, got: %s" , feed . Entries [ 0 ] . Content )
}
2022-10-10 01:51:39 +02:00
if feed . Entries [ 1 ] . URL != "http://liftoff.msfc.nasa.gov/2003/05/30.html#item572" {
t . Errorf ( "Incorrect entry URL, got: %s" , feed . Entries [ 1 ] . URL )
}
2017-11-20 06:10:04 +01:00
}
func TestParseFeedWithoutTitle ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< link > https : //example.org/</link>
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
if feed . Title != "https://example.org/" {
t . Errorf ( "Incorrect feed title, got: %s" , feed . Title )
}
}
2022-03-05 01:49:44 +01:00
func TestParseEntryWithoutTitleAndDescription ( t * testing . T ) {
2017-11-20 06:10:04 +01:00
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< link > https : //example.org/</link>
< item >
< link > https : //example.org/item</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
if feed . Entries [ 0 ] . Title != "https://example.org/item" {
t . Errorf ( "Incorrect entry title, got: %s" , feed . Entries [ 0 ] . Title )
}
2020-06-30 03:08:19 +02:00
}
2022-03-05 01:49:44 +01:00
func TestParseEntryWithoutTitleButWithDescription ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< link > https : //example.org/</link>
< item >
< link > https : //example.org/item</link>
< description >
This is the description
< / description >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2022-03-05 01:49:44 +01:00
if err != nil {
t . Fatal ( err )
}
if feed . Entries [ 0 ] . Title != "This is the description" {
t . Errorf ( "Incorrect entry title, got: %s" , feed . Entries [ 0 ] . Title )
}
}
2020-06-30 03:08:19 +02:00
func TestParseEntryWithMediaTitle ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : media = "http://search.yahoo.com/mrss/" >
< channel >
< link > https : //example.org/</link>
< item >
< title > Entry Title < / title >
< link > https : //example.org/item</link>
< media : title > Media Title < / media : title >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2020-06-30 03:08:19 +02:00
if err != nil {
t . Fatal ( err )
}
if feed . Entries [ 0 ] . Title != "Entry Title" {
t . Errorf ( "Incorrect entry title, got: %q" , feed . Entries [ 0 ] . Title )
}
}
func TestParseEntryWithDCTitleOnly ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : media = "http://search.yahoo.com/mrss/" xmlns : dc = "http://purl.org/dc/elements/1.1/" >
< channel >
< link > https : //example.org/</link>
< item >
< dc : title > Entry Title < / dc : title >
< link > https : //example.org/item</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2020-06-30 03:08:19 +02:00
if err != nil {
t . Fatal ( err )
}
if feed . Entries [ 0 ] . Title != "Entry Title" {
t . Errorf ( "Incorrect entry title, got: %q" , feed . Entries [ 0 ] . Title )
}
2017-11-20 06:10:04 +01:00
}
2017-11-21 00:15:10 +01:00
func TestParseEntryWithoutLink ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< link > https : //example.org/</link>
< item >
< guid isPermaLink = "false" > 1234 < / guid >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-21 00:15:10 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-21 00:15:10 +01:00
}
if feed . Entries [ 0 ] . URL != "https://example.org/" {
t . Errorf ( "Incorrect entry link, got: %s" , feed . Entries [ 0 ] . URL )
}
if feed . Entries [ 0 ] . Hash != "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4" {
t . Errorf ( "Incorrect entry hash, got: %s" , feed . Entries [ 0 ] . Hash )
}
}
2022-10-10 01:51:39 +02:00
func TestParseEntryWithOnlyGuidPermalink ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< link > https : //example.org/</link>
< item >
< guid isPermaLink = "true" > https : //example.org/some-article.html</guid>
< / item >
< item >
< guid > https : //example.org/another-article.html</guid>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2022-10-10 01:51:39 +02:00
if err != nil {
t . Fatal ( err )
}
if feed . Entries [ 0 ] . URL != "https://example.org/some-article.html" {
t . Errorf ( "Incorrect entry link, got: %s" , feed . Entries [ 0 ] . URL )
}
if feed . Entries [ 1 ] . URL != "https://example.org/another-article.html" {
t . Errorf ( "Incorrect entry link, got: %s" , feed . Entries [ 1 ] . URL )
}
}
2017-11-21 00:48:26 +01:00
func TestParseEntryWithAtomLink ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : atom = "http://www.w3.org/2005/Atom" >
< channel >
< link > https : //example.org/</link>
< item >
< title > Test < / title >
< atom : link href = "https://example.org/item" / >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-21 00:48:26 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-21 00:48:26 +01:00
}
if feed . Entries [ 0 ] . URL != "https://example.org/item" {
t . Errorf ( "Incorrect entry link, got: %s" , feed . Entries [ 0 ] . URL )
}
}
func TestParseEntryWithMultipleAtomLinks ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : atom = "http://www.w3.org/2005/Atom" >
< channel >
< link > https : //example.org/</link>
< item >
< title > Test < / title >
< atom : link rel = "payment" href = "https://example.org/a" / >
< atom : link rel = "http://foobar.tld" href = "https://example.org/b" / >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-21 00:48:26 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-21 00:48:26 +01:00
}
if feed . Entries [ 0 ] . URL != "https://example.org/b" {
t . Errorf ( "Incorrect entry link, got: %s" , feed . Entries [ 0 ] . URL )
}
}
2017-11-20 06:10:04 +01:00
func TestParseFeedURLWithAtomLink ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss xmlns : atom = "http://www.w3.org/2005/Atom" version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< atom : link href = "https://example.org/rss" type = "application/rss+xml" rel = "self" > < / atom : link >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
if feed . FeedURL != "https://example.org/rss" {
t . Errorf ( "Incorrect feed URL, got: %s" , feed . FeedURL )
}
if feed . SiteURL != "https://example.org/" {
t . Errorf ( "Incorrect site URL, got: %s" , feed . SiteURL )
}
}
2019-12-23 22:29:53 +01:00
func TestParseFeedWithWebmaster ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< webMaster > webmaster @ example . com < / webMaster >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
expected := "webmaster@example.com"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
}
}
func TestParseFeedWithManagingEditor ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< webMaster > webmaster @ example . com < / webMaster >
< managingEditor > editor @ example . com < / managingEditor >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
expected := "editor@example.com"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
}
}
2018-03-18 19:57:46 +01:00
func TestParseEntryWithAuthorAndInnerHTML ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss xmlns : atom = "http://www.w3.org/2005/Atom" version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< atom : link href = "https://example.org/rss" type = "application/rss+xml" rel = "self" > < / atom : link >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< author > by < a itemprop = "url" class = "author" rel = "author" href = "/author/foobar" > Foo Bar < / a > < / author >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2018-03-18 19:57:46 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2018-03-18 19:57:46 +01:00
}
2019-12-23 22:29:53 +01:00
expected := "by Foo Bar"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
2018-03-18 19:57:46 +01:00
}
}
2021-02-28 21:26:52 +01:00
func TestParseEntryWithAuthorAndCDATA ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss xmlns : atom = "http://www.w3.org/2005/Atom" version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< atom : link href = "https://example.org/rss" type = "application/rss+xml" rel = "self" > < / atom : link >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< author >
by < ! [ CDATA [ Foo Bar ] ] >
< / author >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2021-02-28 21:26:52 +01:00
if err != nil {
t . Fatal ( err )
}
expected := "by Foo Bar"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
}
}
2019-12-23 22:29:53 +01:00
func TestParseEntryWithNonStandardAtomAuthor ( t * testing . T ) {
2017-11-20 06:10:04 +01:00
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss xmlns : atom = "http://www.w3.org/2005/Atom" version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< atom : link href = "https://example.org/rss" type = "application/rss+xml" rel = "self" > < / atom : link >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< author xmlns : author = "http://www.w3.org/2005/Atom" >
< name > Foo Bar < / name >
< title > Vice President < / title >
< department / >
< company > FooBar Inc . < / company >
< / author >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
2019-12-23 22:29:53 +01:00
expected := "Foo Bar"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
}
}
func TestParseEntryWithAtomAuthorEmail ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss xmlns : atom = "http://www.w3.org/2005/Atom" version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< atom : link href = "https://example.org/rss" type = "application/rss+xml" rel = "self" > < / atom : link >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< atom : author >
< email > author @ example . org < / email >
< / atom : author >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
expected := "author@example.org"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
}
}
func TestParseEntryWithAtomAuthor ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss xmlns : atom = "http://www.w3.org/2005/Atom" version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< atom : link href = "https://example.org/rss" type = "application/rss+xml" rel = "self" > < / atom : link >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< atom : author >
< name > Foo Bar < / name >
< / atom : author >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
expected := "Foo Bar"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got: %q instead of %q" , result , expected )
2017-11-20 06:10:04 +01:00
}
}
func TestParseEntryWithDublinCoreAuthor ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : dc = "http://purl.org/dc/elements/1.1/" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< dc : creator > Me ( me @ example . com ) < / dc : creator >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
2019-12-23 22:29:53 +01:00
expected := "Me (me@example.com)"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
2017-11-20 06:10:04 +01:00
}
}
func TestParseEntryWithItunesAuthor ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : itunes = "http://www.itunes.com/dtds/podcast-1.0.dtd" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< itunes : author > Someone < / itunes : author >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
2019-12-23 22:29:53 +01:00
expected := "Someone"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
2017-11-20 06:10:04 +01:00
}
}
func TestParseFeedWithItunesAuthor ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : itunes = "http://www.itunes.com/dtds/podcast-1.0.dtd" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< itunes : author > Someone < / itunes : author >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
2019-12-23 22:29:53 +01:00
expected := "Someone"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
}
}
func TestParseFeedWithItunesOwner ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : itunes = "http://www.itunes.com/dtds/podcast-1.0.dtd" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< itunes : owner >
< itunes : name > John Doe < / itunes : name >
< itunes : email > john . doe @ example . com < / itunes : email >
< / itunes : owner >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
expected := "John Doe"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
}
}
func TestParseFeedWithItunesOwnerEmail ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : itunes = "http://www.itunes.com/dtds/podcast-1.0.dtd" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< itunes : owner >
< itunes : email > john . doe @ example . com < / itunes : email >
< / itunes : owner >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
expected := "john.doe@example.com"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
}
}
func TestParseEntryWithGooglePlayAuthor ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : googleplay = "http://www.google.com/schemas/play-podcasts/1.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< googleplay : author > Someone < / googleplay : author >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
expected := "Someone"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
}
}
func TestParseFeedWithGooglePlayAuthor ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : googleplay = "http://www.google.com/schemas/play-podcasts/1.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< googleplay : author > Someone < / googleplay : author >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
expected := "Someone"
result := feed . Entries [ 0 ] . Author
if result != expected {
t . Errorf ( "Incorrect entry author, got %q instead of %q" , result , expected )
2017-11-20 06:10:04 +01:00
}
}
func TestParseEntryWithDublinCoreDate ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : dc = "http://purl.org/dc/elements/1.1/" >
< channel >
< title > Example < / title >
< link > http : //example.org/</link>
< item >
< title > Item 1 < / title >
< link > http : //example.org/item1</link>
< description > Description . < / description >
< guid isPermaLink = "false" > UUID < / guid >
< dc : date > 2002 - 0 9 - 29 T23 : 40 : 06 - 05 : 00 < / dc : date >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
location , _ := time . LoadLocation ( "EST" )
expectedDate := time . Date ( 2002 , time . September , 29 , 23 , 40 , 06 , 0 , location )
if ! feed . Entries [ 0 ] . Date . Equal ( expectedDate ) {
t . Errorf ( "Incorrect entry date, got: %v, want: %v" , feed . Entries [ 0 ] . Date , expectedDate )
}
}
func TestParseEntryWithContentEncoded ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : content = "http://purl.org/rss/1.0/modules/content/" >
< channel >
< title > Example < / title >
< link > http : //example.org/</link>
< item >
< title > Item 1 < / title >
< link > http : //example.org/item1</link>
< description > Description . < / description >
< guid isPermaLink = "false" > UUID < / guid >
< content : encoded > < ! [ CDATA [ < p > < a href = "http://www.example.org/" > Example < / a > . < / p > ] ] > < / content : encoded >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
2017-12-12 07:16:32 +01:00
if feed . Entries [ 0 ] . Content != ` <p><a href="http://www.example.org/">Example</a>.</p> ` {
2017-11-20 06:10:04 +01:00
t . Errorf ( "Incorrect entry content, got: %s" , feed . Entries [ 0 ] . Content )
}
}
func TestParseEntryWithFeedBurnerLink ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : feedburner = "http://rssnamespace.org/feedburner/ext/1.0" >
< channel >
< title > Example < / title >
< link > http : //example.org/</link>
< item >
< title > Item 1 < / title >
< link > http : //example.org/item1</link>
< feedburner : origLink > http : //example.org/original</feedburner:origLink>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
if feed . Entries [ 0 ] . URL != "http://example.org/original" {
t . Errorf ( "Incorrect entry content, got: %s" , feed . Entries [ 0 ] . URL )
}
}
func TestParseEntryTitleWithWhitespaces ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< title > Example < / title >
< link > http : //example.org</link>
< item >
< title >
Some Title
< / title >
< link > http : //www.example.org/entries/1</link>
< pubDate > Fri , 15 Jul 2005 00 : 00 : 00 - 0500 < / pubDate >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
if feed . Entries [ 0 ] . Title != "Some Title" {
t . Errorf ( "Incorrect entry title, got: %s" , feed . Entries [ 0 ] . Title )
}
}
func TestParseEntryWithEnclosures ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< title > My Podcast Feed < / title >
< link > http : //example.org</link>
< author > some . email @ example . org < / author >
< item >
< title > Podcasting with RSS < / title >
< link > http : //www.example.org/entries/1</link>
< description > An overview of RSS podcasting < / description >
< pubDate > Fri , 15 Jul 2005 00 : 00 : 00 - 0500 < / pubDate >
< guid isPermaLink = "true" > http : //www.example.org/entries/1</guid>
< enclosure url = "http://www.example.org/myaudiofile.mp3"
length = "12345"
type = "audio/mpeg" / >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
if len ( feed . Entries ) != 1 {
t . Errorf ( "Incorrect number of entries, got: %d" , len ( feed . Entries ) )
}
if feed . Entries [ 0 ] . URL != "http://www.example.org/entries/1" {
t . Errorf ( "Incorrect entry URL, got: %s" , feed . Entries [ 0 ] . URL )
}
if len ( feed . Entries [ 0 ] . Enclosures ) != 1 {
t . Errorf ( "Incorrect number of enclosures, got: %d" , len ( feed . Entries [ 0 ] . Enclosures ) )
}
if feed . Entries [ 0 ] . Enclosures [ 0 ] . URL != "http://www.example.org/myaudiofile.mp3" {
t . Errorf ( "Incorrect enclosure URL, got: %s" , feed . Entries [ 0 ] . Enclosures [ 0 ] . URL )
}
if feed . Entries [ 0 ] . Enclosures [ 0 ] . MimeType != "audio/mpeg" {
t . Errorf ( "Incorrect enclosure type, got: %s" , feed . Entries [ 0 ] . Enclosures [ 0 ] . MimeType )
}
if feed . Entries [ 0 ] . Enclosures [ 0 ] . Size != 12345 {
t . Errorf ( "Incorrect enclosure length, got: %d" , feed . Entries [ 0 ] . Enclosures [ 0 ] . Size )
}
}
2020-01-31 06:08:11 +01:00
func TestParseEntryWithEmptyEnclosureURL ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< title > My Podcast Feed < / title >
< link > http : //example.org</link>
< author > some . email @ example . org < / author >
< item >
< title > Podcasting with RSS < / title >
< link > http : //www.example.org/entries/1</link>
< description > An overview of RSS podcasting < / description >
< pubDate > Fri , 15 Jul 2005 00 : 00 : 00 - 0500 < / pubDate >
< guid isPermaLink = "true" > http : //www.example.org/entries/1</guid>
< enclosure url = "" length = "0" / >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2020-01-31 06:08:11 +01:00
if err != nil {
t . Fatal ( err )
}
if len ( feed . Entries ) != 1 {
t . Errorf ( "Incorrect number of entries, got: %d" , len ( feed . Entries ) )
}
if feed . Entries [ 0 ] . URL != "http://www.example.org/entries/1" {
t . Errorf ( "Incorrect entry URL, got: %s" , feed . Entries [ 0 ] . URL )
}
if len ( feed . Entries [ 0 ] . Enclosures ) != 0 {
t . Errorf ( "Incorrect number of enclosures, got: %d" , len ( feed . Entries [ 0 ] . Enclosures ) )
}
}
2017-11-20 06:10:04 +01:00
func TestParseEntryWithFeedBurnerEnclosures ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : feedburner = "http://rssnamespace.org/feedburner/ext/1.0" >
< channel >
< title > My Example Feed < / title >
< link > http : //example.org</link>
< author > some . email @ example . org < / author >
< item >
< title > Example Item < / title >
< link > http : //www.example.org/entries/1</link>
< enclosure
url = "http://feedproxy.google.com/~r/example/~5/lpMyFSCvubs/File.mp3"
length = "76192460"
type = "audio/mpeg" / >
< feedburner : origEnclosureLink > http : //example.org/67ca416c-f22a-4228-a681-68fc9998ec10/File.mp3</feedburner:origEnclosureLink>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-20 06:10:04 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-11-20 06:10:04 +01:00
}
if len ( feed . Entries ) != 1 {
t . Errorf ( "Incorrect number of entries, got: %d" , len ( feed . Entries ) )
}
if feed . Entries [ 0 ] . URL != "http://www.example.org/entries/1" {
t . Errorf ( "Incorrect entry URL, got: %s" , feed . Entries [ 0 ] . URL )
}
if len ( feed . Entries [ 0 ] . Enclosures ) != 1 {
t . Errorf ( "Incorrect number of enclosures, got: %d" , len ( feed . Entries [ 0 ] . Enclosures ) )
}
if feed . Entries [ 0 ] . Enclosures [ 0 ] . URL != "http://example.org/67ca416c-f22a-4228-a681-68fc9998ec10/File.mp3" {
t . Errorf ( "Incorrect enclosure URL, got: %s" , feed . Entries [ 0 ] . Enclosures [ 0 ] . URL )
}
if feed . Entries [ 0 ] . Enclosures [ 0 ] . MimeType != "audio/mpeg" {
t . Errorf ( "Incorrect enclosure type, got: %s" , feed . Entries [ 0 ] . Enclosures [ 0 ] . MimeType )
}
if feed . Entries [ 0 ] . Enclosures [ 0 ] . Size != 76192460 {
t . Errorf ( "Incorrect enclosure length, got: %d" , feed . Entries [ 0 ] . Enclosures [ 0 ] . Size )
}
}
2017-11-21 00:48:26 +01:00
2017-12-14 05:16:15 +01:00
func TestParseEntryWithRelativeURL ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< link > https : //example.org/</link>
< item >
< link > item . html < / link >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-12-14 05:16:15 +01:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2017-12-14 05:16:15 +01:00
}
if feed . Entries [ 0 ] . Title != "https://example.org/item.html" {
t . Errorf ( "Incorrect entry title, got: %s" , feed . Entries [ 0 ] . Title )
}
}
2018-04-07 22:56:11 +02:00
func TestParseEntryWithCommentsURL ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
2018-04-10 05:30:55 +02:00
< rss version = "2.0" xmlns : slash = "http://purl.org/rss/1.0/modules/slash/" >
2018-04-07 22:56:11 +02:00
< channel >
< link > https : //example.org/</link>
< item >
< title > Item 1 < / title >
< link > https : //example.org/item1</link>
2018-04-10 05:30:55 +02:00
< comments >
https : //example.org/comments
< / comments >
< slash : comments > 42 < / slash : comments >
2018-04-07 22:56:11 +02:00
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2018-04-07 22:56:11 +02:00
if err != nil {
2019-08-16 06:37:17 +02:00
t . Fatal ( err )
2018-04-07 22:56:11 +02:00
}
if feed . Entries [ 0 ] . CommentsURL != "https://example.org/comments" {
t . Errorf ( "Incorrect entry comments URL, got: %q" , feed . Entries [ 0 ] . CommentsURL )
}
}
2020-01-05 00:18:24 +01:00
func TestParseEntryWithInvalidCommentsURL ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : slash = "http://purl.org/rss/1.0/modules/slash/" >
< channel >
< link > https : //example.org/</link>
< item >
< title > Item 1 < / title >
< link > https : //example.org/item1</link>
< comments >
Some text
< / comments >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2020-01-05 00:18:24 +01:00
if err != nil {
t . Fatal ( err )
}
if feed . Entries [ 0 ] . CommentsURL != "" {
t . Errorf ( "Incorrect entry comments URL, got: %q" , feed . Entries [ 0 ] . CommentsURL )
}
}
2017-11-21 00:48:26 +01:00
func TestParseInvalidXml ( t * testing . T ) {
data := ` garbage `
2024-03-06 14:57:21 +01:00
_ , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2017-11-21 00:48:26 +01:00
if err == nil {
t . Error ( "Parse should returns an error" )
}
}
2019-08-16 06:37:17 +02:00
2021-01-03 20:33:10 +01:00
func TestParseFeedTitleWithHTMLEntity ( t * testing . T ) {
2019-08-16 06:37:17 +02:00
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : slash = "http://purl.org/rss/1.0/modules/slash/" >
< channel >
< link > https : //example.org/</link>
< title > Example & nbsp ; Feed < / title >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-08-16 06:37:17 +02:00
if err != nil {
t . Fatal ( err )
}
if feed . Title != "Example \u00a0 Feed" {
t . Errorf ( ` Incorrect title, got: %q ` , feed . Title )
}
}
2019-09-19 07:27:25 +02:00
2021-05-01 07:49:17 +02:00
func TestParseFeedTitleWithUnicodeEntityAndCdata ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : slash = "http://purl.org/rss/1.0/modules/slash/" >
< channel >
< link > https : //example.org/</link>
< title > < ! [ CDATA [ Jenny & # 8217 ; s Newsletter ] ] > < / title >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2021-05-01 07:49:17 +02:00
if err != nil {
t . Fatal ( err )
}
if feed . Title != ` Jenny’ s Newsletter ` {
t . Errorf ( ` Incorrect title, got: %q ` , feed . Title )
}
}
2021-01-03 20:33:10 +01:00
func TestParseItemTitleWithHTMLEntity ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : slash = "http://purl.org/rss/1.0/modules/slash/" >
< channel >
< link > https : //example.org/</link>
< title > Example < / title >
< item >
< title > & lt ; / example & gt ; < / title >
< link > http : //www.example.org/entries/1</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2021-01-03 20:33:10 +01:00
if err != nil {
t . Fatal ( err )
}
if feed . Entries [ 0 ] . Title != "</example>" {
2021-02-13 22:26:55 +01:00
t . Errorf ( ` Incorrect title, got: %q ` , feed . Entries [ 0 ] . Title )
}
}
func TestParseItemTitleWithNumericCharacterReference ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : slash = "http://purl.org/rss/1.0/modules/slash/" >
< channel >
< link > https : //example.org/</link>
< title > Example < / title >
< item >
< title > & # 931 ; & # xDF ; < / title >
< link > http : //www.example.org/article.html</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2021-02-13 22:26:55 +01:00
if err != nil {
t . Fatal ( err )
}
if feed . Entries [ 0 ] . Title != "Σ ß" {
t . Errorf ( ` Incorrect title, got: %q ` , feed . Entries [ 0 ] . Title )
}
}
func TestParseItemTitleWithDoubleEncodedEntities ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : slash = "http://purl.org/rss/1.0/modules/slash/" >
< channel >
< link > https : //example.org/</link>
< title > Example < / title >
< item >
< title > & amp ; # 39 ; Text & amp ; # 39 ; < / title >
< link > http : //www.example.org/article.html</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2021-02-13 22:26:55 +01:00
if err != nil {
t . Fatal ( err )
}
if feed . Entries [ 0 ] . Title != "'Text'" {
t . Errorf ( ` Incorrect title, got: %q ` , feed . Entries [ 0 ] . Title )
2021-01-03 20:33:10 +01:00
}
}
func TestParseFeedLinkWithInvalidCharacterEntity ( t * testing . T ) {
2019-09-19 07:27:25 +02:00
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : slash = "http://purl.org/rss/1.0/modules/slash/" >
< channel >
< link > https : //example.org/a&b</link>
< title > Example Feed < / title >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-09-19 07:27:25 +02:00
if err != nil {
t . Fatal ( err )
}
if feed . SiteURL != "https://example.org/a&b" {
t . Errorf ( ` Incorrect url, got: %q ` , feed . SiteURL )
}
}
2019-11-29 06:21:00 +01:00
func TestParseEntryWithMediaGroup ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : media = "http://search.yahoo.com/mrss/" >
< channel >
< title > My Example Feed < / title >
< link > http : //example.org</link>
< item >
< title > Example Item < / title >
< link > http : //www.example.org/entries/1</link>
< enclosure type = "application/x-bittorrent" url = "https://example.org/file3.torrent" length = "670053113" >
< / enclosure >
< media : group >
< media : content type = "application/x-bittorrent" url = "https://example.org/file1.torrent" > < / media : content >
< media : content type = "application/x-bittorrent" url = "https://example.org/file2.torrent" isDefault = "true" > < / media : content >
< media : content type = "application/x-bittorrent" url = "https://example.org/file3.torrent" > < / media : content >
< media : content type = "application/x-bittorrent" url = "https://example.org/file4.torrent" > < / media : content >
< media : content type = "application/x-bittorrent" url = "https://example.org/file5.torrent" fileSize = "42" > < / media : content >
< media : rating > nonadult < / media : rating >
< / media : group >
< media : thumbnail url = "https://example.org/image.jpg" height = "122" width = "223" > < / media : thumbnail >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-11-29 06:21:00 +01:00
if err != nil {
t . Fatal ( err )
}
if len ( feed . Entries ) != 1 {
t . Errorf ( "Incorrect number of entries, got: %d" , len ( feed . Entries ) )
}
if len ( feed . Entries [ 0 ] . Enclosures ) != 6 {
t . Fatalf ( "Incorrect number of enclosures, got: %d" , len ( feed . Entries [ 0 ] . Enclosures ) )
}
expectedResults := [ ] struct {
url string
mimeType string
size int64
} {
{ "https://example.org/image.jpg" , "image/*" , 0 } ,
{ "https://example.org/file3.torrent" , "application/x-bittorrent" , 670053113 } ,
{ "https://example.org/file1.torrent" , "application/x-bittorrent" , 0 } ,
{ "https://example.org/file2.torrent" , "application/x-bittorrent" , 0 } ,
{ "https://example.org/file4.torrent" , "application/x-bittorrent" , 0 } ,
{ "https://example.org/file5.torrent" , "application/x-bittorrent" , 42 } ,
}
for index , enclosure := range feed . Entries [ 0 ] . Enclosures {
if expectedResults [ index ] . url != enclosure . URL {
t . Errorf ( ` Unexpected enclosure URL, got %q instead of %q ` , enclosure . URL , expectedResults [ index ] . url )
}
if expectedResults [ index ] . mimeType != enclosure . MimeType {
t . Errorf ( ` Unexpected enclosure type, got %q instead of %q ` , enclosure . MimeType , expectedResults [ index ] . mimeType )
}
if expectedResults [ index ] . size != enclosure . Size {
t . Errorf ( ` Unexpected enclosure size, got %d instead of %d ` , enclosure . Size , expectedResults [ index ] . size )
}
}
}
func TestParseEntryWithMediaContent ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : media = "http://search.yahoo.com/mrss/" >
< channel >
< title > My Example Feed < / title >
< link > http : //example.org</link>
< item >
< title > Example Item < / title >
< link > http : //www.example.org/entries/1</link>
< media : thumbnail url = "https://example.org/thumbnail.jpg" / >
< media : content url = "https://example.org/media1.jpg" medium = "image" >
< media : title type = "html" > Some Title for Media 1 < / media : title >
< / media : content >
< media : content url = "https://example.org/media2.jpg" medium = "image" / >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-11-29 06:21:00 +01:00
if err != nil {
t . Fatal ( err )
}
if len ( feed . Entries ) != 1 {
t . Errorf ( "Incorrect number of entries, got: %d" , len ( feed . Entries ) )
}
if len ( feed . Entries [ 0 ] . Enclosures ) != 3 {
t . Fatalf ( "Incorrect number of enclosures, got: %d" , len ( feed . Entries [ 0 ] . Enclosures ) )
}
expectedResults := [ ] struct {
url string
mimeType string
size int64
} {
{ "https://example.org/thumbnail.jpg" , "image/*" , 0 } ,
{ "https://example.org/media1.jpg" , "image/*" , 0 } ,
{ "https://example.org/media2.jpg" , "image/*" , 0 } ,
}
for index , enclosure := range feed . Entries [ 0 ] . Enclosures {
if expectedResults [ index ] . url != enclosure . URL {
t . Errorf ( ` Unexpected enclosure URL, got %q instead of %q ` , enclosure . URL , expectedResults [ index ] . url )
}
if expectedResults [ index ] . mimeType != enclosure . MimeType {
t . Errorf ( ` Unexpected enclosure type, got %q instead of %q ` , enclosure . MimeType , expectedResults [ index ] . mimeType )
}
if expectedResults [ index ] . size != enclosure . Size {
t . Errorf ( ` Unexpected enclosure size, got %d instead of %d ` , enclosure . Size , expectedResults [ index ] . size )
}
}
}
2019-11-29 08:47:53 +01:00
func TestParseEntryWithMediaPeerLink ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" xmlns : media = "http://search.yahoo.com/mrss/" >
< channel >
< title > My Example Feed < / title >
< link > http : //example.org</link>
< item >
< title > Example Item < / title >
< link > http : //www.example.org/entries/1</link>
< media : peerLink type = "application/x-bittorrent" href = "http://www.example.org/file.torrent" / >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-11-29 08:47:53 +01:00
if err != nil {
t . Fatal ( err )
}
if len ( feed . Entries ) != 1 {
t . Errorf ( "Incorrect number of entries, got: %d" , len ( feed . Entries ) )
}
2019-12-23 22:29:53 +01:00
2019-11-29 08:47:53 +01:00
if len ( feed . Entries [ 0 ] . Enclosures ) != 1 {
t . Fatalf ( "Incorrect number of enclosures, got: %d" , len ( feed . Entries [ 0 ] . Enclosures ) )
}
expectedResults := [ ] struct {
url string
mimeType string
size int64
} {
{ "http://www.example.org/file.torrent" , "application/x-bittorrent" , 0 } ,
}
for index , enclosure := range feed . Entries [ 0 ] . Enclosures {
if expectedResults [ index ] . url != enclosure . URL {
t . Errorf ( ` Unexpected enclosure URL, got %q instead of %q ` , enclosure . URL , expectedResults [ index ] . url )
}
if expectedResults [ index ] . mimeType != enclosure . MimeType {
t . Errorf ( ` Unexpected enclosure type, got %q instead of %q ` , enclosure . MimeType , expectedResults [ index ] . mimeType )
}
if expectedResults [ index ] . size != enclosure . Size {
t . Errorf ( ` Unexpected enclosure size, got %d instead of %d ` , enclosure . Size , expectedResults [ index ] . size )
}
}
}
2019-12-23 22:29:53 +01:00
func TestEntryDescriptionFromItunesSummary ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "UTF-8" ? >
< rss version = "2.0" xmlns : itunes = "http://www.itunes.com/dtds/podcast-1.0.dtd" >
< channel >
< title > Podcast Example < / title >
< link > http : //www.example.com/index.html</link>
< item >
< title > Podcast Episode < / title >
< guid > http : //example.com/episode.m4a</guid>
< pubDate > Tue , 0 8 Mar 2016 12 : 00 : 00 GMT < / pubDate >
< itunes : subtitle > Episode Subtitle < / itunes : subtitle >
< itunes : summary > Episode Summary < / itunes : summary >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
if len ( feed . Entries ) != 1 {
t . Errorf ( "Incorrect number of entries, got: %d" , len ( feed . Entries ) )
}
expected := "Episode Summary"
result := feed . Entries [ 0 ] . Content
if expected != result {
t . Errorf ( ` Unexpected podcast content, got %q instead of %q ` , result , expected )
}
}
func TestEntryDescriptionFromItunesSubtitle ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "UTF-8" ? >
< rss version = "2.0" xmlns : itunes = "http://www.itunes.com/dtds/podcast-1.0.dtd" >
< channel >
< title > Podcast Example < / title >
< link > http : //www.example.com/index.html</link>
< item >
< title > Podcast Episode < / title >
< guid > http : //example.com/episode.m4a</guid>
< pubDate > Tue , 0 8 Mar 2016 12 : 00 : 00 GMT < / pubDate >
< itunes : subtitle > Episode Subtitle < / itunes : subtitle >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
if len ( feed . Entries ) != 1 {
t . Errorf ( "Incorrect number of entries, got: %d" , len ( feed . Entries ) )
}
expected := "Episode Subtitle"
result := feed . Entries [ 0 ] . Content
if expected != result {
t . Errorf ( ` Unexpected podcast content, got %q instead of %q ` , result , expected )
}
}
func TestEntryDescriptionFromGooglePlayDescription ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "UTF-8" ? >
< rss version = "2.0"
xmlns : googleplay = "http://www.google.com/schemas/play-podcasts/1.0"
xmlns : itunes = "http://www.itunes.com/dtds/podcast-1.0.dtd" >
< channel >
< title > Podcast Example < / title >
< link > http : //www.example.com/index.html</link>
< item >
< title > Podcast Episode < / title >
< guid > http : //example.com/episode.m4a</guid>
< pubDate > Tue , 0 8 Mar 2016 12 : 00 : 00 GMT < / pubDate >
< itunes : subtitle > Episode Subtitle < / itunes : subtitle >
< googleplay : description > Episode Description < / googleplay : description >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2019-12-23 22:29:53 +01:00
if err != nil {
t . Fatal ( err )
}
if len ( feed . Entries ) != 1 {
t . Errorf ( "Incorrect number of entries, got: %d" , len ( feed . Entries ) )
}
expected := "Episode Description"
result := feed . Entries [ 0 ] . Content
if expected != result {
t . Errorf ( ` Unexpected podcast content, got %q instead of %q ` , result , expected )
}
}
2023-02-25 05:52:45 +01:00
func TestParseEntryWithCategoryAndInnerHTML ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss xmlns : atom = "http://www.w3.org/2005/Atom" version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< atom : link href = "https://example.org/rss" type = "application/rss+xml" rel = "self" > < / atom : link >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< category > Category 1 < / category >
< category > Category 2 < / category >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2023-02-25 05:52:45 +01:00
if err != nil {
t . Fatal ( err )
}
if len ( feed . Entries [ 0 ] . Tags ) != 2 {
t . Errorf ( "Incorrect number of tags, got: %d" , len ( feed . Entries [ 0 ] . Tags ) )
}
expected := "Category 2"
result := feed . Entries [ 0 ] . Tags [ 1 ]
if result != expected {
t . Errorf ( "Incorrect entry category, got %q instead of %q" , result , expected )
}
}
func TestParseEntryWithCategoryAndCDATA ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss xmlns : atom = "http://www.w3.org/2005/Atom" version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< atom : link href = "https://example.org/rss" type = "application/rss+xml" rel = "self" > < / atom : link >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< author >
by < ! [ CDATA [ Foo Bar ] ] >
< / author >
< category > Sample Category < / category >
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2023-02-25 05:52:45 +01:00
if err != nil {
t . Fatal ( err )
}
if len ( feed . Entries [ 0 ] . Tags ) != 1 {
t . Errorf ( "Incorrect number of tags, got: %d" , len ( feed . Entries [ 0 ] . Tags ) )
}
expected := "Sample Category"
result := feed . Entries [ 0 ] . Tags [ 0 ]
if result != expected {
t . Errorf ( "Incorrect entry category, got %q instead of %q" , result , expected )
}
}
2023-10-21 04:39:32 +02:00
func TestParseFeedWithTTLField ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< ttl > 60 < / ttl >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2023-10-21 04:39:32 +02:00
if err != nil {
t . Fatal ( err )
}
if feed . TTL != 60 {
t . Errorf ( "Incorrect TTL, got: %d" , feed . TTL )
}
}
func TestParseFeedWithIncorrectTTLValue ( t * testing . T ) {
data := ` < ? xml version = "1.0" encoding = "utf-8" ? >
< rss version = "2.0" >
< channel >
< title > Example < / title >
< link > https : //example.org/</link>
< ttl > invalid < / ttl >
< item >
< title > Test < / title >
< link > https : //example.org/item</link>
< / item >
< / channel >
< / rss > `
2024-03-06 14:57:21 +01:00
feed , err := Parse ( "https://example.org/" , bytes . NewReader ( [ ] byte ( data ) ) )
2023-10-21 04:39:32 +02:00
if err != nil {
t . Fatal ( err )
}
if feed . TTL != 0 {
t . Errorf ( "Incorrect TTL, got: %d" , feed . TTL )
}
}