package storage import "testing" // insertClassified is a tiny helper to seed a visible story and return its id. func insertClassified(t *testing.T, guid, headline, content string) int64 { t.Helper() s := &Story{ GUID: guid, Headline: headline, Content: content, ArticleURL: "https://example.com/" + guid, Source: "Example Wire", Channel: "tech", Classified: true, SeenAt: nowUnix(), } if err := InsertStory(s); err != nil { t.Fatalf("insert %s: %v", guid, err) } var id int64 if err := Get().QueryRow(`SELECT id FROM stories WHERE guid = ?`, guid).Scan(&id); err != nil { t.Fatalf("lookup %s: %v", guid, err) } return id } func TestStoryViews_TotalsAndTrending(t *testing.T) { setupTestDB(t) a := insertClassified(t, "s-a", "Story A", "some body text here") b := insertClassified(t, "s-b", "Story B", "") c := insertClassified(t, "s-c", "Story C", "another body") // A read three times, C twice, B never. RecordStoryView(a) RecordStoryView(a) RecordStoryView(a) RecordStoryView(c) RecordStoryView(c) totals := StoryViewTotals([]int64{a, b, c}) if totals[a] != 3 { t.Errorf("totals[a] = %d, want 3", totals[a]) } if _, ok := totals[b]; ok { t.Errorf("totals[b] present = %v, want absent (zero views)", totals[b]) } if totals[c] != 2 { t.Errorf("totals[c] = %d, want 2", totals[c]) } // Trending over the last week: A (3) before C (2); B is absent (no views). trend, err := TrendingStories(10, unixDay()-6) if err != nil { t.Fatalf("trending: %v", err) } if len(trend) != 2 { t.Fatalf("trending len = %d, want 2 (B has no views)", len(trend)) } if trend[0].ID != a || trend[1].ID != c { t.Errorf("trending order = [%d, %d], want [%d, %d]", trend[0].ID, trend[1].ID, a, c) } // A window that starts after today excludes everything. future, err := TrendingStories(10, unixDay()+1) if err != nil { t.Fatalf("trending future: %v", err) } if len(future) != 0 { t.Errorf("trending (future window) len = %d, want 0", len(future)) } } func TestStoryContentLengths(t *testing.T) { setupTestDB(t) a := insertClassified(t, "c-a", "Has body", "hello world body") b := insertClassified(t, "c-b", "No body", "") lengths := StoryContentLengths([]int64{a, b}) if lengths[a] != len("hello world body") { t.Errorf("lengths[a] = %d, want %d", lengths[a], len("hello world body")) } if _, ok := lengths[b]; ok { t.Errorf("lengths[b] present, want absent (empty content)") } if got := StoryContentLengths(nil); len(got) != 0 { t.Errorf("StoryContentLengths(nil) = %v, want empty", got) } }