Subscribe and post RSS feeds to Bluesky
rss bluesky
at main 4.5 kB view raw
1package rss 2 3import ( 4 "context" 5 "net/http" 6 "net/http/httptest" 7 "testing" 8 "time" 9) 10 11func TestFetchLatestItems(t *testing.T) { 12 // Create a test RSS feed 13 testFeed := `<?xml version="1.0" encoding="UTF-8"?> 14<rss version="2.0"> 15 <channel> 16 <title>Test Feed</title> 17 <link>https://example.com</link> 18 <description>A test feed</description> 19 <item> 20 <title>Test Item 1</title> 21 <link>https://example.com/item1</link> 22 <description>Description for item 1</description> 23 <guid>item-1</guid> 24 <pubDate>Mon, 02 Jan 2023 15:04:05 GMT</pubDate> 25 </item> 26 <item> 27 <title>Test Item 2</title> 28 <link>https://example.com/item2</link> 29 <description>Description for item 2</description> 30 <guid>item-2</guid> 31 <pubDate>Mon, 02 Jan 2023 16:04:05 GMT</pubDate> 32 </item> 33 <item> 34 <title>Test Item 3</title> 35 <link>https://example.com/item3</link> 36 <description>Description for item 3</description> 37 <guid>item-3</guid> 38 <pubDate>Mon, 02 Jan 2023 17:04:05 GMT</pubDate> 39 </item> 40 </channel> 41</rss>` 42 43 // Create a test server 44 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 45 w.Header().Set("Content-Type", "application/rss+xml") 46 w.WriteHeader(http.StatusOK) 47 w.Write([]byte(testFeed)) 48 })) 49 defer server.Close() 50 51 // Create checker 52 checker := NewChecker() 53 54 // Test fetching all items 55 t.Run("FetchAllItems", func(t *testing.T) { 56 items, err := checker.FetchLatestItems(context.Background(), server.URL) 57 if err != nil { 58 t.Fatalf("Failed to fetch items: %v", err) 59 } 60 61 if len(items) != 3 { 62 t.Errorf("Expected 3 items, got %d", len(items)) 63 } 64 65 // Check first item 66 if items[0].Title != "Test Item 1" { 67 t.Errorf("Expected title 'Test Item 1', got '%s'", items[0].Title) 68 } 69 if items[0].Link != "https://example.com/item1" { 70 t.Errorf("Expected link 'https://example.com/item1', got '%s'", items[0].Link) 71 } 72 if items[0].GUID != "item-1" { 73 t.Errorf("Expected GUID 'item-1', got '%s'", items[0].GUID) 74 } 75 }) 76 77 // Test with context timeout 78 t.Run("ContextTimeout", func(t *testing.T) { 79 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond) 80 defer cancel() 81 82 time.Sleep(2 * time.Millisecond) // Ensure context is expired 83 84 _, err := checker.FetchLatestItems(ctx, server.URL) 85 if err == nil { 86 t.Error("Expected error with expired context, got nil") 87 } 88 }) 89} 90 91func TestFetchLatestItems_InvalidURL(t *testing.T) { 92 checker := NewChecker() 93 94 _, err := checker.FetchLatestItems(context.Background(), "not-a-valid-url") 95 if err == nil { 96 t.Error("Expected error with invalid URL, got nil") 97 } 98} 99 100func TestFetchLatestItems_EmptyFeed(t *testing.T) { 101 emptyFeed := `<?xml version="1.0" encoding="UTF-8"?> 102<rss version="2.0"> 103 <channel> 104 <title>Empty Feed</title> 105 <link>https://example.com</link> 106 <description>A feed with no items</description> 107 </channel> 108</rss>` 109 110 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 111 w.Header().Set("Content-Type", "application/rss+xml") 112 w.WriteHeader(http.StatusOK) 113 w.Write([]byte(emptyFeed)) 114 })) 115 defer server.Close() 116 117 checker := NewChecker() 118 items, err := checker.FetchLatestItems(context.Background(), server.URL) 119 120 if err != nil { 121 t.Fatalf("Expected no error with empty feed, got: %v", err) 122 } 123 124 if len(items) != 0 { 125 t.Errorf("Expected 0 items, got %d", len(items)) 126 } 127} 128 129func TestFeedItem_GUIDFallback(t *testing.T) { 130 // Feed with no GUID, should use link instead 131 feedNoGUID := `<?xml version="1.0" encoding="UTF-8"?> 132<rss version="2.0"> 133 <channel> 134 <title>Test Feed</title> 135 <link>https://example.com</link> 136 <description>Test</description> 137 <item> 138 <title>Item Without GUID</title> 139 <link>https://example.com/item-no-guid</link> 140 <description>Description</description> 141 <pubDate>Mon, 02 Jan 2023 15:04:05 GMT</pubDate> 142 </item> 143 </channel> 144</rss>` 145 146 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 147 w.Header().Set("Content-Type", "application/rss+xml") 148 w.WriteHeader(http.StatusOK) 149 w.Write([]byte(feedNoGUID)) 150 })) 151 defer server.Close() 152 153 checker := NewChecker() 154 items, err := checker.FetchLatestItems(context.Background(), server.URL) 155 156 if err != nil { 157 t.Fatalf("Failed to fetch items: %v", err) 158 } 159 160 if len(items) != 1 { 161 t.Fatalf("Expected 1 item, got %d", len(items)) 162 } 163 164 // GUID should fall back to link 165 if items[0].GUID != "https://example.com/item-no-guid" { 166 t.Errorf("Expected GUID to fallback to link, got '%s'", items[0].GUID) 167 } 168}