finder_test.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package subscription
  4. import (
  5. "strings"
  6. "testing"
  7. )
  8. func TestFindYoutubeChannelFeed(t *testing.T) {
  9. scenarios := map[string]string{
  10. "https://www.youtube.com/channel/UC-Qj80avWItNRjkZ41rzHyw": "https://www.youtube.com/feeds/videos.xml?channel_id=UC-Qj80avWItNRjkZ41rzHyw",
  11. }
  12. for websiteURL, expectedFeedURL := range scenarios {
  13. subscriptions, localizedError := NewSubscriptionFinder(nil).FindSubscriptionsFromYouTubeChannelPage(websiteURL)
  14. if localizedError != nil {
  15. t.Fatalf(`Parsing a correctly formatted YouTube channel page should not return any error: %v`, localizedError)
  16. }
  17. if len(subscriptions) != 1 {
  18. t.Fatal(`Incorrect number of subscriptions returned`)
  19. }
  20. if subscriptions[0].URL != expectedFeedURL {
  21. t.Errorf(`Unexpected Feed, got %s, instead of %s`, subscriptions[0].URL, expectedFeedURL)
  22. }
  23. }
  24. }
  25. func TestParseWebPageWithRssFeed(t *testing.T) {
  26. htmlPage := `
  27. <!doctype html>
  28. <html>
  29. <head>
  30. <link href="http://example.org/rss" rel="alternate" type="application/rss+xml" title="Some Title">
  31. </head>
  32. <body>
  33. </body>
  34. </html>`
  35. subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
  36. if err != nil {
  37. t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
  38. }
  39. if len(subscriptions) != 1 {
  40. t.Fatal(`Incorrect number of subscriptions returned`)
  41. }
  42. if subscriptions[0].Title != "Some Title" {
  43. t.Errorf(`Incorrect subscription title: %q`, subscriptions[0].Title)
  44. }
  45. if subscriptions[0].URL != "http://example.org/rss" {
  46. t.Errorf(`Incorrect subscription URL: %q`, subscriptions[0].URL)
  47. }
  48. if subscriptions[0].Type != "rss" {
  49. t.Errorf(`Incorrect subscription type: %q`, subscriptions[0].Type)
  50. }
  51. }
  52. func TestParseWebPageWithAtomFeed(t *testing.T) {
  53. htmlPage := `
  54. <!doctype html>
  55. <html>
  56. <head>
  57. <link href="http://example.org/atom.xml" rel="alternate" type="application/atom+xml" title="Some Title">
  58. </head>
  59. <body>
  60. </body>
  61. </html>`
  62. subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
  63. if err != nil {
  64. t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
  65. }
  66. if len(subscriptions) != 1 {
  67. t.Fatal(`Incorrect number of subscriptions returned`)
  68. }
  69. if subscriptions[0].Title != "Some Title" {
  70. t.Errorf(`Incorrect subscription title: %q`, subscriptions[0].Title)
  71. }
  72. if subscriptions[0].URL != "http://example.org/atom.xml" {
  73. t.Errorf(`Incorrect subscription URL: %q`, subscriptions[0].URL)
  74. }
  75. if subscriptions[0].Type != "atom" {
  76. t.Errorf(`Incorrect subscription type: %q`, subscriptions[0].Type)
  77. }
  78. }
  79. func TestParseWebPageWithJSONFeed(t *testing.T) {
  80. htmlPage := `
  81. <!doctype html>
  82. <html>
  83. <head>
  84. <link href="http://example.org/feed.json" rel="alternate" type="application/feed+json" title="Some Title">
  85. </head>
  86. <body>
  87. </body>
  88. </html>`
  89. subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
  90. if err != nil {
  91. t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
  92. }
  93. if len(subscriptions) != 1 {
  94. t.Fatal(`Incorrect number of subscriptions returned`)
  95. }
  96. if subscriptions[0].Title != "Some Title" {
  97. t.Errorf(`Incorrect subscription title: %q`, subscriptions[0].Title)
  98. }
  99. if subscriptions[0].URL != "http://example.org/feed.json" {
  100. t.Errorf(`Incorrect subscription URL: %q`, subscriptions[0].URL)
  101. }
  102. if subscriptions[0].Type != "json" {
  103. t.Errorf(`Incorrect subscription type: %q`, subscriptions[0].Type)
  104. }
  105. }
  106. func TestParseWebPageWithOldJSONFeedMimeType(t *testing.T) {
  107. htmlPage := `
  108. <!doctype html>
  109. <html>
  110. <head>
  111. <link href="http://example.org/feed.json" rel="alternate" type="application/json" title="Some Title">
  112. </head>
  113. <body>
  114. </body>
  115. </html>`
  116. subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
  117. if err != nil {
  118. t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
  119. }
  120. if len(subscriptions) != 1 {
  121. t.Fatal(`Incorrect number of subscriptions returned`)
  122. }
  123. if subscriptions[0].Title != "Some Title" {
  124. t.Errorf(`Incorrect subscription title: %q`, subscriptions[0].Title)
  125. }
  126. if subscriptions[0].URL != "http://example.org/feed.json" {
  127. t.Errorf(`Incorrect subscription URL: %q`, subscriptions[0].URL)
  128. }
  129. if subscriptions[0].Type != "json" {
  130. t.Errorf(`Incorrect subscription type: %q`, subscriptions[0].Type)
  131. }
  132. }
  133. func TestParseWebPageWithRelativeFeedURL(t *testing.T) {
  134. htmlPage := `
  135. <!doctype html>
  136. <html>
  137. <head>
  138. <link href="/feed.json" rel="alternate" type="application/feed+json" title="Some Title">
  139. </head>
  140. <body>
  141. </body>
  142. </html>`
  143. subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
  144. if err != nil {
  145. t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
  146. }
  147. if len(subscriptions) != 1 {
  148. t.Fatal(`Incorrect number of subscriptions returned`)
  149. }
  150. if subscriptions[0].Title != "Some Title" {
  151. t.Errorf(`Incorrect subscription title: %q`, subscriptions[0].Title)
  152. }
  153. if subscriptions[0].URL != "http://example.org/feed.json" {
  154. t.Errorf(`Incorrect subscription URL: %q`, subscriptions[0].URL)
  155. }
  156. if subscriptions[0].Type != "json" {
  157. t.Errorf(`Incorrect subscription type: %q`, subscriptions[0].Type)
  158. }
  159. }
  160. func TestParseWebPageWithEmptyTitle(t *testing.T) {
  161. htmlPage := `
  162. <!doctype html>
  163. <html>
  164. <head>
  165. <link href="/feed.json" rel="alternate" type="application/feed+json">
  166. </head>
  167. <body>
  168. </body>
  169. </html>`
  170. subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
  171. if err != nil {
  172. t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
  173. }
  174. if len(subscriptions) != 1 {
  175. t.Fatal(`Incorrect number of subscriptions returned`)
  176. }
  177. if subscriptions[0].Title != "http://example.org/feed.json" {
  178. t.Errorf(`Incorrect subscription title: %q`, subscriptions[0].Title)
  179. }
  180. if subscriptions[0].URL != "http://example.org/feed.json" {
  181. t.Errorf(`Incorrect subscription URL: %q`, subscriptions[0].URL)
  182. }
  183. if subscriptions[0].Type != "json" {
  184. t.Errorf(`Incorrect subscription type: %q`, subscriptions[0].Type)
  185. }
  186. }
  187. func TestParseWebPageWithMultipleFeeds(t *testing.T) {
  188. htmlPage := `
  189. <!doctype html>
  190. <html>
  191. <head>
  192. <link href="http://example.org/atom.xml" rel="alternate" type="application/atom+xml" title="Atom Feed">
  193. <link href="http://example.org/feed.json" rel="alternate" type="application/feed+json" title="JSON Feed">
  194. </head>
  195. <body>
  196. </body>
  197. </html>`
  198. subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
  199. if err != nil {
  200. t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
  201. }
  202. if len(subscriptions) != 2 {
  203. t.Fatal(`Incorrect number of subscriptions returned`)
  204. }
  205. }
  206. func TestParseWebPageWithDuplicatedFeeds(t *testing.T) {
  207. htmlPage := `
  208. <!doctype html>
  209. <html>
  210. <head>
  211. <link href="http://example.org/feed.xml" rel="alternate" type="application/rss+xml" title="Feed A">
  212. <link href="http://example.org/feed.xml" rel="alternate" type="application/rss+xml" title="Feed B">
  213. </head>
  214. <body>
  215. </body>
  216. </html>`
  217. subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
  218. if err != nil {
  219. t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
  220. }
  221. if len(subscriptions) != 1 {
  222. t.Fatal(`Incorrect number of subscriptions returned`)
  223. }
  224. if subscriptions[0].Title != "Feed A" {
  225. t.Errorf(`Incorrect subscription title: %q`, subscriptions[0].Title)
  226. }
  227. if subscriptions[0].URL != "http://example.org/feed.xml" {
  228. t.Errorf(`Incorrect subscription URL: %q`, subscriptions[0].URL)
  229. }
  230. if subscriptions[0].Type != "rss" {
  231. t.Errorf(`Incorrect subscription type: %q`, subscriptions[0].Type)
  232. }
  233. }
  234. func TestParseWebPageWithEmptyFeedURL(t *testing.T) {
  235. htmlPage := `
  236. <!doctype html>
  237. <html>
  238. <head>
  239. <link href rel="alternate" type="application/feed+json" title="Some Title">
  240. </head>
  241. <body>
  242. </body>
  243. </html>`
  244. subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
  245. if err != nil {
  246. t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
  247. }
  248. if len(subscriptions) != 0 {
  249. t.Fatal(`Incorrect number of subscriptions returned`)
  250. }
  251. }
  252. func TestParseWebPageWithNoHref(t *testing.T) {
  253. htmlPage := `
  254. <!doctype html>
  255. <html>
  256. <head>
  257. <link rel="alternate" type="application/feed+json" title="Some Title">
  258. </head>
  259. <body>
  260. </body>
  261. </html>`
  262. subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
  263. if err != nil {
  264. t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
  265. }
  266. if len(subscriptions) != 0 {
  267. t.Fatal(`Incorrect number of subscriptions returned`)
  268. }
  269. }