e2e/reviewcarry_test.go
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}