entry_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. // Copyright 2018 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. //go:build integration
  5. // +build integration
  6. package tests
  7. import (
  8. "testing"
  9. miniflux "miniflux.app/client"
  10. )
  11. func TestGetAllFeedEntries(t *testing.T) {
  12. client := createClient(t)
  13. feed, _ := createFeed(t, client)
  14. allResults, err := client.FeedEntries(feed.ID, nil)
  15. if err != nil {
  16. t.Fatal(err)
  17. }
  18. if allResults.Total == 0 {
  19. t.Fatal(`Invalid number of entries`)
  20. }
  21. if allResults.Entries[0].Title == "" {
  22. t.Fatal(`Invalid entry title`)
  23. }
  24. filteredResults, err := client.FeedEntries(feed.ID, &miniflux.Filter{Limit: 1, Offset: 5})
  25. if err != nil {
  26. t.Fatal(err)
  27. }
  28. if allResults.Total != filteredResults.Total {
  29. t.Fatal(`Total should always contains the total number of items regardless of filters`)
  30. }
  31. if allResults.Entries[0].ID == filteredResults.Entries[0].ID {
  32. t.Fatal(`Filtered entries should be different than previous results`)
  33. }
  34. filteredResultsByEntryID, err := client.FeedEntries(feed.ID, &miniflux.Filter{BeforeEntryID: allResults.Entries[0].ID})
  35. if err != nil {
  36. t.Fatal(err)
  37. }
  38. if filteredResultsByEntryID.Entries[0].ID == allResults.Entries[0].ID {
  39. t.Fatal(`The first entry should be filtered out`)
  40. }
  41. }
  42. func TestGetAllCategoryEntries(t *testing.T) {
  43. client := createClient(t)
  44. _, category := createFeed(t, client)
  45. allResults, err := client.CategoryEntries(category.ID, nil)
  46. if err != nil {
  47. t.Fatal(err)
  48. }
  49. if allResults.Total == 0 {
  50. t.Fatal(`Invalid number of entries`)
  51. }
  52. if allResults.Entries[0].Title == "" {
  53. t.Fatal(`Invalid entry title`)
  54. }
  55. filteredResults, err := client.CategoryEntries(category.ID, &miniflux.Filter{Limit: 1, Offset: 5})
  56. if err != nil {
  57. t.Fatal(err)
  58. }
  59. if allResults.Total != filteredResults.Total {
  60. t.Fatal(`Total should always contains the total number of items regardless of filters`)
  61. }
  62. if allResults.Entries[0].ID == filteredResults.Entries[0].ID {
  63. t.Fatal(`Filtered entries should be different than previous results`)
  64. }
  65. filteredResultsByEntryID, err := client.CategoryEntries(category.ID, &miniflux.Filter{BeforeEntryID: allResults.Entries[0].ID})
  66. if err != nil {
  67. t.Fatal(err)
  68. }
  69. if filteredResultsByEntryID.Entries[0].ID == allResults.Entries[0].ID {
  70. t.Fatal(`The first entry should be filtered out`)
  71. }
  72. }
  73. func TestGetAllEntries(t *testing.T) {
  74. client := createClient(t)
  75. createFeed(t, client)
  76. resultWithoutSorting, err := client.Entries(nil)
  77. if err != nil {
  78. t.Fatal(err)
  79. }
  80. if resultWithoutSorting.Total == 0 {
  81. t.Fatal(`Invalid number of entries`)
  82. }
  83. resultWithStatusFilter, err := client.Entries(&miniflux.Filter{Status: miniflux.EntryStatusRead})
  84. if err != nil {
  85. t.Fatal(err)
  86. }
  87. if resultWithStatusFilter.Total != 0 {
  88. t.Fatal(`We should have 0 read entries`)
  89. }
  90. resultWithDifferentSorting, err := client.Entries(&miniflux.Filter{Order: "published_at", Direction: "desc"})
  91. if err != nil {
  92. t.Fatal(err)
  93. }
  94. if resultWithDifferentSorting.Entries[0].Title == resultWithoutSorting.Entries[0].Title {
  95. t.Fatalf(`The items should be sorted differently "%v" vs "%v"`, resultWithDifferentSorting.Entries[0].Title, resultWithoutSorting.Entries[0].Title)
  96. }
  97. resultWithStarredEntries, err := client.Entries(&miniflux.Filter{Starred: miniflux.FilterOnlyStarred})
  98. if err != nil {
  99. t.Fatal(err)
  100. }
  101. if resultWithStarredEntries.Total != 0 {
  102. t.Fatalf(`We are not supposed to have starred entries yet`)
  103. }
  104. }
  105. func TestFilterEntriesByCategory(t *testing.T) {
  106. client := createClient(t)
  107. category, err := client.CreateCategory("Test Filter by Category")
  108. if err != nil {
  109. t.Fatal(err)
  110. }
  111. feedID, err := client.CreateFeed(&miniflux.FeedCreationRequest{
  112. FeedURL: testFeedURL,
  113. CategoryID: category.ID,
  114. })
  115. if err != nil {
  116. t.Fatal(err)
  117. }
  118. if feedID == 0 {
  119. t.Fatalf(`Invalid feed ID, got %q`, feedID)
  120. }
  121. results, err := client.Entries(&miniflux.Filter{CategoryID: category.ID})
  122. if err != nil {
  123. t.Fatal(err)
  124. }
  125. if results.Total == 0 {
  126. t.Fatalf(`We should have more than one entry`)
  127. }
  128. if results.Entries[0].Feed.Category == nil {
  129. t.Fatalf(`The entry feed category should not be nil`)
  130. }
  131. if results.Entries[0].Feed.Category.ID != category.ID {
  132. t.Errorf(`Entries should be filtered by category_id=%d`, category.ID)
  133. }
  134. }
  135. func TestFilterEntriesByFeed(t *testing.T) {
  136. client := createClient(t)
  137. category, err := client.CreateCategory("Test Filter by Feed")
  138. if err != nil {
  139. t.Fatal(err)
  140. }
  141. feedID, err := client.CreateFeed(&miniflux.FeedCreationRequest{
  142. FeedURL: testFeedURL,
  143. CategoryID: category.ID,
  144. })
  145. if err != nil {
  146. t.Fatal(err)
  147. }
  148. if feedID == 0 {
  149. t.Fatalf(`Invalid feed ID, got %q`, feedID)
  150. }
  151. results, err := client.Entries(&miniflux.Filter{FeedID: feedID})
  152. if err != nil {
  153. t.Fatal(err)
  154. }
  155. if results.Total == 0 {
  156. t.Fatalf(`We should have more than one entry`)
  157. }
  158. if results.Entries[0].Feed.Category == nil {
  159. t.Fatalf(`The entry feed category should not be nil`)
  160. }
  161. if results.Entries[0].Feed.Category.ID != category.ID {
  162. t.Errorf(`Entries should be filtered by category_id=%d`, category.ID)
  163. }
  164. }
  165. func TestFilterEntriesByStatuses(t *testing.T) {
  166. client := createClient(t)
  167. category, err := client.CreateCategory("Test Filter by statuses")
  168. if err != nil {
  169. t.Fatal(err)
  170. }
  171. feedID, err := client.CreateFeed(&miniflux.FeedCreationRequest{
  172. FeedURL: testFeedURL,
  173. CategoryID: category.ID,
  174. })
  175. if err != nil {
  176. t.Fatal(err)
  177. }
  178. if feedID == 0 {
  179. t.Fatalf(`Invalid feed ID, got %q`, feedID)
  180. }
  181. results, err := client.Entries(&miniflux.Filter{FeedID: feedID})
  182. if err != nil {
  183. t.Fatal(err)
  184. }
  185. if err := client.UpdateEntries([]int64{results.Entries[0].ID}, miniflux.EntryStatusRead); err != nil {
  186. t.Fatal(err)
  187. }
  188. if err := client.UpdateEntries([]int64{results.Entries[1].ID}, miniflux.EntryStatusRemoved); err != nil {
  189. t.Fatal(err)
  190. }
  191. results, err = client.Entries(&miniflux.Filter{Statuses: []string{miniflux.EntryStatusRead, miniflux.EntryStatusRemoved}})
  192. if err != nil {
  193. t.Fatal(err)
  194. }
  195. if results.Total != 2 {
  196. t.Fatalf(`We should have 2 entries`)
  197. }
  198. if results.Entries[0].Status != "read" {
  199. t.Errorf(`The first entry has the wrong status: %s`, results.Entries[0].Status)
  200. }
  201. if results.Entries[1].Status != "removed" {
  202. t.Errorf(`The 2nd entry has the wrong status: %s`, results.Entries[1].Status)
  203. }
  204. }
  205. func TestSearchEntries(t *testing.T) {
  206. client := createClient(t)
  207. categories, err := client.Categories()
  208. if err != nil {
  209. t.Fatal(err)
  210. }
  211. feedID, err := client.CreateFeed(&miniflux.FeedCreationRequest{
  212. FeedURL: testFeedURL,
  213. CategoryID: categories[0].ID,
  214. })
  215. if err != nil {
  216. t.Fatal(err)
  217. }
  218. if feedID == 0 {
  219. t.Fatalf(`Invalid feed ID, got %q`, feedID)
  220. }
  221. results, err := client.Entries(&miniflux.Filter{Search: "2.0.8"})
  222. if err != nil {
  223. t.Fatal(err)
  224. }
  225. if results.Total != 1 {
  226. t.Fatalf(`We should have only one entry instead of %d`, results.Total)
  227. }
  228. }
  229. func TestInvalidFilters(t *testing.T) {
  230. client := createClient(t)
  231. createFeed(t, client)
  232. _, err := client.Entries(&miniflux.Filter{Status: "invalid"})
  233. if err == nil {
  234. t.Fatal(`Using invalid status should raise an error`)
  235. }
  236. _, err = client.Entries(&miniflux.Filter{Direction: "invalid"})
  237. if err == nil {
  238. t.Fatal(`Using invalid direction should raise an error`)
  239. }
  240. _, err = client.Entries(&miniflux.Filter{Order: "invalid"})
  241. if err == nil {
  242. t.Fatal(`Using invalid order should raise an error`)
  243. }
  244. }
  245. func TestGetFeedEntry(t *testing.T) {
  246. client := createClient(t)
  247. createFeed(t, client)
  248. result, err := client.Entries(&miniflux.Filter{Limit: 1})
  249. if err != nil {
  250. t.Fatal(err)
  251. }
  252. // Test get entry by entry id and feed id
  253. entry, err := client.FeedEntry(result.Entries[0].FeedID, result.Entries[0].ID)
  254. if err != nil {
  255. t.Fatal(err)
  256. }
  257. if entry.ID != result.Entries[0].ID {
  258. t.Fatal("Wrong entry returned")
  259. }
  260. }
  261. func TestGetCategoryEntry(t *testing.T) {
  262. client := createClient(t)
  263. _, category := createFeed(t, client)
  264. result, err := client.Entries(&miniflux.Filter{Limit: 1})
  265. if err != nil {
  266. t.Fatal(err)
  267. }
  268. // Test get entry by entry id and category id
  269. entry, err := client.CategoryEntry(category.ID, result.Entries[0].ID)
  270. if err != nil {
  271. t.Fatal(err)
  272. }
  273. if entry.ID != result.Entries[0].ID {
  274. t.Fatal("Wrong entry returned")
  275. }
  276. }
  277. func TestGetEntry(t *testing.T) {
  278. client := createClient(t)
  279. createFeed(t, client)
  280. result, err := client.Entries(&miniflux.Filter{Limit: 1})
  281. if err != nil {
  282. t.Fatal(err)
  283. }
  284. // Test get entry by entry id only
  285. entry, err := client.Entry(result.Entries[0].ID)
  286. if err != nil {
  287. t.Fatal(err)
  288. }
  289. if entry.ID != result.Entries[0].ID {
  290. t.Fatal("Wrong entry returned")
  291. }
  292. }
  293. func TestUpdateStatus(t *testing.T) {
  294. client := createClient(t)
  295. createFeed(t, client)
  296. result, err := client.Entries(&miniflux.Filter{Limit: 1})
  297. if err != nil {
  298. t.Fatal(err)
  299. }
  300. err = client.UpdateEntries([]int64{result.Entries[0].ID}, miniflux.EntryStatusRead)
  301. if err != nil {
  302. t.Fatal(err)
  303. }
  304. entry, err := client.Entry(result.Entries[0].ID)
  305. if err != nil {
  306. t.Fatal(err)
  307. }
  308. if entry.Status != miniflux.EntryStatusRead {
  309. t.Fatal("The entry status should be updated")
  310. }
  311. err = client.UpdateEntries([]int64{result.Entries[0].ID}, "invalid")
  312. if err == nil {
  313. t.Fatal(`Invalid entry status should not be accepted`)
  314. }
  315. err = client.UpdateEntries([]int64{}, miniflux.EntryStatusRead)
  316. if err == nil {
  317. t.Fatal(`An empty list of entry should not be accepted`)
  318. }
  319. }
  320. func TestToggleBookmark(t *testing.T) {
  321. client := createClient(t)
  322. createFeed(t, client)
  323. result, err := client.Entries(&miniflux.Filter{Limit: 1})
  324. if err != nil {
  325. t.Fatal(err)
  326. }
  327. if result.Entries[0].Starred {
  328. t.Fatal("The entry should not be starred")
  329. }
  330. err = client.ToggleBookmark(result.Entries[0].ID)
  331. if err != nil {
  332. t.Fatal(err)
  333. }
  334. entry, err := client.Entry(result.Entries[0].ID)
  335. if err != nil {
  336. t.Fatal(err)
  337. }
  338. if !entry.Starred {
  339. t.Fatal("The entry should be starred")
  340. }
  341. }
  342. func TestHistoryOrder(t *testing.T) {
  343. client := createClient(t)
  344. createFeed(t, client)
  345. result, err := client.Entries(&miniflux.Filter{Limit: 3})
  346. if err != nil {
  347. t.Fatal(err)
  348. }
  349. selectedEntry := result.Entries[2].ID
  350. err = client.UpdateEntries([]int64{selectedEntry}, miniflux.EntryStatusRead)
  351. if err != nil {
  352. t.Fatal(err)
  353. }
  354. history, err := client.Entries(&miniflux.Filter{Order: "changed_at", Direction: "desc", Limit: 1})
  355. if err != nil {
  356. t.Fatal(err)
  357. }
  358. if history.Entries[0].ID != selectedEntry {
  359. t.Fatal("The entry that we just read should be at the top of the history")
  360. }
  361. }