e2e/mrdraft_test.go

0caaaedf8fa3d930b6b4fb83e249b1e0e3265c0a
gitbay/e2e/mrdraft_test.go history · blame · raw

99 lines · 3371 bytes

 1package e2e
 2
 3import (
 4	"encoding/json"
 5	"os"
 6	"path/filepath"
 7	"strings"
 8	"testing"
 9)
10
11// TestMRDraft covers the first stage of #111: a merge request opened to
12// show work rather than to ask for a merge.
13func TestMRDraft(t *testing.T) {
14	inst := startInstanceWith(t, "[web]\nmode = \"accounts\"\n")
15	aliceKey := inst.newKey(t, "alice")
16	bobKey := inst.newKey(t, "bob")
17	inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub")
18	inst.admin(t, "admin", "user", "create", "bob", "--key", bobKey+".pub")
19	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/app"); code != 0 {
20		t.Fatalf("repo create: %s", errOut)
21	}
22	if _, _, code := inst.ssh(t, aliceKey, "", "repo", "access", "grant", "alice/app", "bob", "write"); code != 0 {
23		t.Fatal("grant failed")
24	}
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, "a.txt"), []byte("a\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	mustGit(t, dir, env, "checkout", "-q", "-b", "feat")
36	mustGit(t, dir, env, "commit", "-q", "--allow-empty", "-m", "work")
37	mustGit(t, dir, env, "push", "-q", "origin", "feat")
38
39	if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "create", "alice/app",
40		"--source", "feat", "--target", "main", "--title", "'wip'", "--draft"); code != 0 {
41		t.Fatalf("mr create --draft: %s", errOut)
42	}
43
44	draft := func() bool {
45		t.Helper()
46		out, errOut, code := inst.ssh(t, aliceKey, "", "mr", "show", "alice/app", "1", "--json")
47		if code != 0 {
48			t.Fatalf("mr show: %s", errOut)
49		}
50		var env struct {
51			Data struct {
52				State string `json:"state"`
53				Draft bool   `json:"draft"`
54			} `json:"data"`
55		}
56		json.Unmarshal([]byte(out), &env)
57		// A draft is open, not a fifth state.
58		if env.Data.State != "open" {
59			t.Fatalf("draft changed the state to %q", env.Data.State)
60		}
61		return env.Data.Draft
62	}
63
64	if !draft() {
65		t.Fatal("--draft did not mark it")
66	}
67
68	// A draft does not merge, and no repository setting is involved.
69	_, errOut, code := inst.ssh(t, aliceKey, "", "mr", "merge", "alice/app", "1")
70	if code != 4 || !strings.Contains(errOut, "is a draft") {
71		t.Fatalf("draft merged: exit %d, %s", code, errOut)
72	}
73
74	// Nor does it sit in anyone's review queue.
75	out, _, _ := inst.ssh(t, bobKey, "", "dashboard", "--json")
76	if strings.Contains(out, `"review_queue":[{`) {
77		t.Fatalf("draft is in the review queue: %s", out)
78	}
79
80	// Ready, and now it does both.
81	if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "ready", "alice/app", "1"); code != 0 {
82		t.Fatalf("mr ready: %s", errOut)
83	}
84	if draft() {
85		t.Fatal("mr ready did not clear the mark")
86	}
87	out, _, _ = inst.ssh(t, bobKey, "", "dashboard", "--json")
88	if !strings.Contains(out, `"number":1`) {
89		t.Fatalf("ready MR is not in the review queue: %s", out)
90	}
91	if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "merge", "alice/app", "1"); code != 0 {
92		t.Fatalf("ready MR refused: %s", errOut)
93	}
94
95	// Ready twice is a usage error rather than a silent no-op.
96	if _, _, code := inst.ssh(t, aliceKey, "", "mr", "ready", "alice/app", "1"); code == 0 {
97		t.Fatal("mr ready on a merged MR succeeded")
98	}
99}