Skip to content

Commit

Permalink
Fetch new feed items func
Browse files Browse the repository at this point in the history
  • Loading branch information
brendanv committed Aug 28, 2024
1 parent 7b2bbe6 commit 8d27fc2
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
37 changes: 37 additions & 0 deletions backend/lynx/feeds/feeds.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package feeds

import (
"fmt"
"net/http"
"time"

Expand Down Expand Up @@ -90,6 +91,42 @@ func SaveNewFeedItems(app core.App, feed *gofeed.Feed, user string, feedId strin
return nil
}

func FetchNewFeedItems(app core.App, feedId string) error {
feed, err := app.Dao().FindRecordById("feeds", feedId)
if err != nil {
return fmt.Errorf("failed to find feed: %w", err)
}

feedURL := feed.GetString("feed_url")
etag := feed.GetString("etag")
lastModified := feed.GetString("modified")
lastModifiedTime, _ := time.Parse(http.TimeFormat, lastModified)

feedResult, err := LoadFeedFromURL(feedURL, etag, lastModifiedTime)
if err != nil {
return fmt.Errorf("failed to load feed from URL: %w", err)
}

if feedResult.Feed == nil {
return nil
}

feed.Set("etag", feedResult.ETag)
feed.Set("modified", feedResult.LastModified)
previousFetchTime := feed.GetDateTime("last_fetched_at").Time()
lastFetchedAt := time.Now().UTC()
feed.Set("last_fetched_at", lastFetchedAt.Format(time.RFC3339))
if err := app.Dao().SaveRecord(feed); err != nil {
return fmt.Errorf("failed to update feed record: %w", err)
}

if err := SaveNewFeedItems(app, feedResult.Feed, feed.GetString("user"), feedId, previousFetchTime); err != nil {
return fmt.Errorf("failed to save new feed items: %w", err)
}

return nil
}

// SaveNewFeed extracts the URL from the request, loads the
// feed, and saves it to the database along with the first
// set of feed items.
Expand Down
92 changes: 92 additions & 0 deletions backend/lynx/feeds/feeds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ import (
"net/http/httptest"
"testing"
"time"

"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/models"
"github.com/pocketbase/pocketbase/tests"
)

const testDataDir = "../../test_pb_data"

func TestLoadFeedFromURL(t *testing.T) {
// Set up a mock server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -77,3 +83,89 @@ func TestLoadFeedFromURL(t *testing.T) {
})
}
}

func TestFetchNewFeedItems(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("If-None-Match") == "initial-etag" {
w.WriteHeader(http.StatusNotModified)
return
}
w.Header().Set("ETag", "new-etag")
w.Header().Set("Last-Modified", "Wed, 21 Oct 2015 07:28:00 GMT")
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Test Feed</title>
<description>A test feed</description>
<item>
<title>New Item</title>
<link>http://example.com/new-item</link>
<guid>http://example.com/new-item</guid>
<pubDate>Wed, 21 Oct 2015 07:28:00 GMT</pubDate>
<description>This is a new item</description>
</item>
</channel>
</rss>`))
}))
defer server.Close()

testApp, err := tests.NewTestApp(testDataDir)
if err != nil {
t.Fatal(err)
}
defer testApp.Cleanup()

feedCollection, err := testApp.Dao().FindCollectionByNameOrId("feeds")
if err != nil {
t.Fatal(err)
}
feed := models.NewRecord(feedCollection)
feed.Set("feed_url", server.URL)
feed.Set("etag", "non-matching-etag")
feed.Set("modified", "Tue, 20 Oct 2015 07:28:00 GMT")
feed.Set("last_fetched_at", "Tue, 20 Oct 2015 07:28:00 GMT")
feed.Set("user", "test-user")
if err := testApp.Dao().SaveRecord(feed); err != nil {
t.Fatal(err)
}

err = FetchNewFeedItems(testApp, feed.Id)
if err != nil {
t.Fatalf("FetchNewFeedItems failed: %v", err)
}

updatedFeed, err := testApp.Dao().FindRecordById("feeds", feed.Id)
if err != nil {
t.Fatal(err)
}
if updatedFeed.GetString("etag") != "new-etag" {
t.Errorf("Expected etag to be 'new-etag', got '%s'", updatedFeed.GetString("etag"))
}
if updatedFeed.GetString("modified") != "Wed, 21 Oct 2015 07:28:00 GMT" {
t.Errorf("Expected modified to be 'Wed, 21 Oct 2015 07:28:00 GMT', got '%s'", updatedFeed.GetString("modified"))
}

feedItems, err := testApp.Dao().FindRecordsByFilter("feed_items", "feed = {:feed}", "created", 100, 0, dbx.Params{"feed": feed.Id})
if err != nil {
t.Fatal(err)
}
if len(feedItems) != 1 {
t.Errorf("Expected 1 feed item, got %d", len(feedItems))
}
if feedItems[0].GetString("title") != "New Item" {
t.Errorf("Expected feed item title to be 'New Item', got '%s'", feedItems[0].GetString("title"))
}

// Test no changes when feed hasn't been modified
err = FetchNewFeedItems(testApp, feed.Id)
if err != nil {
t.Fatalf("Second FetchNewFeedItems failed: %v", err)
}
newFeedItems, err := testApp.Dao().FindRecordsByFilter("feed_items", "feed = {:feed}", "created", 100, 0, dbx.Params{"feed": feed.Id})
if err != nil {
t.Fatal(err)
}
if len(newFeedItems) != 1 {
t.Errorf("Expected 1 feed item after second fetch, got %d", len(feedItems))
}
}

0 comments on commit 8d27fc2

Please sign in to comment.