e2e/adminusersweb_test.go

v1.39.0
gitbay/e2e/adminusersweb_test.go history · blame · raw

85 lines · 3654 bytes

 1package e2e
 2
 3import (
 4	"net/url"
 5	"strings"
 6	"testing"
 7)
 8
 9// /admin/users lists accounts and runs the account commands, which the
10// web can reach now that nothing is held back from it (#234). Demote
11// and disable carry the typed-name check.
12func TestAdminUsersWeb(t *testing.T) {
13	t.Parallel()
14	inst := startInstanceWith(t, "[web]\nmode = \"accounts\"\n")
15	rootKey := inst.newKey(t, "root")
16	aliceKey := inst.newKey(t, "alice")
17	inst.admin(t, "admin", "user", "create", "root", "--key", rootKey+".pub", "--admin",
18		"--email", "root@example.test", "--verified")
19	inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub",
20		"--email", "alice@example.test", "--verified")
21
22	// A non-admin sees neither the page nor a hint that it exists.
23	if status, _ := browserGet(t, inst.login(t, aliceKey), inst.base()+"/admin/users"); status != 404 {
24		t.Fatalf("non-admin reached the account list: %d", status)
25	}
26
27	root := inst.login(t, rootKey)
28	page := inst.base() + "/admin/users"
29	_, body := browserGet(t, root, page)
30	for _, want := range []string{">alice<", ">root<", "Promote", "Disable"} {
31		if !strings.Contains(body, want) {
32			t.Fatalf("account list missing %q:\n%s", want, body)
33		}
34	}
35	// The admin page links here.
36	if _, admin := browserGet(t, root, inst.base()+"/admin"); !strings.Contains(admin, `href="/admin/users"`) {
37		t.Fatalf("admin page does not link the account list:\n%s", admin)
38	}
39
40	post := func(v url.Values) string {
41		t.Helper()
42		status, body := browserPost(t, root, page, v)
43		if status != 200 {
44			t.Fatalf("post %v: %d", v, status)
45		}
46		return body
47	}
48
49	// Disable needs the typed name: the wrong one changes nothing.
50	post(url.Values{"field": {"disable"}, "user": {"alice"}, "confirm": {"alicce"}})
51	if out, _, _ := inst.ssh(t, rootKey, "", "admin", "user", "show", "alice", "--json"); !strings.Contains(out, `"state":"active"`) {
52		t.Fatalf("a mistyped confirm still disabled the account: %s", out)
53	}
54	post(url.Values{"field": {"disable"}, "user": {"alice"}, "confirm": {"alice"}})
55	if out, _, _ := inst.ssh(t, rootKey, "", "admin", "user", "show", "alice", "--json"); !strings.Contains(out, `"state":"disabled"`) {
56		t.Fatalf("disable did not take: %s", out)
57	}
58	post(url.Values{"field": {"enable"}, "user": {"alice"}})
59	post(url.Values{"field": {"promote"}, "user": {"alice"}})
60	if out, _, _ := inst.ssh(t, rootKey, "", "admin", "user", "show", "alice", "--json"); strings.Contains(out, `"admin":true`) {
61		t.Fatalf("promote without a confirm took: %s", out)
62	}
63	post(url.Values{"field": {"promote"}, "user": {"alice"}, "confirm": {"alice"}})
64	if out, _, _ := inst.ssh(t, rootKey, "", "admin", "user", "show", "alice", "--json"); !strings.Contains(out, `"admin":true`) {
65		t.Fatalf("promote did not take: %s", out)
66	}
67	post(url.Values{"field": {"demote"}, "user": {"alice"}, "confirm": {"alice"}})
68	if out, _, _ := inst.ssh(t, rootKey, "", "admin", "user", "show", "alice", "--json"); strings.Contains(out, `"admin":true`) {
69		t.Fatalf("demote did not take: %s", out)
70	}
71
72	// The command's own refusals reach the page: the last admin stays.
73	b := post(url.Values{"field": {"demote"}, "user": {"root"}, "confirm": {"root"}})
74	if !strings.Contains(b, "admin") {
75		t.Fatalf("no message after demoting the last admin:\n%s", b)
76	}
77	if out, _, _ := inst.ssh(t, rootKey, "", "admin", "user", "show", "root", "--json"); !strings.Contains(out, `"admin":true`) {
78		t.Fatalf("the last admin was demoted: %s", out)
79	}
80
81	// The state filter narrows the list.
82	if _, body := browserGet(t, root, page+"?state=admin"); strings.Contains(body, ">alice<") {
83		t.Fatalf("the admin filter listed a non-admin:\n%s", body)
84	}
85}