Files
reddit-reader/internal/monitor/monitor_test.go

113 lines
2.8 KiB
Go

package monitor_test
import (
"context"
"sync"
"testing"
"time"
"somegit.dev/vikingowl/reddit-reader/internal/domain"
"somegit.dev/vikingowl/reddit-reader/internal/monitor"
"somegit.dev/vikingowl/reddit-reader/internal/store"
)
type mockFetcher struct {
posts []domain.Post
}
func (m *mockFetcher) FetchPosts(_ context.Context, _, _ string, _ int) ([]domain.Post, error) {
return m.posts, nil
}
type mockSummarizer struct {
mu sync.Mutex
calls int
}
func (m *mockSummarizer) Score(_ context.Context, _ domain.Post, _ domain.Interests) (float64, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.calls++
return 0.8, nil
}
func (m *mockSummarizer) Summarize(_ context.Context, _ domain.Post) (string, error) {
return "- bullet 1\n- bullet 2\n- bullet 3\n- bullet 4\n- bullet 5", nil
}
func TestMonitorPollCycle(t *testing.T) {
st, err := store.Open(":memory:")
if err != nil {
t.Fatal(err)
}
defer st.Close()
st.AddSubreddit(domain.Subreddit{Name: "golang", PollSort: "new"})
st.AddFilter(domain.Filter{Subreddit: "golang", Pattern: "go"})
fetcher := &mockFetcher{
posts: []domain.Post{
{ID: "t3_new1", Subreddit: "golang", Title: "Go tips", CreatedUTC: time.Now()},
{ID: "t3_new2", Subreddit: "golang", Title: "Rust tips", CreatedUTC: time.Now()},
},
}
summarizer := &mockSummarizer{}
m := monitor.New(st, fetcher, summarizer, monitor.Config{
RelevanceThreshold: 0.6,
MaxPostsPerPoll: 25,
Interests: domain.Interests{Description: "Go programming"},
})
newPosts, err := m.PollOnce(context.Background())
if err != nil {
t.Fatalf("PollOnce: %v", err)
}
// "Go tips" matches keyword "go", "Rust tips" does not
if len(newPosts) != 1 {
t.Fatalf("newPosts = %d, want 1", len(newPosts))
}
if newPosts[0].ID != "t3_new1" {
t.Errorf("post ID = %q, want t3_new1", newPosts[0].ID)
}
if newPosts[0].Summary == nil {
t.Error("expected summary to be set")
}
exists, _ := st.PostExists("t3_new1")
if !exists {
t.Error("post should be in store")
}
}
func TestMonitorDedup(t *testing.T) {
st, err := store.Open(":memory:")
if err != nil {
t.Fatal(err)
}
defer st.Close()
st.AddSubreddit(domain.Subreddit{Name: "golang", PollSort: "new"})
st.InsertPost(domain.Post{ID: "t3_existing", Subreddit: "golang", Title: "Old", CreatedUTC: time.Now()})
fetcher := &mockFetcher{
posts: []domain.Post{
{ID: "t3_existing", Subreddit: "golang", Title: "Old", CreatedUTC: time.Now()},
},
}
m := monitor.New(st, fetcher, &mockSummarizer{}, monitor.Config{
RelevanceThreshold: 0.6, MaxPostsPerPoll: 25,
Interests: domain.Interests{Description: "Go"},
})
newPosts, err := m.PollOnce(context.Background())
if err != nil {
t.Fatalf("PollOnce: %v", err)
}
if len(newPosts) != 0 {
t.Errorf("expected 0 new posts (dedup), got %d", len(newPosts))
}
}