internal/httpd/ownerpage_test.go

e9566eed86ebcd185c4b85f63d667b5e671fe787
gitbay/internal/httpd/ownerpage_test.go history · blame · raw

141 lines · 4408 bytes

  1package httpd
  2
  3import (
  4	"html/template"
  5	"strings"
  6	"testing"
  7
  8	"gitbay.org/gitbay/internal/control"
  9	"gitbay.org/gitbay/internal/store"
 10	"gitbay.org/gitbay/internal/web"
 11)
 12
 13func TestProfileTabFromPath(t *testing.T) {
 14	for path, want := range map[string]string{
 15		"/cmc":            "repos",
 16		"/cmc/-/about":    "about",
 17		"/cmc/-/activity": "activity",
 18		"/cmc/-/people":   "people",
 19		"/krz":            "repos",
 20		"/cmc/-/snippets": "repos",
 21	} {
 22		if got := profileTab(path); got != want {
 23			t.Errorf("profileTab(%q) = %q, want %q", path, got, want)
 24		}
 25	}
 26}
 27
 28// The About text and the year of squares sat above the repository list
 29// and pushed it below the fold (#242). Repositories are the bare
 30// /{owner} now and the rest are tabs beside them.
 31func TestOwnerPageLeadsWithRepositories(t *testing.T) {
 32	out := renderOwner(t, "repos", ownerFixture())
 33	if !strings.Contains(out, "reminiscecleberg.com") {
 34		t.Errorf("the repository list is not on the default tab:\n%s", out)
 35	}
 36	for _, unwanted := range []string{"actgraph", "Christian Cleberg"} {
 37		if strings.Contains(out, unwanted) {
 38			t.Errorf("the default tab still carries %q:\n%s", unwanted, out)
 39		}
 40	}
 41	for _, want := range []string{
 42		`aria-current="page" href="/cmc"`,
 43		`href="/cmc/-/about"`,
 44		`href="/cmc/-/activity"`,
 45	} {
 46		if !strings.Contains(out, want) {
 47			t.Errorf("tab bar missing %q:\n%s", want, out)
 48		}
 49	}
 50	// Nobody administers this profile, so it offers no people tab.
 51	if strings.Contains(out, "/-/people") {
 52		t.Errorf("a profile nobody admins offers a people tab:\n%s", out)
 53	}
 54}
 55
 56func TestOwnerPageTabsCarryOneSectionEach(t *testing.T) {
 57	if out := renderOwner(t, "about", ownerFixture()); !strings.Contains(out, "Christian Cleberg") ||
 58		strings.Contains(out, "actgraph") || strings.Contains(out, "reminiscecleberg.com") {
 59		t.Errorf("about tab is not the About file alone:\n%s", out)
 60	}
 61	if out := renderOwner(t, "activity", ownerFixture()); !strings.Contains(out, "actgraph") ||
 62		strings.Contains(out, "reminiscecleberg.com") {
 63		t.Errorf("activity tab is not the graph alone:\n%s", out)
 64	}
 65	// A profile with no About file does not offer the tab.
 66	d := ownerFixture()
 67	d.AboutHTML = ""
 68	if out := renderOwner(t, "repos", d); strings.Contains(out, "/-/about") {
 69		t.Errorf("a profile with no About file offers the tab:\n%s", out)
 70	}
 71}
 72
 73func TestOwnerPagePeopleTabHoldsTheAdminPanel(t *testing.T) {
 74	d := ownerFixture()
 75	d.Kind = "org"
 76	d.CanAdmin = true
 77	d.Members = []control.ProfileMember{{Name: "cmc", Role: "admin"}}
 78
 79	repos := renderOwner(t, "repos", d)
 80	if !strings.Contains(repos, `href="/cmc/-/people"`) {
 81		t.Errorf("an admin gets no people tab:\n%s", repos)
 82	}
 83	if strings.Contains(repos, "Create a team") {
 84		t.Errorf("the admin forms still sit under the repository list:\n%s", repos)
 85	}
 86	people := renderOwner(t, "people", d)
 87	for _, want := range []string{"Create a team", "member-add", "org-rename"} {
 88		if !strings.Contains(people, want) {
 89			t.Errorf("people tab missing %q:\n%s", want, people)
 90		}
 91	}
 92}
 93
 94type ownerFixtureData struct {
 95	Kind      string
 96	AboutHTML template.HTML
 97	CanAdmin  bool
 98	Members   []control.ProfileMember
 99}
100
101func ownerFixture() ownerFixtureData {
102	return ownerFixtureData{
103		Kind:      "user",
104		AboutHTML: template.HTML("<p><strong>Christian Cleberg</strong></p>"),
105	}
106}
107
108func renderOwner(t *testing.T, tab string, d ownerFixtureData) string {
109	t.Helper()
110	var sb strings.Builder
111	err := web.Render(&sb, "owner.html", struct {
112		basePage
113		Owner         string
114		Kind          string
115		Tab           string
116		Profile       store.Profile
117		AboutHTML     template.HTML
118		Repos         []profileRepoRow
119		Members       []control.ProfileMember
120		Orgs          []control.ProfileMember
121		Activity      []activityWeek
122		ActivityTotal int
123		Teams         []teamView
124		CanAdmin      bool
125		Self          bool
126		Snippets      int
127		Notice        string
128		Feed          string
129	}{
130		basePage{Site: "gitbay"}, "cmc", d.Kind, tab,
131		store.Profile{Description: "Org-Mode · Self-Hosting · Privacy"}, d.AboutHTML,
132		[]profileRepoRow{{control.ProfileRepo{Path: "cmc/reminiscecleberg.com", Description: "Personal placeholder site."}}},
133		d.Members, nil,
134		[]activityWeek{{Month: "Sep", Days: []activityDay{{Date: "2026-09-20", Count: 3, Level: 2}}}}, 6088,
135		nil, d.CanAdmin, false, 0, "", "/cmc/activity.atom",
136	})
137	if err != nil {
138		t.Fatalf("render: %v", err)
139	}
140	return sb.String()
141}