Pete's side of the Adventure news feed. Receives structured game-event
facts from gogobee, templates them in Pete's warm-reporter voice, and
publishes to a new /adventure section + live Matrix posts.
- adventure.go: bearer ingest + fact-guard + 13 event templates;
/adventure/{guid} permalink (story.html); per-event SVG emblems at
/adventure/art/{type}.svg (card image + og:image); NoPush suppresses
the live Matrix post (cold-start backfill).
- adventure_digest.go: daily BULLETIN roundup at DigestHour (UTC);
unposted-in-48h = bulletins; marks them digested; per-day ?digest= URL
avoids canonical dedup.
- config AdventureConfig (enabled/ingest_token/channel/digest_hour);
web.New takes the seam + a priority poster; started in main.
- adventure theme colors; thumbURL passes through local emblem paths;
adventure pages are noindex (player-named; gap #5).
Claude-Session: https://claude.ai/code/session_017mEwUmmS7aQTP2NQXj6rUa
70 lines
1.8 KiB
Go
70 lines
1.8 KiB
Go
package web
|
|
|
|
import (
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"net/http/httptest"
|
|
|
|
"pete/internal/config"
|
|
"pete/internal/storage"
|
|
)
|
|
|
|
// TestIndexTrendingAndBadges seeds a story with captured content and some reader
|
|
// views, then asserts the home page renders the "Popular this week" rail plus the
|
|
// per-card reading-time chip and read-count badge that decorate() fills in.
|
|
func TestIndexTrendingAndBadges(t *testing.T) {
|
|
storage.Close()
|
|
if err := storage.Init(filepath.Join(t.TempDir(), "trending.db")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() { storage.Close() })
|
|
|
|
// ~1200 chars of body → about a 1 min read.
|
|
body := strings.Repeat("word ", 240)
|
|
story := &storage.Story{
|
|
GUID: "trend-e2e",
|
|
Headline: "A Trending Headline",
|
|
Lede: "Lede.",
|
|
Content: body,
|
|
ArticleURL: "https://example.com/trend",
|
|
Source: "Example Wire",
|
|
Channel: "tech",
|
|
Classified: true,
|
|
SeenAt: time.Now().Unix(),
|
|
}
|
|
if err := storage.InsertStory(story); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var id int64
|
|
if err := storage.Get().QueryRow(`SELECT id FROM stories WHERE guid = ?`, story.GUID).Scan(&id); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Two reads so the story trends and the badge shows a count.
|
|
storage.RecordStoryView(id)
|
|
storage.RecordStoryView(id)
|
|
|
|
s, err := New(config.WebConfig{SiteTitle: "Pete", ListenAddr: ":0"}, nil, true, config.AdventureConfig{}, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rw := httptest.NewRecorder()
|
|
s.handleIndex(rw, httptest.NewRequest("GET", "/", nil))
|
|
if rw.Code != 200 {
|
|
t.Fatalf("index status = %d", rw.Code)
|
|
}
|
|
body = rw.Body.String()
|
|
|
|
for _, want := range []string{
|
|
"Popular this week", // trending rail heading
|
|
"min read", // reading-time chip
|
|
`title="2 reads"`, // view-count badge
|
|
} {
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("index HTML missing %q", want)
|
|
}
|
|
}
|
|
}
|