Files
sub2api/backend/internal/service/openai_codex_pat_service_test.go
李建琦 6d655c9903
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
Sub2API v1.0 - AI API 网关(二开初始版本,基于上游 Wei-Shaw/sub2api)
2026-08-21 18:30:13 +08:00

124 lines
4.5 KiB
Go

package service
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/Wei-Shaw/sub2api/internal/pkg/openai"
"github.com/stretchr/testify/require"
)
func TestOpenAIOAuthService_ValidateCodexPersonalAccessToken(t *testing.T) {
var gotAuthorization string
var gotOriginator string
var gotUserAgent string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotAuthorization = r.Header.Get("authorization")
gotOriginator = r.Header.Get("originator")
gotUserAgent = r.Header.Get("user-agent")
w.Header().Set("content-type", "application/json")
_, _ = w.Write([]byte(`{
"email":"user@example.com",
"chatgpt_user_id":"user-123",
"chatgpt_account_id":"acct-123",
"chatgpt_plan_type":"plus",
"chatgpt_account_is_fedramp":true
}`))
}))
defer server.Close()
originalURL := openAICodexPATWhoamiURL
openAICodexPATWhoamiURL = server.URL
defer func() { openAICodexPATWhoamiURL = originalURL }()
svc := NewOpenAIOAuthService(nil, nil)
defer svc.Stop()
info, err := svc.ValidateCodexPersonalAccessToken(context.Background(), " at-test-token ", "")
require.NoError(t, err)
require.Equal(t, "Bearer at-test-token", gotAuthorization)
require.Equal(t, openai.CodexDefaultOriginator, gotOriginator)
require.Equal(t, CodexCanonicalUserAgent(), gotUserAgent)
require.Equal(t, OpenAIAuthModePersonalAccessToken, info.AuthMode)
require.Equal(t, "user@example.com", info.Email)
require.Equal(t, "user-123", info.ChatGPTUserID)
require.Equal(t, "acct-123", info.ChatGPTAccountID)
require.Equal(t, "plus", info.PlanType)
require.True(t, info.ChatGPTAccountFedRAMP)
require.Zero(t, info.ExpiresAt)
require.Empty(t, info.RefreshToken)
}
func TestOpenAIOAuthService_ValidateCodexPersonalAccessTokenRequiresATPrefix(t *testing.T) {
svc := NewOpenAIOAuthService(nil, nil)
defer svc.Stop()
_, err := svc.ValidateCodexPersonalAccessToken(context.Background(), "eyJ.jwt", "")
require.Error(t, err)
require.Contains(t, err.Error(), "at-")
}
func TestOpenAIOAuthService_BuildAccountCredentialsForPAT(t *testing.T) {
svc := NewOpenAIOAuthService(nil, nil)
defer svc.Stop()
credentials := svc.BuildAccountCredentials(&OpenAITokenInfo{
AccessToken: "at-test-token",
AuthMode: OpenAIAuthModePersonalAccessToken,
Email: "user@example.com",
ChatGPTAccountID: "acct-123",
ChatGPTUserID: "user-123",
ChatGPTAccountFedRAMP: true,
PlanType: "plus",
})
require.Equal(t, "at-test-token", credentials["access_token"])
require.Equal(t, OpenAIAuthModePersonalAccessToken, credentials["auth_mode"])
require.Equal(t, "personal_access_token", credentials["openai_auth_mode"])
require.Equal(t, "Bearer", credentials["token_type"])
require.Equal(t, true, credentials["chatgpt_account_is_fedramp"])
require.NotContains(t, credentials, "expires_at")
require.NotContains(t, credentials, "refresh_token")
require.NotContains(t, credentials, "id_token")
}
func TestNormalizeOpenAIPersonalAccessTokenCredentialsRemovesOAuthFields(t *testing.T) {
account := &Account{
Platform: PlatformOpenAI,
Type: AccountTypeOAuth,
Credentials: map[string]any{
"auth_mode": "personal_access_token",
},
}
credentials := map[string]any{
"access_token": "at-test-token",
"refresh_token": "stale-refresh-token",
"id_token": "stale-id-token",
"expires_at": "2026-01-01T00:00:00Z",
"expires_in": 3600,
"client_id": "stale-client",
"model_mapping": map[string]any{"gpt-5": "gpt-5-codex"},
"chatgpt_account_is_fedramp": true,
"subscription_expires_at": "2026-12-31T00:00:00Z",
"openai_usage_channel_fields": []any{"custom"},
}
got := NormalizeOpenAIPersonalAccessTokenCredentials(account, nil, credentials)
require.Equal(t, "at-test-token", got["access_token"])
require.Equal(t, OpenAIAuthModePersonalAccessToken, got["auth_mode"])
require.Equal(t, "personal_access_token", got["openai_auth_mode"])
require.Equal(t, "Bearer", got["token_type"])
require.NotContains(t, got, "refresh_token")
require.NotContains(t, got, "id_token")
require.NotContains(t, got, "expires_at")
require.NotContains(t, got, "expires_in")
require.NotContains(t, got, "client_id")
require.Equal(t, map[string]any{"gpt-5": "gpt-5-codex"}, got["model_mapping"])
require.Equal(t, true, got["chatgpt_account_is_fedramp"])
require.Equal(t, "2026-12-31T00:00:00Z", got["subscription_expires_at"])
require.Equal(t, []any{"custom"}, got["openai_usage_channel_fields"])
}