e2e/profileabout_test.go

ff759b53942049b2043e132f5482b442a7265b98
gitbay/e2e/profileabout_test.go history · blame · raw

168 lines · 6444 bytes

  1package e2e
  2
  3import (
  4	"strings"
  5	"testing"
  6)
  7
  8// The about text is a file in <owner>/.gitbay, read on every surface with
  9// the reader's own access.
 10func TestProfileAboutFromRepo(t *testing.T) {
 11	t.Parallel()
 12	inst := startInstance(t)
 13	aliceKey := inst.newKey(t, "alice")
 14	inst.admin(t, "admin", "user", "create", "alice",
 15		"--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
 16	bobKey := inst.newKey(t, "bob")
 17	inst.admin(t, "admin", "user", "create", "bob",
 18		"--key", bobKey+".pub", "--email", "bob@example.test", "--verified")
 19
 20	if _, _, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/.gitbay"); code != 0 {
 21		t.Fatal("creating alice/.gitbay failed")
 22	}
 23	if _, _, code := inst.ssh(t, aliceKey, "# alice\n\nhello from a file\n",
 24		"repo", "commit-file", "alice/.gitbay", "profile/README.md",
 25		"--ref", "main", "--file", "-"); code != 0 {
 26		t.Fatal("committing the about failed")
 27	}
 28
 29	out, _, code := inst.ssh(t, bobKey, "", "profile", "show", "alice", "--json")
 30	if code != 0 {
 31		t.Fatalf("profile show: %d", code)
 32	}
 33	if !strings.Contains(out, "hello from a file") {
 34		t.Errorf("about not read from the repository: %s", out)
 35	}
 36	if !strings.Contains(out, `"about_format":"md"`) {
 37		t.Errorf("about_format not md: %s", out)
 38	}
 39	if !strings.Contains(out, `"about_path":"profile/README.md"`) {
 40		t.Errorf("about_path missing: %s", out)
 41	}
 42
 43	_, body := inst.get(t, "/alice")
 44	if !strings.Contains(body, "hello from a file") {
 45		t.Error("web profile does not render the about")
 46	}
 47
 48	// The extension drives the renderer: an .org about renders as org.
 49	if _, _, code := inst.ssh(t, bobKey, "", "repo", "create", "bob/.gitbay"); code != 0 {
 50		t.Fatal("creating bob/.gitbay failed")
 51	}
 52	if _, errOut, code := inst.ssh(t, bobKey, "a /note/ in org\n",
 53		"repo", "commit-file", "bob/.gitbay", "profile/README.org",
 54		"--ref", "main", "--file", "-"); code != 0 {
 55		t.Fatalf("committing bob's org about: %s", errOut)
 56	}
 57	if _, page := inst.get(t, "/bob"); !strings.Contains(page, "<em>note</em>") {
 58		t.Errorf("about did not render as org:\n%s", page)
 59	}
 60}
 61
 62// The extension picks the format, .md wins the resolution order, and a
 63// private .gitbay keeps the about to the people who can read it.
 64func TestProfileAboutFormatAndPrivacy(t *testing.T) {
 65	t.Parallel()
 66	inst := startInstance(t)
 67	aliceKey := inst.newKey(t, "alice")
 68	inst.admin(t, "admin", "user", "create", "alice",
 69		"--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
 70	bobKey := inst.newKey(t, "bob")
 71	inst.admin(t, "admin", "user", "create", "bob",
 72		"--key", bobKey+".pub", "--email", "bob@example.test", "--verified")
 73
 74	inst.ssh(t, aliceKey, "", "repo", "create", "alice/.gitbay", "--private")
 75	if _, _, code := inst.ssh(t, aliceKey, "* heading\n\norg text here\n",
 76		"repo", "commit-file", "alice/.gitbay", "profile/README.org",
 77		"--ref", "main", "--file", "-"); code != 0 {
 78		t.Fatal("committing the org about failed")
 79	}
 80
 81	out, _, _ := inst.ssh(t, aliceKey, "", "profile", "show", "alice", "--json")
 82	if !strings.Contains(out, "org text here") || !strings.Contains(out, `"about_format":"org"`) {
 83		t.Errorf("owner cannot read their own private about: %s", out)
 84	}
 85
 86	out, _, code := inst.ssh(t, bobKey, "", "profile", "show", "alice", "--json")
 87	if code != 0 {
 88		t.Fatalf("profile show for an outsider should succeed: %d", code)
 89	}
 90	if strings.Contains(out, "org text here") {
 91		t.Errorf("private about leaked to an outsider: %s", out)
 92	}
 93
 94	// A .md beside the .org wins: it is first in the resolution order.
 95	if _, _, code := inst.ssh(t, aliceKey, "markdown wins\n",
 96		"repo", "commit-file", "alice/.gitbay", "profile/README.md",
 97		"--ref", "main", "--file", "-"); code != 0 {
 98		t.Fatal("committing the md about failed")
 99	}
100	out, _, _ = inst.ssh(t, aliceKey, "", "profile", "show", "alice", "--json")
101	if !strings.Contains(out, "markdown wins") {
102		t.Errorf(".md did not win resolution: %s", out)
103	}
104}
105
106// A dot-repo is infrastructure: it stays out of explore and off the
107// profile's repository list, and stays in the owner's own inventory.
108func TestDotReposHiddenFromListings(t *testing.T) {
109	t.Parallel()
110	inst := startInstance(t)
111	aliceKey := inst.newKey(t, "alice")
112	inst.admin(t, "admin", "user", "create", "alice",
113		"--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
114	inst.ssh(t, aliceKey, "", "repo", "create", "alice/.gitbay")
115	inst.ssh(t, aliceKey, "", "repo", "create", "alice/app")
116
117	out, _, _ := inst.ssh(t, aliceKey, "", "explore", "--json")
118	if strings.Contains(out, ".gitbay") {
119		t.Errorf("dot-repo listed in explore: %s", out)
120	}
121	if !strings.Contains(out, "alice/app") {
122		t.Errorf("ordinary repo missing from explore: %s", out)
123	}
124
125	out, _, _ = inst.ssh(t, aliceKey, "", "profile", "show", "alice", "--json")
126	if strings.Contains(out, `"path":"alice/.gitbay"`) {
127		t.Errorf("dot-repo listed on the profile: %s", out)
128	}
129	if !strings.Contains(out, `"path":"alice/app"`) {
130		t.Errorf("ordinary repo missing from the profile: %s", out)
131	}
132
133	out, _, _ = inst.ssh(t, aliceKey, "", "repo", "list", "--json")
134	if !strings.Contains(out, "alice/.gitbay") {
135		t.Errorf("dot-repo missing from the owner's own inventory: %s", out)
136	}
137
138	// It is still reachable at its URL.
139	if _, page := inst.get(t, "/alice/.gitbay"); strings.Contains(page, "not found") {
140		t.Error("dot-repo page not reachable")
141	}
142}
143
144// The about is not settable through profile set any more: it is a file.
145func TestProfileSetHasNoAbout(t *testing.T) {
146	t.Parallel()
147	inst := startInstance(t)
148	aliceKey := inst.newKey(t, "alice")
149	inst.admin(t, "admin", "user", "create", "alice",
150		"--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
151
152	if _, _, code := inst.ssh(t, aliceKey, "", "profile", "set", "--about", "'inline text'"); code == 0 {
153		t.Error("profile set --about still accepted")
154	}
155	if _, _, code := inst.ssh(t, aliceKey, "x", "profile", "set", "--file", "-"); code == 0 {
156		t.Error("profile set --file still accepted")
157	}
158
159	// The flags that stay still work.
160	if _, errOut, code := inst.ssh(t, aliceKey, "",
161		"profile", "set", "--description", "'a line'", "--link", "'site|https://example.org'"); code != 0 {
162		t.Fatalf("profile set --description --link: %s", errOut)
163	}
164	out, _, _ := inst.ssh(t, aliceKey, "", "profile", "show", "alice", "--json")
165	if !strings.Contains(out, "a line") || !strings.Contains(out, "https://example.org") {
166		t.Errorf("description or link not saved: %s", out)
167	}
168}