package feed
import (
"encoding/xml"
"os"
"path/filepath"
"strings"
"testing"
"time"
"mercemay.top/src/tilstream/internal/render"
)
func samplePosts() []render.Post {
return []render.Post{
{
Slug: "interfaces-vs-structs",
Title: "Go interfaces vs structs",
Date: time.Date(2024, 12, 28, 10, 0, 0, 0, time.UTC),
Tags: []string{"go", "design"},
Body: "Short body that mentions empty interfaces once.",
},
{
Slug: "fsnotify-linux-quirks",
Title: "fsnotify on Linux",
Date: time.Date(2024, 12, 2, 9, 30, 0, 0, time.UTC),
Tags: []string{"go", "linux"},
Body: "fsnotify can fire twice on editor saves; debounce it.",
},
}
}
func TestRSSWrite_ItemCountAndGUID(t *testing.T) {
dir := t.TempDir()
dest := filepath.Join(dir, "rss.xml")
if err := Write(dest, samplePosts(), "https://til.example.com/"); err != nil {
t.Fatalf("Write returned error: %v", err)
}
data, err := os.ReadFile(dest)
if err != nil {
t.Fatal(err)
}
var parsed rss
if err := xml.Unmarshal(data, &parsed); err != nil {
t.Fatalf("unmarshal: %v", err)
}
if got, want := len(parsed.Channel.Items), 2; got != want {
t.Fatalf("item count: got %d want %d", got, want)
}
// Commit d9c4f01: GUID should include first category.
if !strings.HasSuffix(parsed.Channel.Items[0].GUID.Value, ":go") {
t.Errorf("guid missing category suffix: %q", parsed.Channel.Items[0].GUID.Value)
}
}
func TestAtomWrite_HasSelfLink(t *testing.T) {
dir := t.TempDir()
dest := filepath.Join(dir, "atom.xml")
err := WriteAtom(dest, samplePosts(), "https://til.example.com", "merce", "me@example.com")
if err != nil {
t.Fatal(err)
}
body, _ := os.ReadFile(dest)
if !strings.Contains(string(body), `rel="self"`) {
t.Fatal("atom feed missing self link")
}
if !strings.Contains(string(body), `<name>merce</name>`) {
t.Fatal("atom feed missing author name")
}
}
func TestAtomWrite_EmptyPosts(t *testing.T) {
dir := t.TempDir()
dest := filepath.Join(dir, "atom.xml")
if err := WriteAtom(dest, nil, "https://til.example.com", "merce", ""); err != nil {
t.Fatalf("empty feed should not error: %v", err)
}
info, err := os.Stat(dest)
if err != nil {
t.Fatal(err)
}
if info.Size() == 0 {
t.Fatal("expected a non-empty file even with zero entries")
}
}
func TestNewestMtime_FallsBackToNow(t *testing.T) {
got := newestMtime(nil)
if got.IsZero() {
t.Fatal("zero fallback mtime")
}
if time.Since(got) > time.Minute {
t.Fatalf("fallback mtime not recent enough: %v", got)
}
}
func TestWriteXML_CreatesParentExists(t *testing.T) {
dir := t.TempDir()
dest := filepath.Join(dir, "sub", "missing.xml")
if err := writeXML(dest, atomFeed{Title: "x"}); err == nil {
t.Fatal("expected error when parent directory does not exist")
}
}