Files
gh-repo-bootstrap/internal/githubapi/resolve_test.go
T
2026-05-26 09:09:47 -05:00

174 lines
4.1 KiB
Go

package githubapi
import (
"fmt"
"os"
"os/exec"
"strings"
"testing"
)
func TestHelperProcess(t *testing.T) {
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
return
}
defer os.Exit(0)
args := os.Args
for i, arg := range args {
if arg == "--" {
args = args[i+1:]
break
}
}
if len(args) < 3 {
fmt.Fprintf(os.Stderr, "invalid args: %v\n", args)
os.Exit(2)
}
command := args[0]
subCmd := args[1]
path := args[2]
if command != "gh" || subCmd != "api" {
fmt.Fprintf(os.Stderr, "expected command 'gh api', got: %s %s\n", command, subCmd)
os.Exit(2)
}
switch {
case path == "users/octocat":
fmt.Print(`{"id":583234}`)
case path == "users/error-user":
fmt.Fprint(os.Stderr, "http error 404")
os.Exit(1)
case path == "users/no-id-user":
fmt.Print(`{"login":"no-id-user"}`)
case path == "users/bad-json-user":
fmt.Print(`{invalid}`)
case path == "orgs/JMR-dev/teams/release-managers":
fmt.Print(`{"id":98765}`)
case path == "orgs/JMR-dev/teams/error-team":
fmt.Fprint(os.Stderr, "http error 404")
os.Exit(1)
default:
fmt.Fprintf(os.Stderr, "unknown path: %s\n", path)
os.Exit(2)
}
}
func mockExec(command string, args ...string) *exec.Cmd {
cs := []string{"-test.run=TestHelperProcess", "--", command}
cs = append(cs, args...)
cmd := exec.Command(os.Args[0], cs...)
cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
return cmd
}
func TestResolveUser(t *testing.T) {
oldExec := ExecCommand
ExecCommand = mockExec
defer func() { ExecCommand = oldExec }()
r := New()
// 1. Numeric ID passes through
id, err := r.ResolveUser("12345")
if err != nil {
t.Fatalf("unexpected error for numeric user ID: %v", err)
}
if id != 12345 {
t.Errorf("expected 12345, got %d", id)
}
// 2. Resolve login (with leading @)
id, err = r.ResolveUser("@octocat")
if err != nil {
t.Fatalf("unexpected error for user @octocat: %v", err)
}
if id != 583234 {
t.Errorf("expected 583234, got %d", id)
}
// 3. Cached lookup
id, err = r.ResolveUser("octocat")
if err != nil {
t.Fatalf("unexpected error for user octocat (cached): %v", err)
}
if id != 583234 {
t.Errorf("expected 583234, got %d", id)
}
// 4. API Error
_, err = r.ResolveUser("error-user")
if err == nil || !strings.Contains(err.Error(), "http error 404") {
t.Errorf("expected http error 404, got %v", err)
}
// 5. No ID field in response
_, err = r.ResolveUser("no-id-user")
if err == nil || !strings.Contains(err.Error(), "returned no id") {
t.Errorf("expected 'returned no id' error, got %v", err)
}
// 6. Bad JSON response
_, err = r.ResolveUser("bad-json-user")
if err == nil || !strings.Contains(err.Error(), "decoding gh api") {
t.Errorf("expected decoding error, got %v", err)
}
}
func TestResolveTeam(t *testing.T) {
oldExec := ExecCommand
ExecCommand = mockExec
defer func() { ExecCommand = oldExec }()
r := New()
// 1. Numeric ID passes through
id, err := r.ResolveTeam("54321")
if err != nil {
t.Fatalf("unexpected error for numeric team ID: %v", err)
}
if id != 54321 {
t.Errorf("expected 54321, got %d", id)
}
// 2. Bare slug rejected
_, err = r.ResolveTeam("release-managers")
if err == nil || !strings.Contains(err.Error(), "must be in the form org/team-slug") {
t.Errorf("expected format error, got %v", err)
}
// 3. Invalid formats
for _, invalid := range []string{"org/", "/team"} {
_, err = r.ResolveTeam(invalid)
if err == nil || !strings.Contains(err.Error(), "must be in the form org/team-slug") {
t.Errorf("expected format error for %q, got %v", invalid, err)
}
}
// 4. Resolve slug
id, err = r.ResolveTeam("JMR-dev/release-managers")
if err != nil {
t.Fatalf("unexpected error for team: %v", err)
}
if id != 98765 {
t.Errorf("expected 98765, got %d", id)
}
// 5. Cached slug
id, err = r.ResolveTeam("JMR-dev/release-managers")
if err != nil {
t.Fatalf("unexpected error for team (cached): %v", err)
}
if id != 98765 {
t.Errorf("expected 98765, got %d", id)
}
// 6. API Error
_, err = r.ResolveTeam("JMR-dev/error-team")
if err == nil || !strings.Contains(err.Error(), "http error 404") {
t.Errorf("expected http error 404, got %v", err)
}
}