e2e/forkweb_test.go

185f434bf23123c61a922129270c2db4cfebd493
gitbay/e2e/forkweb_test.go history · blame · raw

78 lines · 3133 bytes

 1package e2e
 2
 3import (
 4	"net/url"
 5	"os"
 6	"path/filepath"
 7	"strings"
 8	"testing"
 9)
10
11// Forking from the browser completes the contributor path: fork, edit a
12// file in the fork, open the merge request against the parent, without a
13// terminal at any step (#174).
14func TestForkWeb(t *testing.T) {
15	inst := startInstanceWith(t, "[web]\nmode = \"accounts\"\n")
16	aliceKey := inst.newKey(t, "alice")
17	bobKey := inst.newKey(t, "bob")
18	inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub",
19		"--email", "alice@example.test", "--verified")
20	inst.admin(t, "admin", "user", "create", "bob", "--key", bobKey+".pub",
21		"--email", "bob@example.test", "--verified")
22
23	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/app"); code != 0 {
24		t.Fatalf("repo create: %s", errOut)
25	}
26	env := inst.gitEnv(aliceKey)
27	work := t.TempDir()
28	mustGit(t, work, env, "clone", inst.sshURL("alice/app"), "w")
29	dir := filepath.Join(work, "w")
30	os.WriteFile(filepath.Join(dir, "f.txt"), []byte("x\n"), 0o644)
31	mustGit(t, dir, env, "checkout", "-q", "-b", "main")
32	mustGit(t, dir, env, "add", ".")
33	mustGit(t, dir, env, "commit", "-q", "-m", "base")
34	mustGit(t, dir, env, "push", "-q", "origin", "main")
35
36	bob := inst.login(t, bobKey)
37	base := inst.base() + "/alice/app"
38
39	// The control is on the repository header for a signed-in visitor.
40	if _, page := browserGet(t, bob, base); !strings.Contains(page, `/alice/app/fork"`) {
41		t.Fatalf("no fork control on the repository header:\n%s", page)
42	}
43
44	// Forking lands on the fork, which carries the parent's history.
45	if status, body := browserPost(t, bob, base+"/fork", url.Values{}); status != 200 ||
46		!strings.Contains(body, "bob/app") {
47		t.Fatalf("fork did not land on the new repository: %d\n%s", status, body)
48	}
49	out, _, _ := inst.ssh(t, bobKey, "", "repo", "list", "--json")
50	if !strings.Contains(out, `"path":"bob/app"`) {
51		t.Fatalf("fork not created:\n%s", out)
52	}
53
54	// Editing a file in the fork from the browser — the editor commits to
55	// the ref in the URL — then proposing it to the parent through the
56	// source picker.
57	if status, _ := browserPost(t, bob, inst.base()+"/bob/app/edit/main/f.txt", url.Values{
58		"content": {"y\n"}, "message": {"change f"}}); status != 200 {
59		t.Fatal("web edit in the fork failed")
60	}
61	if _, page := browserGet(t, bob, base+"/mrs/new"); !strings.Contains(page, `value="bob/app:main"`) {
62		t.Fatalf("the fork's branch is not offered:\n%s", page)
63	}
64	if status, _ := browserPost(t, bob, base+"/mrs/new", url.Values{
65		"source": {"bob/app:main"}, "target": {"main"}, "title": {"change"}}); status != 200 {
66		t.Fatal("mr create from the fork failed")
67	}
68	if out, _, _ := inst.ssh(t, aliceKey, "", "mr", "show", "alice/app", "1", "--json"); !strings.Contains(out, `"source":"bob/app:main"`) {
69		t.Fatalf("merge request not opened from the fork:\n%s", out)
70	}
71
72	// Forking twice collides on the name, and says so on the page rather
73	// than failing silently.
74	_, body := browserPost(t, bob, base+"/fork", url.Values{})
75	if !strings.Contains(body, `class="error"`) {
76		t.Errorf("a second fork reported nothing:\n%s", body)
77	}
78}