Files
xinghuoapi/backend/internal/service/token_refresher_test.go
IanShaw027 a4953785d9 fix(lint): 修复所有 Go 命名规范问题
- 全局替换 ApiKey → APIKey(类型、字段、方法、变量)
- 修复所有 initialism 命名(API, SMTP, HTML, URL 等)
- 添加所有缺失的包注释
- 修复导出符号的注释格式

主要修改:
- ApiKey → APIKey(所有出现的地方)
- ApiKeyID → APIKeyID
- ApiKeyIDs → APIKeyIDs
- TestSmtpConnection → TestSMTPConnection
- HtmlURL → HTMLURL
- 添加 20+ 个包注释
- 修复 10+ 个导出符号注释格式

验证结果:
- ✓ golangci-lint: 0 issues
- ✓ 单元测试: 通过
- ✓ 集成测试: 通过
2026-01-04 19:28:20 +08:00

229 lines
5.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build unit
package service
import (
"strconv"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestClaudeTokenRefresher_NeedsRefresh(t *testing.T) {
refresher := &ClaudeTokenRefresher{}
refreshWindow := 30 * time.Minute
tests := []struct {
name string
credentials map[string]any
wantRefresh bool
}{
{
name: "expires_at as string - expired",
credentials: map[string]any{
"expires_at": "1000", // 1970-01-01 00:16:40 UTC, 已过期
},
wantRefresh: true,
},
{
name: "expires_at as float64 - expired",
credentials: map[string]any{
"expires_at": float64(1000), // 数字类型,已过期
},
wantRefresh: true,
},
{
name: "expires_at as RFC3339 - expired",
credentials: map[string]any{
"expires_at": "1970-01-01T00:00:00Z", // RFC3339 格式,已过期
},
wantRefresh: true,
},
{
name: "expires_at as string - far future",
credentials: map[string]any{
"expires_at": "9999999999", // 远未来
},
wantRefresh: false,
},
{
name: "expires_at as float64 - far future",
credentials: map[string]any{
"expires_at": float64(9999999999), // 远未来,数字类型
},
wantRefresh: false,
},
{
name: "expires_at as RFC3339 - far future",
credentials: map[string]any{
"expires_at": "2099-12-31T23:59:59Z", // RFC3339 格式,远未来
},
wantRefresh: false,
},
{
name: "expires_at missing",
credentials: map[string]any{},
wantRefresh: false,
},
{
name: "expires_at is nil",
credentials: map[string]any{
"expires_at": nil,
},
wantRefresh: false,
},
{
name: "expires_at is invalid string",
credentials: map[string]any{
"expires_at": "invalid",
},
wantRefresh: false,
},
{
name: "credentials is nil",
credentials: nil,
wantRefresh: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
account := &Account{
Platform: PlatformAnthropic,
Type: AccountTypeOAuth,
Credentials: tt.credentials,
}
got := refresher.NeedsRefresh(account, refreshWindow)
require.Equal(t, tt.wantRefresh, got)
})
}
}
func TestClaudeTokenRefresher_NeedsRefresh_WithinWindow(t *testing.T) {
refresher := &ClaudeTokenRefresher{}
refreshWindow := 30 * time.Minute
// 设置一个在刷新窗口内的时间(当前时间 + 15分钟
expiresAt := time.Now().Add(15 * time.Minute).Unix()
tests := []struct {
name string
credentials map[string]any
}{
{
name: "string type - within refresh window",
credentials: map[string]any{
"expires_at": strconv.FormatInt(expiresAt, 10),
},
},
{
name: "float64 type - within refresh window",
credentials: map[string]any{
"expires_at": float64(expiresAt),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
account := &Account{
Platform: PlatformAnthropic,
Type: AccountTypeOAuth,
Credentials: tt.credentials,
}
got := refresher.NeedsRefresh(account, refreshWindow)
require.True(t, got, "should need refresh when within window")
})
}
}
func TestClaudeTokenRefresher_NeedsRefresh_OutsideWindow(t *testing.T) {
refresher := &ClaudeTokenRefresher{}
refreshWindow := 30 * time.Minute
// 设置一个在刷新窗口外的时间(当前时间 + 1小时
expiresAt := time.Now().Add(1 * time.Hour).Unix()
tests := []struct {
name string
credentials map[string]any
}{
{
name: "string type - outside refresh window",
credentials: map[string]any{
"expires_at": strconv.FormatInt(expiresAt, 10),
},
},
{
name: "float64 type - outside refresh window",
credentials: map[string]any{
"expires_at": float64(expiresAt),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
account := &Account{
Platform: PlatformAnthropic,
Type: AccountTypeOAuth,
Credentials: tt.credentials,
}
got := refresher.NeedsRefresh(account, refreshWindow)
require.False(t, got, "should not need refresh when outside window")
})
}
}
func TestClaudeTokenRefresher_CanRefresh(t *testing.T) {
refresher := &ClaudeTokenRefresher{}
tests := []struct {
name string
platform string
accType string
want bool
}{
{
name: "anthropic oauth - can refresh",
platform: PlatformAnthropic,
accType: AccountTypeOAuth,
want: true,
},
{
name: "anthropic api-key - cannot refresh",
platform: PlatformAnthropic,
accType: AccountTypeAPIKey,
want: false,
},
{
name: "openai oauth - cannot refresh",
platform: PlatformOpenAI,
accType: AccountTypeOAuth,
want: false,
},
{
name: "gemini oauth - cannot refresh",
platform: PlatformGemini,
accType: AccountTypeOAuth,
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
account := &Account{
Platform: tt.platform,
Type: tt.accType,
}
got := refresher.CanRefresh(account)
require.Equal(t, tt.want, got)
})
}
}