156 lines
5.3 KiB
Go
156 lines
5.3 KiB
Go
package rss
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestDiscover_HTMLLinkTags(t *testing.T) {
|
|
html := `<html>
|
|
<head>
|
|
<title>My Site</title>
|
|
<link rel="alternate" type="application/rss+xml" href="https://example.com/feed.xml" title="RSS Feed"/>
|
|
<link rel="alternate" type="application/atom+xml" href="https://example.com/atom.xml" title="Atom Feed"/>
|
|
<link rel="stylesheet" href="/style.css"/>
|
|
</head>
|
|
<body>Hello</body>
|
|
</html>`
|
|
|
|
links := Discover(html)
|
|
require.Len(t, links, 2)
|
|
|
|
assert.Equal(t, "https://example.com/feed.xml", links[0].URL)
|
|
assert.Equal(t, "RSS Feed", links[0].Title)
|
|
assert.Equal(t, "rss", links[0].Type)
|
|
|
|
assert.Equal(t, "https://example.com/atom.xml", links[1].URL)
|
|
assert.Equal(t, "Atom Feed", links[1].Title)
|
|
assert.Equal(t, "atom", links[1].Type)
|
|
}
|
|
|
|
func TestDiscover_HTMLLinkTags_AttributeOrder(t *testing.T) {
|
|
// Attributes in different order, single quotes
|
|
html := `<link href='https://blog.example.com/rss' title='Blog' type='application/rss+xml' rel='alternate'>`
|
|
links := Discover(html)
|
|
require.Len(t, links, 1)
|
|
assert.Equal(t, "https://blog.example.com/rss", links[0].URL)
|
|
assert.Equal(t, "Blog", links[0].Title)
|
|
assert.Equal(t, "rss", links[0].Type)
|
|
}
|
|
|
|
func TestDiscover_MarkdownLinks(t *testing.T) {
|
|
md := `# My Bookmarks
|
|
|
|
Here are some feeds:
|
|
- [Tech News](https://news.example.com/rss.xml)
|
|
- [Go Blog](https://go.dev/blog/feed.atom)
|
|
- [Not a feed](https://example.com/about)
|
|
`
|
|
links := Discover(md)
|
|
require.Len(t, links, 2)
|
|
|
|
assert.Equal(t, "https://news.example.com/rss.xml", links[0].URL)
|
|
assert.Equal(t, "Tech News", links[0].Title)
|
|
assert.Equal(t, "rss", links[0].Type)
|
|
|
|
assert.Equal(t, "https://go.dev/blog/feed.atom", links[1].URL)
|
|
assert.Equal(t, "Go Blog", links[1].Title)
|
|
assert.Equal(t, "atom", links[1].Type)
|
|
}
|
|
|
|
func TestDiscover_BareURLs(t *testing.T) {
|
|
text := `Check out these feeds:
|
|
https://example.com/feed.xml
|
|
https://blog.example.com/rss
|
|
https://news.example.com/atom.xml
|
|
https://example.com/about (not a feed)
|
|
`
|
|
links := Discover(text)
|
|
require.Len(t, links, 3)
|
|
|
|
assert.Equal(t, "https://example.com/feed.xml", links[0].URL)
|
|
assert.Equal(t, "https://blog.example.com/rss", links[1].URL)
|
|
assert.Equal(t, "https://news.example.com/atom.xml", links[2].URL)
|
|
}
|
|
|
|
func TestDiscover_BareURLs_QueryParams(t *testing.T) {
|
|
text := `Feed URL: https://example.com/api?feed=rss&lang=en`
|
|
links := Discover(text)
|
|
require.Len(t, links, 1)
|
|
assert.Equal(t, "https://example.com/api?feed=rss&lang=en", links[0].URL)
|
|
}
|
|
|
|
func TestDiscover_Deduplication(t *testing.T) {
|
|
// Same URL appears in HTML link tag and as bare URL
|
|
text := `<link rel="alternate" type="application/rss+xml" href="https://example.com/feed.xml" title="Feed"/>
|
|
Check out: https://example.com/feed.xml`
|
|
|
|
links := Discover(text)
|
|
require.Len(t, links, 1) // deduplicated
|
|
assert.Equal(t, "https://example.com/feed.xml", links[0].URL)
|
|
assert.Equal(t, "Feed", links[0].Title) // from HTML tag (higher priority)
|
|
}
|
|
|
|
func TestDiscover_PartialHTML(t *testing.T) {
|
|
// Incomplete HTML fragment
|
|
fragment := `<div>Some content</div>
|
|
<link rel="alternate" type="application/rss+xml" href="https://example.com/feed" title="My Feed">
|
|
<p>More broken`
|
|
|
|
links := Discover(fragment)
|
|
require.Len(t, links, 1)
|
|
assert.Equal(t, "https://example.com/feed", links[0].URL)
|
|
}
|
|
|
|
func TestDiscover_Empty(t *testing.T) {
|
|
assert.Nil(t, Discover(""))
|
|
assert.Nil(t, Discover(" "))
|
|
}
|
|
|
|
func TestDiscover_NoFeeds(t *testing.T) {
|
|
links := Discover("Hello world! Visit https://example.com for more info.")
|
|
assert.Empty(t, links)
|
|
}
|
|
|
|
func TestDiscover_MixedContent(t *testing.T) {
|
|
// HTML link + Markdown link + bare URL, all different
|
|
mixed := `<link rel="alternate" type="application/atom+xml" href="https://a.com/atom.xml" title="A"/>
|
|
Some text with [B Feed](https://b.com/feed.xml) and also
|
|
https://c.com/rss.xml is available.`
|
|
|
|
links := Discover(mixed)
|
|
require.Len(t, links, 3)
|
|
assert.Equal(t, "https://a.com/atom.xml", links[0].URL)
|
|
assert.Equal(t, "atom", links[0].Type)
|
|
assert.Equal(t, "https://b.com/feed.xml", links[1].URL)
|
|
assert.Equal(t, "https://c.com/rss.xml", links[2].URL)
|
|
assert.Equal(t, "rss", links[2].Type)
|
|
}
|
|
|
|
func TestDiscover_TrailingPunctuation(t *testing.T) {
|
|
text := `Check https://example.com/feed.xml.`
|
|
links := Discover(text)
|
|
require.Len(t, links, 1)
|
|
assert.Equal(t, "https://example.com/feed.xml", links[0].URL)
|
|
}
|
|
|
|
func TestLooksLikeFeedURL(t *testing.T) {
|
|
assert.True(t, looksLikeFeedURL("https://example.com/feed.xml"))
|
|
assert.True(t, looksLikeFeedURL("https://example.com/rss"))
|
|
assert.True(t, looksLikeFeedURL("https://example.com/atom.xml"))
|
|
assert.True(t, looksLikeFeedURL("https://example.com/index.xml"))
|
|
assert.True(t, looksLikeFeedURL("https://example.com/feed/"))
|
|
assert.True(t, looksLikeFeedURL("https://example.com/api?feed=rss"))
|
|
assert.True(t, looksLikeFeedURL("https://example.com/blog.rss"))
|
|
assert.False(t, looksLikeFeedURL("https://example.com/about"))
|
|
assert.False(t, looksLikeFeedURL("https://example.com/image.png"))
|
|
}
|
|
|
|
func TestGuessTypeFromURL(t *testing.T) {
|
|
assert.Equal(t, "rss", guessTypeFromURL("https://example.com/rss.xml"))
|
|
assert.Equal(t, "atom", guessTypeFromURL("https://example.com/atom.xml"))
|
|
assert.Equal(t, "", guessTypeFromURL("https://example.com/feed.xml"))
|
|
assert.Equal(t, "", guessTypeFromURL("https://example.com/index.xml"))
|
|
}
|