173 lines
3.7 KiB
Go
173 lines
3.7 KiB
Go
|
|
package pull
|
||
|
|
|
||
|
|
import (
|
||
|
|
"archive/zip"
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"reflect"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"code.geekeey.de/actions/sdk"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestParseConfig(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
cases := []struct {
|
||
|
|
name string
|
||
|
|
env map[string]string
|
||
|
|
want *config
|
||
|
|
wantErr bool
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "default path",
|
||
|
|
env: map[string]string{"name": "foo"},
|
||
|
|
want: &config{Name: "foo", Path: "."},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "explicit path",
|
||
|
|
env: map[string]string{"name": "foo", "path": "out"},
|
||
|
|
want: &config{Name: "foo", Path: "out"},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "other repository",
|
||
|
|
env: map[string]string{
|
||
|
|
"name": "foo", "repository": "owner/repo", "run-id": "42", "github-token": "tok",
|
||
|
|
},
|
||
|
|
want: &config{Name: "foo", Path: ".", Repository: "owner/repo", RunID: "42", Token: "tok"},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "missing name",
|
||
|
|
env: map[string]string{},
|
||
|
|
wantErr: true,
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tc := range cases {
|
||
|
|
tc := tc
|
||
|
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
got, err := parseConfig(func(k string) string { return tc.env[k] })
|
||
|
|
if tc.wantErr {
|
||
|
|
if err == nil {
|
||
|
|
t.Fatalf("expected error, got %+v", got)
|
||
|
|
}
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if !reflect.DeepEqual(got, tc.want) {
|
||
|
|
t.Errorf("expected %+v, got %+v", tc.want, got)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestUseRepositoryAPI(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
gh := &sdk.GitHubContext{Repository: "owner/repo", RunID: "100"}
|
||
|
|
|
||
|
|
cases := []struct {
|
||
|
|
name string
|
||
|
|
cfg *config
|
||
|
|
want bool
|
||
|
|
}{
|
||
|
|
{"current", &config{Repository: "owner/repo", RunID: "100"}, false},
|
||
|
|
{"empty means current", &config{}, false},
|
||
|
|
{"other repository", &config{Repository: "other/repo", RunID: "100"}, true},
|
||
|
|
{"other run", &config{Repository: "owner/repo", RunID: "200"}, true},
|
||
|
|
{"repository only matches", &config{Repository: "owner/repo"}, false},
|
||
|
|
{"repository only differs", &config{Repository: "other/repo"}, true},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tc := range cases {
|
||
|
|
tc := tc
|
||
|
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
if got := useRepositoryAPI(tc.cfg, gh); got != tc.want {
|
||
|
|
t.Errorf("expected %v, got %v", tc.want, got)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestExtractArchive(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
zipPath := filepath.Join(t.TempDir(), "artifact.zip")
|
||
|
|
writeZip(t, zipPath, map[string]string{
|
||
|
|
"a.txt": "a",
|
||
|
|
"sub/b.txt": "b",
|
||
|
|
})
|
||
|
|
|
||
|
|
dest := t.TempDir()
|
||
|
|
if err := extractArchive(zipPath, dest); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
for name, want := range map[string]string{"a.txt": "a", "sub/b.txt": "b"} {
|
||
|
|
got, err := os.ReadFile(filepath.Join(dest, name))
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if string(got) != want {
|
||
|
|
t.Errorf("expected %q to contain %q, got %q", name, want, got)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestExtractArchive_PathTraversal(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
zipPath := filepath.Join(t.TempDir(), "artifact.zip")
|
||
|
|
writeZip(t, zipPath, map[string]string{"../evil.txt": "evil"})
|
||
|
|
|
||
|
|
if err := extractArchive(zipPath, t.TempDir()); err == nil {
|
||
|
|
t.Fatal("expected error for path traversal entry")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDownloadPath(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
|
||
|
|
abs := t.TempDir()
|
||
|
|
if got := downloadPath(abs); got != abs {
|
||
|
|
t.Errorf("expected %q, got %q", abs, got)
|
||
|
|
}
|
||
|
|
|
||
|
|
wd, err := os.Getwd()
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if got, want := downloadPath("out"), filepath.Join(wd, "out"); got != want {
|
||
|
|
t.Errorf("expected %q, got %q", want, got)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func writeZip(t *testing.T, path string, files map[string]string) {
|
||
|
|
t.Helper()
|
||
|
|
|
||
|
|
f, err := os.Create(path)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
defer f.Close()
|
||
|
|
|
||
|
|
zw := zip.NewWriter(f)
|
||
|
|
for name, content := range files {
|
||
|
|
w, err := zw.Create(name)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if _, err := w.Write([]byte(content)); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if err := zw.Close(); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
}
|