package main import ( "os" "os/exec" "path/filepath" "strings" "testing" ) func skipIfNoGit(t *testing.T) { t.Helper() if _, err := exec.LookPath("git"); err != nil { t.Skip("git not installed") } } func initRepo(t *testing.T, dir string) { t.Helper() mustRun := func(args ...string) { c := exec.Command("git", args...) c.Dir = dir c.Env = append(os.Environ(), "GIT_AUTHOR_NAME=test", "GIT_AUTHOR_EMAIL=test@x", "GIT_COMMITTER_NAME=test", "GIT_COMMITTER_EMAIL=test@x") out, err := c.CombinedOutput() if err != nil { t.Fatalf("git %v: %v\n%s", args, err, out) } } mustRun("init", "-b", "master") mustRun("config", "user.email", "test@x") mustRun("config", "user.name", "test") } func TestGitCommit_OK(t *testing.T) { skipIfNoGit(t) tmp := t.TempDir() repo := filepath.Join(tmp, "repo") os.MkdirAll(repo, 0755) initRepo(t, repo) os.WriteFile(filepath.Join(repo, "f.txt"), []byte("hello"), 0644) cap := tempCap(t, tmp+"/**") res, _, err := runGitCommit(cap, map[string]any{ "repo": repo, "message": "init", "files": []any{"f.txt"}, }) if err != nil { t.Fatalf("commit: %v", err) } m := res.(map[string]any) if m["commit_sha"].(string) == "" { t.Fatalf("empty sha") } } func TestGitCommit_PathNotAllowed(t *testing.T) { skipIfNoGit(t) cap := tempCap(t, "/tmp/safe/**") _, _, err := runGitCommit(cap, map[string]any{ "repo": "/etc", "message": "evil", }) if err == nil || !strings.Contains(err.Error(), "not allowed") { t.Fatalf("expected reject, got %v", err) } } func TestGitClone_Local(t *testing.T) { skipIfNoGit(t) tmp := t.TempDir() src := filepath.Join(tmp, "src") os.MkdirAll(src, 0755) initRepo(t, src) os.WriteFile(filepath.Join(src, "f.txt"), []byte("data"), 0644) c := exec.Command("git", "add", ".") c.Dir = src c.Run() c = exec.Command("git", "commit", "-m", "init") c.Dir = src c.Env = append(os.Environ(), "GIT_AUTHOR_NAME=t", "GIT_AUTHOR_EMAIL=t@x", "GIT_COMMITTER_NAME=t", "GIT_COMMITTER_EMAIL=t@x") out, err := c.CombinedOutput() if err != nil { t.Fatalf("seed commit: %v %s", err, out) } dest := filepath.Join(tmp, "clone") cap := tempCap(t, tmp+"/**") res, code, err := runGitClone(cap, map[string]any{ "url": src, "dest": dest, }) if err != nil { t.Fatalf("clone: %v code=%d", err, code) } m := res.(map[string]any) if m["commit_sha"].(string) == "" { t.Fatalf("empty sha") } if _, err := os.Stat(filepath.Join(dest, "f.txt")); err != nil { t.Fatalf("file not present after clone") } } func TestGitPush_PathNotAllowed(t *testing.T) { skipIfNoGit(t) cap := tempCap(t, "/tmp/safe/**") _, _, err := runGitPush(cap, map[string]any{"repo": "/etc"}) if err == nil || !strings.Contains(err.Error(), "not allowed") { t.Fatalf("expected reject, got %v", err) } }