仰望星辰工作室

gitcat

gitcat/ internal/server/testhelper_test.go 3.4 KB · 110 行 原始文件
1package server
2
3import (
4 "fmt"
5 "os"
6 "os/exec"
7 "path/filepath"
8 "strings"
9 "testing"
10
11 "gitcat/internal/gitx"
12 "gitcat/internal/store"
13)
14
15// testHash 是测试账号的明文密码;哈希由服务自己的 hashPassword 生成,
16// 必须用真 bcrypt 串——basicAuthUser 会走 CompareHashAndAuthentication。
17const testPass = "secret-pw"
18
19func testHash(t *testing.T) string {
20 t.Helper()
21 h, err := hashPassword(testPass)
22 if err != nil {
23 t.Fatalf("生成密码哈希失败: %v", err)
24 }
25 return h
26}
27
28// newTestServer 起一个已完成安装的测试服务。alice 是管理员兼仓库 owner,
29// bob 是无关的普通用户——权限测试只需要这个区分。
30func newTestServer(t *testing.T) (*Server, *store.Store, *store.User, *store.User) {
31 t.Helper()
32 dir := t.TempDir()
33 st, err := store.Open(filepath.Join(dir, "gitcat.db"))
34 if err != nil {
35 t.Fatalf("打开数据库失败: %v", err)
36 }
37 t.Cleanup(func() { st.Close() })
38 for _, kv := range [][2]string{{"installed", "1"}, {"site_name", "测试站"}} {
39 if err := st.SetSetting(kv[0], kv[1]); err != nil {
40 t.Fatalf("写入设置失败: %v", err)
41 }
42 }
43 alice, err := st.CreateUser("alice", "Alice", "", testHash(t), true)
44 if err != nil {
45 t.Fatalf("建 alice 失败: %v", err)
46 }
47 bob, err := st.CreateUser("bob", "Bob", "", testHash(t), false)
48 if err != nil {
49 t.Fatalf("建 bob 失败: %v", err)
50 }
51 srv, err := New(Config{Addr: ":0", DataDir: dir, Version: "1.0.0-test"}, st)
52 if err != nil {
53 t.Fatalf("构造服务失败: %v", err)
54 }
55 return srv, st, alice, bob
56}
57
58// makeRepo 造一个仓库记录 + 磁盘裸仓库,返回目录路径。
59// owner 为 nil 时挂到 alice 名下——repos.owner_id 有外键,传 0 会失败。
60func makeRepo(t *testing.T, srv *Server, st *store.Store, name string, owner *store.User) string {
61 t.Helper()
62 if owner == nil {
63 owner, _ = st.UserByUsername("alice")
64 }
65 repo, err := st.CreateRepo(name, "", owner.ID)
66 if err != nil {
67 t.Fatalf("建仓库记录失败: %v", err)
68 }
69 dir := srv.repoPath(repo.Name)
70 if err := gitx.InitBare(dir, "main"); err != nil {
71 t.Fatalf("初始化裸仓库失败: %v", err)
72 }
73 return dir
74}
75
76// gitOut 在裸仓库里跑一条 git 命令并返回输出。
77func gitOut(t *testing.T, dir, stdin string, args ...string) string {
78 t.Helper()
79 cmd := exec.Command("git", args...)
80 cmd.Dir = dir
81 cmd.Env = testGitEnv()
82 if stdin != "" {
83 cmd.Stdin = strings.NewReader(stdin)
84 }
85 out, err := cmd.CombinedOutput()
86 if err != nil {
87 t.Fatalf("git %s 失败: %v\n%s", strings.Join(args, " "), err, out)
88 }
89 return strings.TrimSpace(string(out))
90}
91
92// commitFiles 把一组文件写进裸仓库并提交到 main。
93func commitFiles(t *testing.T, dir, message string, files map[string]string) {
94 t.Helper()
95 var lines []string
96 for name, content := range files {
97 sha := gitOut(t, dir, content, "hash-object", "-w", "--stdin")
98 lines = append(lines, fmt.Sprintf("100644 blob %s\t%s", sha, name))
99 }
100 tree := gitOut(t, dir, strings.Join(lines, "\n")+"\n", "mktree")
101 commit := gitOut(t, dir, "", "commit-tree", tree, "-m", message)
102 gitOut(t, dir, "", "update-ref", "refs/heads/main", commit)
103}
104
105// testGitEnv 补上 git 作者身份,测试机未必配了 user.name/email。
106func testGitEnv() []string {
107 return append(os.Environ(),
108 "GIT_AUTHOR_NAME=gitcat", "GIT_AUTHOR_EMAIL=test@gitcat.local",
109 "GIT_COMMITTER_NAME=gitcat", "GIT_COMMITTER_EMAIL=test@gitcat.local")
110}