mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-18 04:10:51 +08:00
Add Google One personal account login to Gemini CLI OAuth flow: - CLI --login shows mode menu (Code Assist vs Google One) - Web management API accepts project_id=GOOGLE_ONE sentinel - Auto-discover project via onboardUser without cloudaicompanionProject when project is unresolved Improve robustness of auto-discovery and token handling: - Add context-aware auto-discovery polling (30s timeout, 2s interval) - Distinguish network errors from project-selection-required errors - Refresh expired access tokens in readAuthFile before project lookup - Extend project_id auto-fill to gemini auth type (was antigravity-only) Unify credential file naming to geminicli- prefix for both CLI and web. Add extractAccessToken unit tests (9 cases).
81 lines
1.5 KiB
Go
81 lines
1.5 KiB
Go
package auth
|
|
|
|
import "testing"
|
|
|
|
func TestExtractAccessToken(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
metadata map[string]any
|
|
expected string
|
|
}{
|
|
{
|
|
"antigravity top-level access_token",
|
|
map[string]any{"access_token": "tok-abc"},
|
|
"tok-abc",
|
|
},
|
|
{
|
|
"gemini nested token.access_token",
|
|
map[string]any{
|
|
"token": map[string]any{"access_token": "tok-nested"},
|
|
},
|
|
"tok-nested",
|
|
},
|
|
{
|
|
"top-level takes precedence over nested",
|
|
map[string]any{
|
|
"access_token": "tok-top",
|
|
"token": map[string]any{"access_token": "tok-nested"},
|
|
},
|
|
"tok-top",
|
|
},
|
|
{
|
|
"empty metadata",
|
|
map[string]any{},
|
|
"",
|
|
},
|
|
{
|
|
"whitespace-only access_token",
|
|
map[string]any{"access_token": " "},
|
|
"",
|
|
},
|
|
{
|
|
"wrong type access_token",
|
|
map[string]any{"access_token": 12345},
|
|
"",
|
|
},
|
|
{
|
|
"token is not a map",
|
|
map[string]any{"token": "not-a-map"},
|
|
"",
|
|
},
|
|
{
|
|
"nested whitespace-only",
|
|
map[string]any{
|
|
"token": map[string]any{"access_token": " "},
|
|
},
|
|
"",
|
|
},
|
|
{
|
|
"fallback to nested when top-level empty",
|
|
map[string]any{
|
|
"access_token": "",
|
|
"token": map[string]any{"access_token": "tok-fallback"},
|
|
},
|
|
"tok-fallback",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
got := extractAccessToken(tt.metadata)
|
|
if got != tt.expected {
|
|
t.Errorf("extractAccessToken() = %q, want %q", got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|