cli/pkg/cmd/auth/shared/gitcredentials/helper_config_test.go
2024-05-16 17:01:41 +02:00

188 lines
5.9 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/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 TestConfigureOursNoPreexistingHelpersConfigured(t *testing.T) {
// Given there are no credential helpers configured
withIsolatedGitConfig(t)
// When we configure ourselves as the git credential helper
hc := gitcredentials.HelperConfig{
SelfExecutablePath: "/path/to/gh",
GitClient: &git.Client{},
}
require.NoError(t, hc.ConfigureOurs("github.com"))
// Then the git config should be updated to use our credential helper for both repos and gists
repoHelper, err := hc.ConfiguredHelper("github.com")
require.NoError(t, err)
require.True(t, repoHelper.IsConfigured(), "expected our helper to be configured")
require.True(t, repoHelper.IsOurs(), "expected the helper to be ours but was %q", repoHelper.Cmd)
gistHelper, err := hc.ConfiguredHelper("gist.github.com")
require.NoError(t, err)
require.True(t, gistHelper.IsConfigured(), "expected our helper to be configured")
require.True(t, gistHelper.IsOurs(), "expected the helper to be ours but was %q", gistHelper.Cmd)
}
func TestConfigureOursWithPreexistingHelpersConfigured(t *testing.T) {
// Given there are other credential helpers configured
withIsolatedGitConfig(t)
configureTestCredentialHelper(t, "credential.helper")
configureTestCredentialHelper(t, "credential.https://github.com.helper")
// When we configure ourselves as the git credential helper
hc := gitcredentials.HelperConfig{
SelfExecutablePath: "/path/to/gh",
GitClient: &git.Client{},
}
require.NoError(t, hc.ConfigureOurs("github.com"))
// Then the git config should be updated to use our credential repoHelper for both repos and gists
repoHelper, err := hc.ConfiguredHelper("github.com")
require.NoError(t, err)
require.True(t, repoHelper.IsConfigured(), "expected our helper to be configured")
require.True(t, repoHelper.IsOurs(), "expected the helper to be ours but was %q", repoHelper.Cmd)
gistHelper, err := hc.ConfiguredHelper("gist.github.com")
require.NoError(t, err)
require.True(t, gistHelper.IsConfigured(), "expected our helper to be configured")
require.True(t, gistHelper.IsOurs(), "expected the helper to be ours but was %q", gistHelper.Cmd)
}
func TestConfiguredHelperNoPreexistingHelpersConfigured(t *testing.T) {
// Given there are no credential helpers configured
withIsolatedGitConfig(t)
// When we check the configured helper for a hostname
hc := gitcredentials.HelperConfig{
SelfExecutablePath: "/path/to/gh",
GitClient: &git.Client{},
}
helper, err := hc.ConfiguredHelper("github.com")
// Then the helper should not be configured and not ours
require.NoError(t, err)
require.False(t, helper.IsConfigured(), "expected no helper to be configured")
require.False(t, helper.IsOurs(), "expected the helper not to be ours but was %q", helper.Cmd)
}
func TestConfiguredHelperWithPreexistingGlobalHelperConfigured(t *testing.T) {
// Given there is a global credential helper configured
withIsolatedGitConfig(t)
configureTestCredentialHelper(t, "credential.helper")
// When we check the configured helper for a hostname
hc := gitcredentials.HelperConfig{
SelfExecutablePath: "/path/to/gh",
GitClient: &git.Client{},
}
helper, err := hc.ConfiguredHelper("github.com")
// Then the helper should be configured, but not ours
require.NoError(t, err)
require.True(t, helper.IsConfigured(), "expected no helper to be configured")
require.False(t, helper.IsOurs(), "expected the helper not to be ours but was %q", helper.Cmd)
}
func TestConfiguredHelperWithPreexistingHostHelperConfigured(t *testing.T) {
// Given there is a credential helper configured for a hostname
withIsolatedGitConfig(t)
configureTestCredentialHelper(t, "credential.https://github.com.helper")
// When we check the configured helper for a hostname
hc := gitcredentials.HelperConfig{
SelfExecutablePath: "/path/to/gh",
GitClient: &git.Client{},
}
helper, err := hc.ConfiguredHelper("github.com")
// Then the helper should be configured, but not ours
require.NoError(t, err)
require.True(t, helper.IsConfigured(), "expected no helper to be configured")
require.False(t, helper.IsOurs(), "expected the helper not to be ours but was %q", helper.Cmd)
}
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)
}
})
}
}