internal/httpd/ownerpage_test.go
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}