package web
import (
"encoding/xml"
"net/http"
"strings"
"testing"
)
// A visitor who cannot sign in can follow a repository (7a608b5b): the
// timeline is an Atom feed whose items link where the timeline rows
// do, it keeps the page's filters, and the pages announce it.
func TestAVisitorCanFollowARepositoryTimeline(t *testing.T) {
srv := activityServer(t)
resp, err := http.Get(srv.URL + "/r/alpha/timeline.atom")
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 || !strings.HasPrefix(resp.Header.Get("Content-Type"), "application/atom+xml") {
t.Fatalf("FAIL: status %d, type %q", resp.StatusCode, resp.Header.Get("Content-Type"))
}
var f atomFeed
if err := xml.NewDecoder(resp.Body).Decode(&f); err != nil {
t.Fatalf("FAIL: not Atom: %v", err)
}
if len(f.Entries) != 4 || f.Updated != "2026-08-04T16:00:00Z" {
t.Fatalf("FAIL: %d entries updated %q, want 4 and the newest check-in's time", len(f.Entries), f.Updated)
}
ids := map[string]bool{}
for _, e := range f.Entries {
if !strings.HasPrefix(e.Link.Href, srv.URL+"/r/alpha/checkin/") || e.Author.Name == "" || ids[e.ID] {
t.Fatalf("FAIL: entry %+v: link must be an absolute check-in URL, author named, id unique", e)
}
ids[e.ID] = true
}
_, all := getPage(t, srv, "/r/alpha/timeline.atom")
_, feat := getPage(t, srv, "/r/alpha/timeline.atom?branch=feat")
if strings.Count(feat, "<entry>") >= strings.Count(all, "<entry>") || !strings.Contains(feat, "timeline.atom?branch=feat") {
t.Fatal("FAIL: a branch feed should narrow the entries and name itself with the filter")
}
_, page := getPage(t, srv, "/r/alpha/timeline?branch=feat")
if !strings.Contains(page, `rel="alternate" type="application/atom+xml"`) {
t.Fatal("FAIL: the page head does not announce the feed")
}
if !strings.Contains(page, `data-hook="timeline-feed"`) || !strings.Contains(page, `/r/alpha/timeline.atom?branch=feat`) {
t.Fatal("FAIL: the timeline's feed link does not carry the branch filter")
}
t.Logf("ok: 4 entries, newest %s; branch feed %d of %d; page announces and links it",
f.Updated, strings.Count(feat, "<entry>"), strings.Count(all, "<entry>"))
}