internal/httpd/atom_test.go

8e6fc2062ca26f7a848bdf6ad6345fd345351231
gitbay/internal/httpd/atom_test.go history · blame · raw

72 lines · 2672 bytes

 1package httpd
 2
 3import (
 4	"encoding/xml"
 5	"net/http/httptest"
 6	"strings"
 7	"testing"
 8
 9	"gitbay.org/gitbay/internal/config"
10	"gitbay.org/gitbay/internal/store"
11)
12
13func TestWriteAtom(t *testing.T) {
14	s := &Server{cfg: config.Config{Server: config.Server{SiteURL: "https://forge.test/"}}}
15	rec := httptest.NewRecorder()
16	s.writeAtom(rec, "/alice/app/releases.atom", "alice/app releases", []atomEntry{
17		{ID: "https://forge.test/alice/app/releases#v1", Title: "v1: <first>", Updated: "2026-09-07T10:00:00Z",
18			Author: &atomAuthor{Name: "alice"}, Link: atomLink{Rel: "alternate", Href: "https://forge.test/alice/app/releases#v1"},
19			Content: &atomContent{Type: "text", Text: "notes & more"}},
20	})
21	if ct := rec.Header().Get("Content-Type"); !strings.HasPrefix(ct, "application/atom+xml") {
22		t.Fatalf("content type %q", ct)
23	}
24	var got atomFeed
25	if err := xml.Unmarshal(rec.Body.Bytes(), &got); err != nil {
26		t.Fatalf("not XML: %v\n%s", err, rec.Body.String())
27	}
28	if got.ID != "https://forge.test/alice/app/releases.atom" || got.Updated != "2026-09-07T10:00:00Z" || len(got.Entries) != 1 {
29		t.Fatalf("feed: %+v", got)
30	}
31	if e := got.Entries[0]; e.Title != "v1: <first>" || e.Content.Text != "notes & more" || e.Author.Name != "alice" {
32		t.Fatalf("entry: %+v", e)
33	}
34	alt := ""
35	for _, l := range got.Links {
36		if l.Rel == "alternate" {
37			alt = l.Href
38		}
39	}
40	if alt != "https://forge.test/alice/app/releases" {
41		t.Fatalf("alternate link %q", alt)
42	}
43
44	// No entries: still a feed, updated now.
45	rec = httptest.NewRecorder()
46	s.writeAtom(rec, "/alice/activity.atom", "alice activity", nil)
47	if err := xml.Unmarshal(rec.Body.Bytes(), &got); err != nil || got.Updated == "" {
48		t.Fatalf("empty feed: %v %+v", err, got)
49	}
50}
51
52func TestEventTitle(t *testing.T) {
53	cases := []struct {
54		ev          store.FeedEvent
55		title, link string
56	}{
57		{store.FeedEvent{RepoPath: "alice/app", Actor: "bob", Kind: "issue.created", Data: `{"number":3}`},
58			"bob: issue.created alice/app#3", "/alice/app/issues/3"},
59		{store.FeedEvent{RepoPath: "alice/app", Actor: "bob", Kind: "mr.merged", Data: `{"number":7}`},
60			"bob: mr.merged alice/app!7", "/alice/app/mrs/7"},
61		{store.FeedEvent{RepoPath: "alice/app", Actor: "alice", Kind: "release.created", Data: `{"tag":"v1.0"}`},
62			"alice: release.created alice/app v1.0", "/alice/app/releases#v1.0"},
63		{store.FeedEvent{RepoPath: "alice/app", Kind: "repo.imported", Data: `{"from":"x"}`},
64			"repo.imported in alice/app", "/alice/app"},
65	}
66	for _, tc := range cases {
67		title, link := eventTitle(tc.ev)
68		if title != tc.title || link != tc.link {
69			t.Errorf("%s: got %q %q, want %q %q", tc.ev.Kind, title, link, tc.title, tc.link)
70		}
71	}
72}