e2e/adminusersweb_test.go

e9566eed86ebcd185c4b85f63d667b5e671fe787
gitbay/e2e/adminusersweb_test.go history · blame · raw

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