e2e/settingsweb_test.go

v1.1.0
gitbay/e2e/settingsweb_test.go history · blame · raw

94 lines · 3997 bytes

 1package e2e
 2
 3import (
 4	"net/url"
 5	"strings"
 6	"testing"
 7)
 8
 9// TestRepoSettingsWeb drives the settings page: each control runs the
10// command the CLI runs, so repo show and settings show are the check.
11func TestRepoSettingsWeb(t *testing.T) {
12	inst := startInstanceWith(t, "[web]\nmode = \"accounts\"\n")
13	aliceKey := inst.newKey(t, "alice")
14	bobKey := inst.newKey(t, "bob")
15	inst.admin(t, "admin", "user", "create", "alice",
16		"--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
17	inst.admin(t, "admin", "user", "create", "bob", "--key", bobKey+".pub")
18	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/app"); code != 0 {
19		t.Fatalf("repo create: %s", errOut)
20	}
21
22	alice := inst.login(t, aliceKey)
23	set := inst.base() + "/alice/app/settings"
24
25	// Only admins reach the page, and only they see the tab.
26	if _, body := browserGet(t, alice, inst.base()+"/alice/app"); !strings.Contains(body, "/alice/app/settings") {
27		t.Fatalf("no settings tab for the owner:\n%s", body)
28	}
29	if status, _ := browserGet(t, inst.login(t, bobKey), set); status != 403 && status != 404 {
30		t.Fatalf("reader reached settings: %d", status)
31	}
32
33	post := func(v url.Values) string {
34		t.Helper()
35		status, body := browserPost(t, alice, set, v)
36		if status != 200 {
37			t.Fatalf("settings post %v: %d", v, status)
38		}
39		return body
40	}
41
42	post(url.Values{"field": {"description"}, "description": {"a fine tool"}})
43	post(url.Values{"field": {"website"}, "website": {"https://tool.example"}})
44	post(url.Values{"field": {"topics"}, "add": {"cli forge"}})
45	post(url.Values{"field": {"require-checks"}, "require-checks": {"on"}})
46	post(url.Values{"field": {"require-approvals"}, "approvals": {"2"}})
47	post(url.Values{"field": {"protect"}, "branch": {"main"}})
48
49	out, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/app", "--json")
50	for _, want := range []string{"a fine tool", "https://tool.example", `"cli"`, `"forge"`} {
51		if !strings.Contains(out, want) {
52			t.Fatalf("repo show missing %q:\n%s", want, out)
53		}
54	}
55	out, _, _ = inst.ssh(t, aliceKey, "", "repo", "settings", "show", "alice/app", "--json")
56	for _, want := range []string{`"require_checks":true`, `"require_approvals":2`, `"main"`} {
57		if !strings.Contains(out, want) {
58			t.Fatalf("settings show missing %q:\n%s", want, out)
59		}
60	}
61
62	// Visibility is a new command; the web form drives it both ways.
63	post(url.Values{"field": {"visibility"}, "visibility": {"private"}})
64	if out, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/app", "--json"); !strings.Contains(out, `"visibility":"private"`) {
65		t.Fatalf("not private:\n%s", out)
66	}
67	// A private repo disappears from anonymous surfaces.
68	if status, _ := inst.get(t, "/alice/app"); status != 404 {
69		t.Fatalf("private repo still public: %d", status)
70	}
71	post(url.Values{"field": {"visibility"}, "visibility": {"public"}})
72	if status, _ := inst.get(t, "/alice/app"); status != 200 {
73		t.Fatalf("public repo not restored: %d", status)
74	}
75
76	// Archiving is reversible from the page; unchecking the box unarchives.
77	post(url.Values{"field": {"archive"}, "archive": {"on"}})
78	if out, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/app", "--json"); !strings.Contains(out, `"archived":true`) {
79		t.Fatalf("not archived:\n%s", out)
80	}
81	post(url.Values{"field": {"archive"}})
82	if out, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/app", "--json"); strings.Contains(out, `"archived":true`) {
83		t.Fatalf("still archived:\n%s", out)
84	}
85
86	// Unprotecting works, and a refusal surfaces the command's message.
87	post(url.Values{"field": {"unprotect"}, "branch": {"main"}})
88	if out, _, _ := inst.ssh(t, aliceKey, "", "repo", "settings", "show", "alice/app", "--json"); strings.Contains(out, `"protected_branches"`) {
89		t.Fatalf("branch still protected:\n%s", out)
90	}
91	if body := post(url.Values{"field": {"website"}, "website": {"javascript:alert(1)"}}); !strings.Contains(body, `class="error"`) {
92		t.Fatalf("bad website accepted:\n%s", body)
93	}
94}