e2e/settingsweb_test.go

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

103 lines · 4614 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	if body := post(url.Values{"field": {"description"}, "description": {"a thing"}}); !strings.Contains(body, `class="notice" role="status">Saved the description.`) {
 43		t.Fatalf("no success flash after saving the description:\n%s", body)
 44	}
 45	if body := post(url.Values{"field": {"topics"}, "topics": {"cli, forge"}}); !strings.Contains(body, `value="cli, forge"`) {
 46		t.Fatalf("topics field is not prefilled after save:\n%s", body)
 47	}
 48	if body := post(url.Values{"field": {"topics"}, "topics": {"forge"}}); strings.Contains(body, `>cli<`) || !strings.Contains(body, `value="forge"`) {
 49		t.Fatalf("removing a topic through the field failed:\n%s", body)
 50	}
 51	if body := post(url.Values{"field": {"website"}, "website": {"javascript:alert(1)"}}); !strings.Contains(body, `class="error"`) || !strings.Contains(body, `value="javascript:alert(1)"`) {
 52		t.Fatalf("error does not keep the submitted website:\n%s", body)
 53	}
 54
 55	post(url.Values{"field": {"description"}, "description": {"a fine tool"}})
 56	post(url.Values{"field": {"website"}, "website": {"https://tool.example"}})
 57	post(url.Values{"field": {"require-checks"}, "require-checks": {"on"}})
 58	post(url.Values{"field": {"require-approvals"}, "approvals": {"2"}})
 59	post(url.Values{"field": {"protect"}, "branch": {"main"}})
 60
 61	out, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/app", "--json")
 62	for _, want := range []string{"a fine tool", "https://tool.example", `"forge"`} {
 63		if !strings.Contains(out, want) {
 64			t.Fatalf("repo show missing %q:\n%s", want, out)
 65		}
 66	}
 67	out, _, _ = inst.ssh(t, aliceKey, "", "repo", "settings", "show", "alice/app", "--json")
 68	for _, want := range []string{`"require_checks":true`, `"require_approvals":2`, `"main"`} {
 69		if !strings.Contains(out, want) {
 70			t.Fatalf("settings show missing %q:\n%s", want, out)
 71		}
 72	}
 73
 74	// Visibility is a new command; the web form drives it both ways.
 75	post(url.Values{"field": {"visibility"}, "visibility": {"private"}})
 76	if out, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/app", "--json"); !strings.Contains(out, `"visibility":"private"`) {
 77		t.Fatalf("not private:\n%s", out)
 78	}
 79	// A private repo disappears from anonymous surfaces.
 80	if status, _ := inst.get(t, "/alice/app"); status != 404 {
 81		t.Fatalf("private repo still public: %d", status)
 82	}
 83	post(url.Values{"field": {"visibility"}, "visibility": {"public"}})
 84	if status, _ := inst.get(t, "/alice/app"); status != 200 {
 85		t.Fatalf("public repo not restored: %d", status)
 86	}
 87
 88	// Archiving is reversible from the page; unchecking the box unarchives.
 89	post(url.Values{"field": {"archive"}, "archive": {"on"}})
 90	if out, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/app", "--json"); !strings.Contains(out, `"archived":true`) {
 91		t.Fatalf("not archived:\n%s", out)
 92	}
 93	post(url.Values{"field": {"archive"}})
 94	if out, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/app", "--json"); strings.Contains(out, `"archived":true`) {
 95		t.Fatalf("still archived:\n%s", out)
 96	}
 97
 98	// Unprotecting works.
 99	post(url.Values{"field": {"unprotect"}, "branch": {"main"}})
100	if out, _, _ := inst.ssh(t, aliceKey, "", "repo", "settings", "show", "alice/app", "--json"); strings.Contains(out, `"protected_branches"`) {
101		t.Fatalf("branch still protected:\n%s", out)
102	}
103}