Files
sub2api/backend/internal/service/account_codex_fingerprint_seed_lifecycle_test.go
T
李建琦 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

246 lines
8.4 KiB
Go

package service
import (
"context"
"testing"
"github.com/stretchr/testify/require"
)
const userSuppliedCodexFingerprintSeed = "22222222-2222-4222-8222-222222222222"
func requireValidCodexFingerprintSeed(t *testing.T, extra map[string]any) string {
t.Helper()
seed, ok := codexFingerprintSeed(extra)
require.True(t, ok, "expected valid canonical Codex fingerprint seed")
return seed
}
func TestAdminCreateAccountStripsUserSeedAndCreatesFreshSeedWhenEnabled(t *testing.T) {
repo := &upstreamBillingProbeAccountRepo{}
svc := &adminServiceImpl{accountRepo: repo}
created, err := svc.CreateAccount(context.Background(), &CreateAccountInput{
Name: "codex-oauth",
Platform: PlatformOpenAI,
Type: AccountTypeOAuth,
SkipDefaultGroupBind: true,
Extra: map[string]any{
codexFingerprintModeExtraKey: "session",
codexFingerprintSeedExtraKey: userSuppliedCodexFingerprintSeed,
},
})
require.NoError(t, err)
seed := requireValidCodexFingerprintSeed(t, created.Extra)
require.NotEqual(t, userSuppliedCodexFingerprintSeed, seed)
require.Equal(t, "session", created.Extra[codexFingerprintModeExtraKey])
}
func TestAdminUpdateAccountPreservesExistingSeedAndStripsUserSeed(t *testing.T) {
accountID := int64(201)
repo := &upstreamBillingProbeAccountRepo{accounts: map[int64]*Account{
accountID: {
ID: accountID,
Name: "before",
Platform: PlatformOpenAI,
Type: AccountTypeOAuth,
Status: StatusActive,
Extra: map[string]any{
codexFingerprintModeExtraKey: "session",
codexFingerprintSeedExtraKey: testCodexFingerprintSeed,
},
},
}}
svc := &adminServiceImpl{accountRepo: repo}
updated, err := svc.UpdateAccount(context.Background(), accountID, &UpdateAccountInput{
Extra: map[string]any{
codexFingerprintModeExtraKey: "full",
codexFingerprintSeedExtraKey: userSuppliedCodexFingerprintSeed,
"custom": "value",
},
})
require.NoError(t, err)
require.Equal(t, testCodexFingerprintSeed, requireValidCodexFingerprintSeed(t, updated.Extra))
require.Equal(t, "full", updated.Extra[codexFingerprintModeExtraKey])
require.Equal(t, "value", updated.Extra["custom"])
}
func TestAdminUpdateAccountInitializesSeedWhenFullEditEnables(t *testing.T) {
accountID := int64(202)
repo := &upstreamBillingProbeAccountRepo{accounts: map[int64]*Account{
accountID: {
ID: accountID,
Name: "before",
Platform: PlatformOpenAI,
Type: AccountTypeOAuth,
Status: StatusActive,
Extra: map[string]any{
codexFingerprintModeExtraKey: "off",
codexFingerprintSeedExtraKey: "not-a-seed",
},
},
}}
updated, err := (&adminServiceImpl{accountRepo: repo}).UpdateAccount(context.Background(), accountID, &UpdateAccountInput{
Extra: map[string]any{codexFingerprintModeExtraKey: "device"},
})
require.NoError(t, err)
require.NotEqual(t, "not-a-seed", requireValidCodexFingerprintSeed(t, updated.Extra))
require.Equal(t, "device", updated.Extra[codexFingerprintModeExtraKey])
}
func TestAdminUpdateAccountDisableReenablePreservesValidSeed(t *testing.T) {
accountID := int64(203)
repo := &upstreamBillingProbeAccountRepo{accounts: map[int64]*Account{
accountID: {
ID: accountID,
Platform: PlatformOpenAI,
Type: AccountTypeOAuth,
Status: StatusActive,
Extra: map[string]any{
codexFingerprintModeExtraKey: "session",
codexFingerprintSeedExtraKey: testCodexFingerprintSeed,
},
},
}}
svc := &adminServiceImpl{accountRepo: repo}
disabled, err := svc.UpdateAccount(context.Background(), accountID, &UpdateAccountInput{
Extra: map[string]any{codexFingerprintModeExtraKey: "off"},
})
require.NoError(t, err)
require.Equal(t, testCodexFingerprintSeed, requireValidCodexFingerprintSeed(t, disabled.Extra))
reenabled, err := svc.UpdateAccount(context.Background(), accountID, &UpdateAccountInput{
Extra: map[string]any{codexFingerprintModeExtraKey: "session"},
})
require.NoError(t, err)
require.Equal(t, testCodexFingerprintSeed, requireValidCodexFingerprintSeed(t, reenabled.Extra))
}
func TestAdminUpdateAccountExtraStripsSeedAndLeavesAtomicEnsureToRepository(t *testing.T) {
accountID := int64(204)
repo := &upstreamBillingProbeAccountRepo{accounts: map[int64]*Account{
accountID: {
ID: accountID,
Platform: PlatformOpenAI,
Type: AccountTypeOAuth,
Extra: map[string]any{},
},
}}
err := (&adminServiceImpl{accountRepo: repo}).UpdateAccountExtra(context.Background(), accountID, map[string]any{
codexFingerprintModeExtraKey: "device",
codexFingerprintSeedExtraKey: userSuppliedCodexFingerprintSeed,
})
require.NoError(t, err)
require.Len(t, repo.updates[accountID], 1)
require.Equal(t, "device", repo.updates[accountID][0][codexFingerprintModeExtraKey])
require.NotContains(t, repo.updates[accountID][0], codexFingerprintSeedExtraKey)
}
func TestBulkUpdateAccountsDoesNotPrewriteCodexSeed(t *testing.T) {
repo := &upstreamBillingProbeAccountRepo{}
result, err := (&adminServiceImpl{accountRepo: repo}).BulkUpdateAccounts(context.Background(), &BulkUpdateAccountsInput{
AccountIDs: []int64{301, 302},
Extra: map[string]any{
codexFingerprintModeExtraKey: "session",
codexFingerprintSeedExtraKey: userSuppliedCodexFingerprintSeed,
},
})
require.NoError(t, err)
require.Equal(t, 2, result.Success)
require.Empty(t, repo.updates, "bulk enable must not loop through UpdateExtra before BulkUpdate")
require.Len(t, repo.bulkUpdates, 1)
require.True(t, repo.bulkUpdates[0].EnsureCodexFingerprintSeed)
require.Equal(t, "session", repo.bulkUpdates[0].Extra[codexFingerprintModeExtraKey])
require.NotContains(t, repo.bulkUpdates[0].Extra, codexFingerprintSeedExtraKey)
}
type codexSeedDuplicateRepo struct {
*upstreamBillingProbeAccountRepo
}
func (r *codexSeedDuplicateRepo) CreateWithAccountGroups(ctx context.Context, account *Account, _ []AccountGroup) error {
return r.Create(ctx, account)
}
func TestDuplicateAccountDoesNotCopyCodexFingerprintSeed(t *testing.T) {
ctx := context.Background()
repo := &codexSeedDuplicateRepo{upstreamBillingProbeAccountRepo: &upstreamBillingProbeAccountRepo{accounts: make(map[int64]*Account)}}
svc := &adminServiceImpl{accountRepo: repo, accountDuplicateRepo: repo}
source := &Account{
Name: "source",
Platform: PlatformOpenAI,
Type: AccountTypeAPIKey,
Extra: map[string]any{
codexFingerprintModeExtraKey: "session",
codexFingerprintSeedExtraKey: testCodexFingerprintSeed,
},
}
require.NoError(t, repo.Create(ctx, source))
duplicate, err := svc.DuplicateAccount(ctx, source.ID, "admin:1", "")
require.NoError(t, err)
require.NotEqual(t, source.ID, duplicate.ID)
require.NotContains(t, duplicate.Extra, codexFingerprintSeedExtraKey)
require.Equal(t, "session", duplicate.Extra[codexFingerprintModeExtraKey])
}
func TestDuplicateCreatePathMintsFreshSeedWhenEligible(t *testing.T) {
extra, err := duplicateAccountExtra(map[string]any{
codexFingerprintModeExtraKey: "session",
codexFingerprintSeedExtraKey: testCodexFingerprintSeed,
})
require.NoError(t, err)
account, err := buildAccountForCreate(&CreateAccountInput{
Name: "eligible-copy",
Platform: PlatformOpenAI,
Type: AccountTypeOAuth,
Extra: extra,
}, extra)
require.NoError(t, err)
require.NotEqual(t, testCodexFingerprintSeed, requireValidCodexFingerprintSeed(t, account.Extra))
require.Equal(t, "session", account.Extra[codexFingerprintModeExtraKey])
}
func TestAccountServiceCreateAndUpdateCodexSeedLifecycle(t *testing.T) {
ctx := context.Background()
repo := &upstreamBillingProbeAccountRepo{accounts: make(map[int64]*Account)}
svc := NewAccountService(repo, nil)
created, err := svc.Create(ctx, CreateAccountRequest{
Name: "legacy-create",
Platform: PlatformOpenAI,
Type: AccountTypeOAuth,
Extra: map[string]any{
codexFingerprintModeExtraKey: "session",
codexFingerprintSeedExtraKey: userSuppliedCodexFingerprintSeed,
},
})
require.NoError(t, err)
createdSeed := requireValidCodexFingerprintSeed(t, created.Extra)
require.NotEqual(t, userSuppliedCodexFingerprintSeed, createdSeed)
updateSeed := userSuppliedCodexFingerprintSeed
updated, err := svc.Update(ctx, created.ID, UpdateAccountRequest{
Extra: &map[string]any{
codexFingerprintModeExtraKey: "full",
codexFingerprintSeedExtraKey: updateSeed,
},
})
require.NoError(t, err)
require.Equal(t, createdSeed, requireValidCodexFingerprintSeed(t, updated.Extra))
require.Equal(t, "full", updated.Extra[codexFingerprintModeExtraKey])
}