e2e/reviewcarry_test.go

e6cd75b5f28bacf51620bb531320c30fd4e66bfd
gitbay/e2e/reviewcarry_test.go history · blame · raw

83 lines · 3323 bytes

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