internal/httpd/atom_test.go
72 lines · 2672 bytes
2 symbols in this file
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}