e2e/reviewcarry_test.go

8e6fc2062ca26f7a848bdf6ad6345fd345351231
gitbay/e2e/reviewcarry_test.go history · blame · raw

82 lines · 3309 bytes

 1package e2e
 2
 3import (
 4	"os"
 5	"path/filepath"
 6	"strings"
 7	"testing"
 8)
 9
10// A rebase that leaves the merge request's diff unchanged keeps its
11// fresh approvals; a push that changes the diff stales them (#198).
12func TestApprovalsSurviveSameDiffRebase(t *testing.T) {
13	inst := startInstance(t)
14	aliceKey := inst.newKey(t, "alice")
15	bobKey := inst.newKey(t, "bob")
16	inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub")
17	inst.admin(t, "admin", "user", "create", "bob", "--key", bobKey+".pub")
18	for _, args := range [][]string{
19		{"repo", "create", "alice/app"},
20		{"repo", "access", "grant", "alice/app", "bob", "write"},
21		{"repo", "settings", "require-approvals", "alice/app", "1"},
22	} {
23		if _, errOut, code := inst.ssh(t, aliceKey, "", args...); code != 0 {
24			t.Fatalf("%v: %s", args, errOut)
25		}
26	}
27	env := inst.gitEnv(aliceKey)
28	work := t.TempDir()
29	mustGit(t, work, env, "clone", "-q", inst.sshURL("alice/app"), "w")
30	dir := filepath.Join(work, "w")
31	write := func(name, content string) {
32		t.Helper()
33		if err := os.WriteFile(filepath.Join(dir, name), []byte(content), 0o644); err != nil {
34			t.Fatal(err)
35		}
36		mustGit(t, dir, env, "add", name)
37		mustGit(t, dir, env, "commit", "-q", "-m", name)
38	}
39	mustGit(t, dir, env, "checkout", "-q", "-b", "main")
40	write("a.txt", "a\n")
41	mustGit(t, dir, env, "push", "-q", "origin", "main")
42
43	mustGit(t, dir, env, "checkout", "-q", "-b", "feat")
44	write("b.txt", "b\n")
45	mustGit(t, dir, env, "push", "-q", "origin", "feat")
46	if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "create", "alice/app",
47		"--source", "feat", "--target", "main", "--title", "'feat'"); code != 0 {
48		t.Fatalf("mr create: %s", errOut)
49	}
50	if _, errOut, code := inst.ssh(t, bobKey, "", "mr", "review", "alice/app", "1", "--approve"); code != 0 {
51		t.Fatalf("approve: %s", errOut)
52	}
53
54	// main moves on; the author rebases and force-pushes. Same diff.
55	mustGit(t, dir, env, "checkout", "-q", "main")
56	write("c.txt", "c\n")
57	mustGit(t, dir, env, "push", "-q", "origin", "main")
58	mustGit(t, dir, env, "checkout", "-q", "feat")
59	mustGit(t, dir, env, "rebase", "-q", "main")
60	mustGit(t, dir, env, "push", "-q", "--force", "origin", "feat")
61	out, _, _ := inst.ssh(t, aliceKey, "", "mr", "show", "alice/app", "1", "--json")
62	if !strings.Contains(out, `"reviewer":"bob","verdict":"approve","stale":false`) {
63		t.Fatalf("approval went stale on a same-diff rebase:\n%s", out)
64	}
65
66	// A push that changes the diff stales it, and the merge waits.
67	write("b.txt", "b2\n")
68	mustGit(t, dir, env, "push", "-q", "origin", "feat")
69	out, _, _ = inst.ssh(t, aliceKey, "", "mr", "show", "alice/app", "1", "--json")
70	if !strings.Contains(out, `"reviewer":"bob","verdict":"approve","stale":true`) {
71		t.Fatalf("approval survived a changed diff:\n%s", out)
72	}
73	if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "merge", "alice/app", "1"); code != 4 || !strings.Contains(errOut, "fresh approval") {
74		t.Fatalf("merge on a stale approval: %d %s", code, errOut)
75	}
76	if _, errOut, code := inst.ssh(t, bobKey, "", "mr", "review", "alice/app", "1", "--approve"); code != 0 {
77		t.Fatalf("second approve: %s", errOut)
78	}
79	if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "merge", "alice/app", "1", "--strategy", "ff"); code != 0 {
80		t.Fatalf("merge after fresh approval: %s", errOut)
81	}
82}