e2e/defaultbranch_test.go
94 lines · 4105 bytes
1package e2e
2
3import (
4 "net/url"
5 "os"
6 "path/filepath"
7 "strings"
8 "testing"
9)
10
11// A first push of a branch other than main moves the unborn HEAD to it,
12// and repo settings default-branch moves it later (#189).
13func TestDefaultBranch(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",
18 "--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
19 inst.admin(t, "admin", "user", "create", "bob", "--key", bobKey+".pub")
20 if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/proj"); code != 0 {
21 t.Fatalf("repo create: %s", errOut)
22 }
23
24 env := inst.gitEnv(aliceKey)
25 dir := filepath.Join(t.TempDir(), "proj")
26 mustGit(t, t.TempDir(), env, "init", "-q", "-b", "master", dir)
27 if err := os.WriteFile(filepath.Join(dir, "README"), []byte("hello\n"), 0o644); err != nil {
28 t.Fatal(err)
29 }
30 mustGit(t, dir, env, "add", "README")
31 mustGit(t, dir, env, "commit", "-q", "-m", "one")
32 mustGit(t, dir, env, "remote", "add", "origin", inst.sshURL("alice/proj"))
33 mustGit(t, dir, env, "push", "-q", "origin", "master")
34
35 // HEAD followed the push: a clone checks master out, and the record
36 // agrees.
37 clone := filepath.Join(t.TempDir(), "c1")
38 mustGit(t, t.TempDir(), env, "clone", "-q", inst.sshURL("alice/proj"), clone)
39 if head := strings.TrimSpace(mustGit(t, clone, env, "symbolic-ref", "HEAD")); head != "refs/heads/master" {
40 t.Fatalf("clone HEAD %q", head)
41 }
42 if _, err := os.Stat(filepath.Join(clone, "README")); err != nil {
43 t.Fatalf("clone checked out nothing: %v", err)
44 }
45 out, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/proj", "--json")
46 if !strings.Contains(out, `"default_branch":"master"`) {
47 t.Fatalf("repo show after first push: %s", out)
48 }
49
50 // A second branch does not move HEAD; the setting does.
51 mustGit(t, dir, env, "checkout", "-q", "-b", "dev")
52 if err := os.WriteFile(filepath.Join(dir, "DEV"), []byte("dev\n"), 0o644); err != nil {
53 t.Fatal(err)
54 }
55 mustGit(t, dir, env, "add", "DEV")
56 mustGit(t, dir, env, "commit", "-q", "-m", "two")
57 mustGit(t, dir, env, "push", "-q", "origin", "dev")
58 out, _, _ = inst.ssh(t, aliceKey, "", "repo", "show", "alice/proj", "--json")
59 if !strings.Contains(out, `"default_branch":"master"`) {
60 t.Fatalf("second branch moved the default: %s", out)
61 }
62 if _, errOut, code := inst.ssh(t, bobKey, "", "repo", "settings", "default-branch", "alice/proj", "dev"); code != 4 {
63 t.Fatalf("non-admin set the default branch: %d %s", code, errOut)
64 }
65 if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "settings", "default-branch", "alice/proj", "nope"); code != 1 || !strings.Contains(errOut, "no branch") {
66 t.Fatalf("missing branch accepted: %d %s", code, errOut)
67 }
68 if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "settings", "default-branch", "alice/proj", "dev"); code != 0 {
69 t.Fatalf("default-branch: %s", errOut)
70 }
71 clone = filepath.Join(t.TempDir(), "c2")
72 mustGit(t, t.TempDir(), env, "clone", "-q", inst.sshURL("alice/proj"), clone)
73 if head := strings.TrimSpace(mustGit(t, clone, env, "symbolic-ref", "HEAD")); head != "refs/heads/dev" {
74 t.Fatalf("clone HEAD after setting %q", head)
75 }
76 out, _, _ = inst.ssh(t, aliceKey, "", "repo", "show", "alice/proj", "--json")
77 if !strings.Contains(out, `"default_branch":"dev"`) {
78 t.Fatalf("repo show after setting: %s", out)
79 }
80
81 // The settings page carries the same control.
82 alice := inst.login(t, aliceKey)
83 set := inst.base() + "/alice/proj/settings"
84 if _, body := browserGet(t, alice, set); !strings.Contains(body, `value="dev" selected`) {
85 t.Fatalf("settings page does not show the default branch:\n%s", body)
86 }
87 if status, _ := browserPost(t, alice, set, url.Values{"field": {"default-branch"}, "default-branch": {"master"}}); status != 200 {
88 t.Fatalf("settings post: %d", status)
89 }
90 out, _, _ = inst.ssh(t, aliceKey, "", "repo", "show", "alice/proj", "--json")
91 if !strings.Contains(out, `"default_branch":"master"`) {
92 t.Fatalf("repo show after web: %s", out)
93 }
94}