125 lines
3 KiB
Go
125 lines
3 KiB
Go
package gitcredentials_test
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/cli/cli/v2/git"
|
|
"github.com/cli/cli/v2/pkg/cmd/auth/shared"
|
|
"github.com/cli/cli/v2/pkg/cmd/auth/shared/contract"
|
|
"github.com/cli/cli/v2/pkg/cmd/auth/shared/gitcredentials"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func withIsolatedGitConfig(t *testing.T) {
|
|
t.Helper()
|
|
|
|
// https://git-scm.com/docs/git-config#ENVIRONMENT
|
|
// Set the global git config to a temporary file
|
|
tmpDir := t.TempDir()
|
|
configFile := filepath.Join(tmpDir, ".gitconfig")
|
|
t.Setenv("GIT_CONFIG_GLOBAL", configFile)
|
|
|
|
// And disable git reading the system config
|
|
t.Setenv("GIT_CONFIG_NOSYSTEM", "true")
|
|
}
|
|
|
|
func configureTestCredentialHelper(t *testing.T, key string) {
|
|
t.Helper()
|
|
|
|
gc := &git.Client{}
|
|
cmd, err := gc.Command(context.Background(), "config", "--global", "--add", key, "test-helper")
|
|
require.NoError(t, err)
|
|
require.NoError(t, cmd.Run())
|
|
}
|
|
|
|
func TestHelperConfigContract(t *testing.T) {
|
|
contract.HelperConfig{
|
|
NewHelperConfig: func(t *testing.T) shared.HelperConfig {
|
|
withIsolatedGitConfig(t)
|
|
|
|
return &gitcredentials.HelperConfig{
|
|
SelfExecutablePath: "/path/to/gh",
|
|
GitClient: &git.Client{},
|
|
}
|
|
},
|
|
ConfigureHelper: func(t *testing.T, hostname string) {
|
|
configureTestCredentialHelper(t, hostname)
|
|
},
|
|
}.Test(t)
|
|
}
|
|
|
|
// This is a whitebox test unlike the contract because although we don't use the exact configured command, it's
|
|
// important that it is exactly right since git uses it.
|
|
func TestSetsCorrectCommandInGitConfig(t *testing.T) {
|
|
withIsolatedGitConfig(t)
|
|
|
|
gc := &git.Client{}
|
|
hc := &gitcredentials.HelperConfig{
|
|
SelfExecutablePath: "/path/to/gh",
|
|
GitClient: gc,
|
|
}
|
|
require.NoError(t, hc.ConfigureOurs("github.com"))
|
|
|
|
// Check that the correct command was set in the git config
|
|
cmd, err := gc.Command(context.Background(), "config", "--get", "credential.https://github.com.helper")
|
|
require.NoError(t, err)
|
|
output, err := cmd.Output()
|
|
require.NoError(t, err)
|
|
require.Equal(t, "!/path/to/gh auth git-credential\n", string(output))
|
|
}
|
|
|
|
func TestHelperIsOurs(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cmd string
|
|
want bool
|
|
windowsOnly bool
|
|
}{
|
|
{
|
|
name: "blank",
|
|
cmd: "",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "invalid",
|
|
cmd: "!",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "osxkeychain",
|
|
cmd: "osxkeychain",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "looks like gh but isn't",
|
|
cmd: "gh auth",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "ours",
|
|
cmd: "!/path/to/gh auth",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "ours - Windows edition",
|
|
cmd: `!'C:\Program Files\GitHub CLI\gh.exe' auth git-credential`,
|
|
want: true,
|
|
windowsOnly: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.windowsOnly && runtime.GOOS != "windows" {
|
|
t.Skip("skipping test on non-Windows platform")
|
|
}
|
|
|
|
h := gitcredentials.Helper{Cmd: tt.cmd}
|
|
if got := h.IsOurs(); got != tt.want {
|
|
t.Errorf("IsOurs() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|