feat: implement rule engine, worker pool, event bus, and readability scraping with enhanced logging and content sanitization.

This commit is contained in:
2026-08-25 00:31:32 -07:00
parent 5ea176d5ad
commit d440728ca5
29 changed files with 2788 additions and 204 deletions
+61 -4
View File
@@ -72,8 +72,8 @@ func TestDatabaseOperations(t *testing.T) {
if err != nil {
t.Fatalf("UpsertFeedEntries failed: %v", err)
}
if inserted != 2 {
t.Fatalf("expected 2 inserted entries, got %d", inserted)
if len(inserted) != 2 {
t.Fatalf("expected 2 inserted entries, got %d", len(inserted))
}
// 5. List entries
@@ -94,12 +94,69 @@ func TestDatabaseOperations(t *testing.T) {
t.Fatalf("UpdateEntryStarred failed: %v", err)
}
// 7. Verify Stats
// 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.TotalCategories != 1 {
if stats.TotalFeeds != 1 || stats.TotalUnread != 1 || stats.TotalStarred != 1 || stats.TotalRules != 1 {
t.Errorf("unexpected stats: %+v", stats)
}