e2e/profileweb_test.go

32a5f76e5b270097b63a5bba9a43557cf50ad63d
gitbay/e2e/profileweb_test.go history · blame · raw

138 lines · 5252 bytes

  1package e2e
  2
  3import (
  4	"net/url"
  5	"strings"
  6	"testing"
  7)
  8
  9// TestProfileSettingsWeb covers profile set from the account settings page
 10// (#161): description, website and links round-trip through the form, and
 11// emptying a field actually clears it rather than being skipped. The about
 12// text is not on this form — it is a file, covered below.
 13func TestProfileSettingsWeb(t *testing.T) {
 14	t.Parallel()
 15	inst := startInstanceWith(t, "[web]\nmode = \"accounts\"\n")
 16	aliceKey := inst.newKey(t, "alice")
 17	inst.admin(t, "admin", "user", "create", "alice",
 18		"--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
 19	alice := inst.login(t, aliceKey)
 20	settingsURL := inst.base() + "/settings"
 21
 22	// The form is on the page, every input labelled.
 23	_, body := browserGet(t, alice, settingsURL)
 24	for _, want := range []string{
 25		`<label for="p-description">`, `<label for="p-website">`,
 26		`<label for="p-links">`,
 27	} {
 28		if !strings.Contains(body, want) {
 29			t.Fatalf("profile form missing %q:\n%s", want, body)
 30		}
 31	}
 32
 33	// Setting every field lands where the CLI reads it.
 34	status, _ := browserPost(t, alice, settingsURL, url.Values{
 35		"field":       {"profile"},
 36		"description": {"builds small tools"},
 37		"website":     {"https://alice.example"},
 38		"links":       {"Mastodon|https://fosstodon.example/@alice\nhttps://alice.example/now"},
 39	})
 40	if status != 200 && status != 303 {
 41		t.Fatalf("profile post: %d", status)
 42	}
 43	out, _, _ := inst.ssh(t, aliceKey, "", "profile", "show", "--json")
 44	for _, want := range []string{
 45		`"description":"builds small tools"`, `"website":"https://alice.example"`,
 46		`"label":"Mastodon"`, `"url":"https://fosstodon.example/@alice"`,
 47		`"url":"https://alice.example/now"`,
 48	} {
 49		if !strings.Contains(out, want) {
 50			t.Fatalf("profile set missing %q: %s", want, out)
 51		}
 52	}
 53
 54	// The page shows what was just saved.
 55	_, body = browserGet(t, alice, settingsURL)
 56	for _, want := range []string{
 57		"builds small tools", "https://alice.example", "Mastodon|https://fosstodon.example/@alice",
 58		"https://alice.example/now",
 59	} {
 60		if !strings.Contains(body, want) {
 61			t.Fatalf("settings page did not round-trip %q:\n%s", want, body)
 62		}
 63	}
 64
 65	// The whole form resubmits every time, the way a settings page does:
 66	// each step below carries the fields already in place and changes one.
 67	links := "Mastodon|https://fosstodon.example/@alice\nhttps://alice.example/now"
 68
 69	// Emptying the website clears it, not leaves it alone.
 70	if status, _ := browserPost(t, alice, settingsURL, url.Values{
 71		"field": {"profile"}, "description": {"builds small tools"},
 72		"website": {""}, "links": {links},
 73	}); status != 200 && status != 303 {
 74		t.Fatalf("profile post (clear website): %d", status)
 75	}
 76	out, _, _ = inst.ssh(t, aliceKey, "", "profile", "show", "--json")
 77	if strings.Contains(out, "alice.example") && strings.Contains(out, `"website"`) {
 78		t.Fatalf("website not cleared: %s", out)
 79	}
 80	if !strings.Contains(out, "builds small tools") {
 81		t.Fatalf("clearing website clobbered the description: %s", out)
 82	}
 83	if !strings.Contains(out, `"label":"Mastodon"`) {
 84		t.Fatalf("clearing website clobbered the links: %s", out)
 85	}
 86
 87	// Emptying the links field clears the whole list.
 88	if status, _ := browserPost(t, alice, settingsURL, url.Values{
 89		"field": {"profile"}, "description": {"builds small tools"}, "links": {""},
 90	}); status != 200 && status != 303 {
 91		t.Fatalf("profile post (clear links): %d", status)
 92	}
 93	out, _, _ = inst.ssh(t, aliceKey, "", "profile", "show", "--json")
 94	if strings.Contains(out, "Mastodon") || strings.Contains(out, `"links"`) {
 95		t.Fatalf("links not cleared: %s", out)
 96	}
 97}
 98
 99// The settings page does not edit the about text; it creates the
100// repository that holds it and points at the file editor.
101func TestProfileAboutRepoFromWeb(t *testing.T) {
102	t.Parallel()
103	inst := startInstanceWith(t, "[web]\nmode = \"accounts\"\n")
104	aliceKey := inst.newKey(t, "alice")
105	inst.admin(t, "admin", "user", "create", "alice",
106		"--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
107	alice := inst.login(t, aliceKey)
108	settingsURL := inst.base() + "/settings"
109
110	// With no repository yet, the page offers to create one.
111	_, body := browserGet(t, alice, settingsURL)
112	if !strings.Contains(body, "Create alice/.gitbay") {
113		t.Fatalf("settings page does not offer the profile repository:\n%s", body)
114	}
115
116	if status, _ := browserPost(t, alice, settingsURL, url.Values{
117		"field": {"profile-repo"},
118	}); status != 200 && status != 303 {
119		t.Fatalf("profile-repo post: %d", status)
120	}
121
122	// The repository exists with a starter file, and the page now links to
123	// the editor instead of offering to create it again.
124	out, _, code := inst.ssh(t, aliceKey, "", "profile", "show", "alice", "--json")
125	if code != 0 {
126		t.Fatalf("profile show: %d", code)
127	}
128	if !strings.Contains(out, `"about_path":"profile/README.md"`) {
129		t.Fatalf("starter about not committed: %s", out)
130	}
131	_, body = browserGet(t, alice, settingsURL)
132	if !strings.Contains(body, "/alice/.gitbay/edit/main/profile/README.md") {
133		t.Fatalf("settings page does not link to the about file:\n%s", body)
134	}
135	if strings.Contains(body, "Create alice/.gitbay") {
136		t.Error("settings page still offers to create an existing repository")
137	}
138}