e2e/requiremr_test.go

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

84 lines · 3319 bytes

 1package e2e
 2
 3import (
 4	"os"
 5	"path/filepath"
 6	"strings"
 7	"testing"
 8)
 9
10// With require-mr on, a protected branch takes changes through mr merge
11// only: direct pushes and commit-file are refused, a branch that does
12// not exist yet can still be created, and unprotected branches are
13// unaffected (#197).
14func TestRequireMR(t *testing.T) {
15	t.Parallel()
16	inst := startInstance(t)
17	aliceKey := inst.newKey(t, "alice")
18	inst.admin(t, "admin", "user", "create", "alice",
19		"--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
20	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/lib"); code != 0 {
21		t.Fatalf("repo create: %s", errOut)
22	}
23	env := inst.gitEnv(aliceKey)
24	work := t.TempDir()
25	mustGit(t, work, env, "clone", "-q", inst.sshURL("alice/lib"), "lib")
26	dir := filepath.Join(work, "lib")
27	write := func(name, content string) {
28		t.Helper()
29		if err := os.WriteFile(filepath.Join(dir, name), []byte(content), 0o644); err != nil {
30			t.Fatal(err)
31		}
32		mustGit(t, dir, env, "add", name)
33		mustGit(t, dir, env, "commit", "-q", "-m", name)
34	}
35	mustGit(t, dir, env, "checkout", "-q", "-b", "main")
36	write("README", "one\n")
37	mustGit(t, dir, env, "push", "-q", "origin", "main")
38
39	for _, args := range [][]string{
40		{"repo", "settings", "protect", "alice/lib", "main"},
41		{"repo", "settings", "protect", "alice/lib", "release"},
42		{"repo", "settings", "require-mr", "alice/lib", "on"},
43	} {
44		if _, errOut, code := inst.ssh(t, aliceKey, "", args...); code != 0 {
45			t.Fatalf("%v: %s", args, errOut)
46		}
47	}
48	out, _, _ := inst.ssh(t, aliceKey, "", "repo", "settings", "show", "alice/lib", "--json")
49	if !strings.Contains(out, `"require_mr":true`) {
50		t.Fatalf("settings show: %s", out)
51	}
52
53	// Direct push to main: refused, with the reason.
54	write("two", "two\n")
55	if out, code := gitRun(t, dir, env, "push", "origin", "main"); code == 0 || !strings.Contains(out, "merge requests only") {
56		t.Fatalf("direct push to protected branch: %d\n%s", code, out)
57	}
58	if _, errOut, code := inst.ssh(t, aliceKey, "x\n", "repo", "commit-file", "alice/lib", "notes.txt",
59		"--ref", "main", "--file", "-"); code != 4 || !strings.Contains(errOut, "merge requests only") {
60		t.Fatalf("commit-file to protected branch: %d %s", code, errOut)
61	}
62	// Creating a protected branch is still a push; so is an unprotected one.
63	mustGit(t, dir, env, "push", "-q", "origin", "main:release")
64	mustGit(t, dir, env, "push", "-q", "origin", "main:feature")
65
66	// The same change lands through a merge request.
67	if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "create", "alice/lib",
68		"--source", "feature", "--target", "main", "--title", "'two'"); code != 0 {
69		t.Fatalf("mr create: %s", errOut)
70	}
71	if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "merge", "alice/lib", "1", "--strategy", "ff"); code != 0 {
72		t.Fatalf("mr merge: %s", errOut)
73	}
74	if out, _, _ := inst.ssh(t, aliceKey, "", "repo", "log", "alice/lib", "--limit", "1"); !strings.Contains(out, "two") {
75		t.Fatalf("merge did not move main: %s", out)
76	}
77
78	// Off again, and the push goes through.
79	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "settings", "require-mr", "alice/lib", "off"); code != 0 {
80		t.Fatalf("require-mr off: %s", errOut)
81	}
82	write("three", "three\n")
83	mustGit(t, dir, env, "push", "-q", "origin", "main")
84}