Files
goclaw/internal/skills/github_installer_test.go

158 lines
4.6 KiB
Go

package skills
import (
"errors"
"path/filepath"
"strings"
"testing"
)
func TestParseGitHubSpec(t *testing.T) {
cases := []struct {
in string
ok bool
owner string
repo string
tag string
}{
{"github:cli/cli@v2.45.0", true, "cli", "cli", "v2.45.0"},
{"github:cli/cli", true, "cli", "cli", ""},
{"github:jesseduffield/lazygit@v0.42.0", true, "jesseduffield", "lazygit", "v0.42.0"},
{"github:sharkdp/fd@v9.0.0+build.1", true, "sharkdp", "fd", "v9.0.0+build.1"},
{"github:owner/repo.subpath@v1", true, "owner", "repo.subpath", "v1"},
{"github:a/b", true, "a", "b", ""},
{"github:Org-1/Repo_2@x-y.z", true, "Org-1", "Repo_2", "x-y.z"},
{"pip:foo", false, "", "", ""},
{"github:/repo", false, "", "", ""},
{"github:owner/", false, "", "", ""},
{"github:-bad/repo", false, "", "", ""},
{"github:bad-/repo", false, "", "", ""},
{"github:owner/repo@", false, "", "", ""},
{"", false, "", "", ""},
}
for _, tc := range cases {
got, err := ParseGitHubSpec(tc.in)
if tc.ok {
if err != nil {
t.Errorf("%q: unexpected error %v", tc.in, err)
continue
}
if got.Owner != tc.owner || got.Repo != tc.repo || got.Tag != tc.tag {
t.Errorf("%q: got %+v, want {%s %s %s}", tc.in, got, tc.owner, tc.repo, tc.tag)
}
} else {
if err == nil {
t.Errorf("%q: expected error, got %+v", tc.in, got)
}
}
}
}
func TestSelectAsset(t *testing.T) {
// Realistic-ish asset lists.
lazygit := []GitHubAsset{
{Name: "lazygit_0.42.0_Linux_x86_64.tar.gz"},
{Name: "lazygit_0.42.0_Linux_arm64.tar.gz"},
{Name: "lazygit_0.42.0_Darwin_x86_64.tar.gz"},
{Name: "lazygit_0.42.0_Windows_x86_64.zip"},
{Name: "checksums.txt"},
}
starship := []GitHubAsset{
{Name: "starship-x86_64-unknown-linux-musl.tar.gz"},
{Name: "starship-aarch64-unknown-linux-musl.tar.gz"},
{Name: "starship-x86_64-pc-windows-msvc.zip"},
{Name: "starship-x86_64-unknown-linux-musl.tar.gz.sha256"},
}
noMatch := []GitHubAsset{
{Name: "tool-Darwin-arm64.tar.gz"},
{Name: "Source code (zip)"},
}
t.Run("lazygit amd64", func(t *testing.T) {
a, err := SelectAsset(lazygit, "linux", "amd64")
if err != nil {
t.Fatal(err)
}
if !strings.Contains(a.Name, "Linux_x86_64") {
t.Errorf("got %s", a.Name)
}
})
t.Run("lazygit arm64", func(t *testing.T) {
a, err := SelectAsset(lazygit, "linux", "arm64")
if err != nil {
t.Fatal(err)
}
if !strings.Contains(a.Name, "Linux_arm64") {
t.Errorf("got %s", a.Name)
}
})
t.Run("starship musl amd64", func(t *testing.T) {
a, err := SelectAsset(starship, "linux", "amd64")
if err != nil {
t.Fatal(err)
}
if a.Name != "starship-x86_64-unknown-linux-musl.tar.gz" {
t.Errorf("got %s", a.Name)
}
})
t.Run("no match", func(t *testing.T) {
_, err := SelectAsset(noMatch, "linux", "amd64")
if !errors.Is(err, ErrNoMatchingAsset) {
t.Errorf("want ErrNoMatchingAsset, got %v", err)
}
if !strings.Contains(err.Error(), "tool-Darwin-arm64") {
t.Errorf("error should list available assets, got: %v", err)
}
})
}
func TestAllowedOrg(t *testing.T) {
empty := NewGitHubInstaller(nil, &GitHubPackagesConfig{})
if !empty.AllowedOrg("anyone") {
t.Error("empty allowlist should permit all orgs")
}
locked := NewGitHubInstaller(nil, &GitHubPackagesConfig{AllowedOrgs: []string{"GoodOrg", " digitop "}})
if !locked.AllowedOrg("goodorg") {
t.Error("goodorg should be allowed (case-insensitive)")
}
if !locked.AllowedOrg("Digitop") {
t.Error("digitop should be allowed after trim+lowercase")
}
if locked.AllowedOrg("evil") {
t.Error("evil should be rejected")
}
}
func TestConfigDefaults(t *testing.T) {
runtimeDir := t.TempDir()
t.Setenv("RUNTIME_DIR", runtimeDir)
c := &GitHubPackagesConfig{}
c.Defaults()
if c.BinDir == "" || c.ManifestPath == "" || c.MaxAssetSizeMB != 200 {
t.Errorf("unexpected defaults: %+v", c)
}
if want := filepath.Join(runtimeDir, "bin"); c.BinDir != want {
t.Errorf("BinDir = %q, want %q", c.BinDir, want)
}
if want := filepath.Join(runtimeDir, "github-packages.json"); c.ManifestPath != want {
t.Errorf("ManifestPath = %q, want %q", c.ManifestPath, want)
}
if c.MaxAssetBytes() != 200*1024*1024 {
t.Errorf("MaxAssetBytes wrong: %d", c.MaxAssetBytes())
}
}
func TestCanonicalPackageName(t *testing.T) {
spec := &GitHubSpec{Owner: "cli", Repo: "cli"}
if canonicalPackageName(spec, []string{"gh"}) != "gh" {
t.Error("single differing binary name should win")
}
if canonicalPackageName(spec, []string{"cli"}) != "cli" {
t.Error("matching binary name should use repo")
}
if canonicalPackageName(spec, []string{"a", "b"}) != "cli" {
t.Error("multi binaries should fall back to repo name")
}
}