Files
rsspipe/internal/db/db_test.go
T

176 lines
4.6 KiB
Go

package db
import (
"os"
"path/filepath"
"testing"
"time"
"git.pengzhan.dev/haopengzhan/rsspipe/internal/models"
)
func TestDatabaseOperations(t *testing.T) {
tempDir, err := os.MkdirTemp("", "rsspipe-test-*")
if err != nil {
t.Fatalf("failed to create temp dir: %v", err)
}
defer func() {
_ = os.RemoveAll(tempDir)
}()
dbPath := filepath.Join(tempDir, "test.db")
database, err := InitDB(dbPath)
if err != nil {
t.Fatalf("InitDB failed: %v", err)
}
defer func() {
_ = database.Close()
}()
// 1. Test User
u, err := database.CreateUser("admin", "$2a$10$dummyhashvalue")
if err != nil {
t.Fatalf("CreateUser failed: %v", err)
}
if u.Username != "admin" {
t.Errorf("expected username admin, got %s", u.Username)
}
// 2. Test Category
cat, err := database.CreateCategory("Tech News", nil)
if err != nil {
t.Fatalf("CreateCategory failed: %v", err)
}
// 3. Test Feed
feed, err := database.CreateFeed("Hacker News", "https://news.ycombinator.com/rss", "https://news.ycombinator.com", "", &cat.ID)
if err != nil {
t.Fatalf("CreateFeed failed: %v", err)
}
// 4. Test Upsert Feed Entries
entries := []models.FeedEntry{
{
GUID: "item-1",
URL: "https://example.com/1",
Title: "Post One",
Author: "Alice",
Content: "<p>Content 1</p>",
PublishedAt: time.Now().Add(-1 * time.Hour),
},
{
GUID: "item-2",
URL: "https://example.com/2",
Title: "Post Two",
Author: "Bob",
Content: "<p>Content 2</p>",
PublishedAt: time.Now(),
},
}
inserted, err := database.UpsertFeedEntries(feed.ID, entries)
if err != nil {
t.Fatalf("UpsertFeedEntries failed: %v", err)
}
if len(inserted) != 2 {
t.Fatalf("expected 2 inserted entries, got %d", len(inserted))
}
// 5. List entries
list, total, err := database.ListEntries(EntryFilter{View: "inbox"})
if err != nil {
t.Fatalf("ListEntries failed: %v", err)
}
if total != 2 || len(list) != 2 {
t.Errorf("expected 2 entries, got total %d, len %d", total, len(list))
}
// 6. Update Read & Star
firstID := list[0].ID
if err := database.UpdateEntryRead(firstID, true); err != nil {
t.Fatalf("UpdateEntryRead failed: %v", err)
}
if err := database.UpdateEntryStarred(firstID, true); err != nil {
t.Fatalf("UpdateEntryStarred failed: %v", err)
}
// 7. Test Variant CRUD
variant := models.EntryVariant{
EntryID: firstID,
VariantKey: "readability_full_text",
ContentType: "html",
TextValue: "<div>Clean full text content</div>",
Metadata: map[string]interface{}{
"scraped_at": time.Now().UTC().Format(time.RFC3339),
"length": 100,
},
}
if err := database.SetVariant(variant); err != nil {
t.Fatalf("SetVariant failed: %v", err)
}
fetchedVariant, err := database.GetVariant(firstID, "readability_full_text")
if err != nil {
t.Fatalf("GetVariant failed: %v", err)
}
if fetchedVariant.TextValue != "<div>Clean full text content</div>" {
t.Fatalf("expected variant text, got %s", fetchedVariant.TextValue)
}
// Test GetEntry with variants
entryWithVariants, err := database.GetEntry(firstID)
if err != nil {
t.Fatalf("GetEntry failed: %v", err)
}
if len(entryWithVariants.Variants) != 1 {
t.Fatalf("expected 1 variant in GetEntry, got %d", len(entryWithVariants.Variants))
}
// 8. Test Rules CRUD
rule, err := database.CreateRule(
"Auto Scrape Rule",
"on_post_created",
"all",
[]models.RuleCondition{
{Field: "feed_id", Operator: "eq", Value: feed.ID},
},
[]models.RuleAction{
{Type: "readability_scrape"},
},
)
if err != nil {
t.Fatalf("CreateRule failed: %v", err)
}
if rule.Name != "Auto Scrape Rule" {
t.Errorf("expected rule name Auto Scrape Rule, got %s", rule.Name)
}
activeRules, err := database.GetActiveRules("on_post_created")
if err != nil {
t.Fatalf("GetActiveRules failed: %v", err)
}
if len(activeRules) != 1 {
t.Fatalf("expected 1 active rule, got %d", len(activeRules))
}
// 9. Verify Stats
stats, err := database.GetStats()
if err != nil {
t.Fatalf("GetStats failed: %v", err)
}
if stats.TotalFeeds != 1 || stats.TotalUnread != 1 || stats.TotalStarred != 1 || stats.TotalRules != 1 {
t.Errorf("unexpected stats: %+v", stats)
}
// 8. Test UpdateUserPassword
newHash := "$2a$10$updatedhashvalue"
if err := database.UpdateUserPassword(u.ID, newHash); err != nil {
t.Fatalf("UpdateUserPassword failed: %v", err)
}
updatedUser, err := database.GetUserByUsername("admin")
if err != nil {
t.Fatalf("GetUserByUsername failed: %v", err)
}
if updatedUser.PasswordHash != newHash {
t.Errorf("expected hash %s, got %s", newHash, updatedUser.PasswordHash)
}
}