| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- //go:build unit
- package admin
- import (
- "bytes"
- "encoding/json"
- "net/http"
- "net/http/httptest"
- "testing"
- "github.com/Wei-Shaw/sub2api/internal/config"
- "github.com/Wei-Shaw/sub2api/internal/pkg/response"
- "github.com/Wei-Shaw/sub2api/internal/service"
- "github.com/gin-gonic/gin"
- "github.com/stretchr/testify/require"
- )
- func TestDiffSettings_DetectsGlobalPlatformQuotaChange(t *testing.T) {
- five := 5.0
- ten := 10.0
- before := &service.SystemSettings{
- DefaultPlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{
- "anthropic": {DailyLimitUSD: &five},
- },
- }
- after := &service.SystemSettings{
- DefaultPlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{
- "anthropic": {DailyLimitUSD: &ten},
- },
- }
- changed := diffSettings(before, after, nil, nil, UpdateSettingsRequest{})
- found := false
- for _, key := range changed {
- if key == service.SettingKeyDefaultPlatformQuotas {
- found = true
- break
- }
- }
- if !found {
- t.Errorf("expected change detection for default platform quotas, got %v", changed)
- }
- }
- func TestDiffSettings_NoChangeWhenEqual(t *testing.T) {
- five := 5.0
- before := &service.SystemSettings{
- DefaultPlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{
- "anthropic": {DailyLimitUSD: &five},
- },
- }
- after := &service.SystemSettings{
- DefaultPlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{
- "anthropic": {DailyLimitUSD: &five},
- },
- }
- changed := diffSettings(before, after, nil, nil, UpdateSettingsRequest{})
- for _, key := range changed {
- if key == service.SettingKeyDefaultPlatformQuotas {
- t.Error("equal values should not be detected as changed")
- }
- }
- }
- func TestSettingsAuditRequestDoesNotInheritStoredTencentSecrets(t *testing.T) {
- req := UpdateSettingsRequest{
- TencentCaptchaAppSecretKey: " ",
- TencentCaptchaCloudSecretID: "\t",
- TencentCaptchaCloudSecretKey: "\n",
- }
- auditReq := settingsAuditRequest(req)
- req.TencentCaptchaAppSecretKey = "stored-app-secret"
- req.TencentCaptchaCloudSecretID = "stored-secret-id"
- req.TencentCaptchaCloudSecretKey = "stored-secret-key"
- require.Empty(t, auditReq.TencentCaptchaAppSecretKey)
- require.Empty(t, auditReq.TencentCaptchaCloudSecretID)
- require.Empty(t, auditReq.TencentCaptchaCloudSecretKey)
- }
- func TestDiffSettings_DetectsCompactHomeChange(t *testing.T) {
- changed := diffSettings(
- &service.SystemSettings{},
- &service.SystemSettings{CompactHomeEnabled: true},
- nil,
- nil,
- UpdateSettingsRequest{},
- )
- require.Contains(t, changed, service.SettingKeyCompactHomeEnabled)
- }
- func TestEqualNullableFloat(t *testing.T) {
- five := 5.0
- five2 := 5.0
- ten := 10.0
- cases := []struct {
- a, b *float64
- want bool
- }{
- {nil, nil, true},
- {&five, nil, false},
- {nil, &five, false},
- {&five, &five2, true},
- {&five, &ten, false},
- }
- for _, c := range cases {
- if got := equalNullableFloat(c.a, c.b); got != c.want {
- t.Errorf("equalNullableFloat(%v, %v) = %v, want %v", c.a, c.b, got, c.want)
- }
- }
- }
- func TestEqualPlatformQuotaSettings_DetectsPerWindowChange(t *testing.T) {
- five := 5.0
- ten := 10.0
- before := map[string]*service.DefaultPlatformQuotaSetting{
- "anthropic": {DailyLimitUSD: &five},
- }
- after := map[string]*service.DefaultPlatformQuotaSetting{
- "anthropic": {DailyLimitUSD: &ten},
- }
- if equalPlatformQuotaSettings(before, after) {
- t.Error("expected unequal")
- }
- }
- func TestAppendAuthSourceDefaultChanges_DetectsPerWindow(t *testing.T) {
- five := 5.0
- ten := 10.0
- before := &service.AuthSourceDefaultSettings{
- LinuxDo: service.ProviderDefaultGrantSettings{
- PlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{
- "anthropic": {DailyLimitUSD: &five},
- },
- },
- }
- after := &service.AuthSourceDefaultSettings{
- LinuxDo: service.ProviderDefaultGrantSettings{
- PlatformQuotas: map[string]*service.DefaultPlatformQuotaSetting{
- "anthropic": {DailyLimitUSD: &ten},
- },
- },
- }
- changed := appendAuthSourceDefaultChanges([]string{}, before, after)
- // 改动 B5:整体替换语义,审计 log 发单个 JSON key,而非展开 84 个扁平 key。
- key := service.SettingKeyAuthSourcePlatformQuotas("linuxdo")
- found := false
- for _, k := range changed {
- if k == key {
- found = true
- break
- }
- }
- if !found {
- t.Errorf("expected %q in changed, got %v", key, changed)
- }
- }
- // TestSettingHandler_AuthSourcePlatformQuotas_PutGetRoundTrip 验证 Bug A 修复:
- // PUT 发 auth_source_default_email_platform_quotas,GET 能读回相同值(端到端往返)。
- func TestSettingHandler_AuthSourcePlatformQuotas_PutGetRoundTrip(t *testing.T) {
- gin.SetMode(gin.TestMode)
- repo := &settingHandlerRepoStub{
- values: map[string]string{
- service.SettingKeyPromoCodeEnabled: "true",
- },
- }
- svc := service.NewSettingService(repo, &config.Config{Default: config.DefaultConfig{UserConcurrency: 5}})
- handler := NewSettingHandler(svc, nil, nil, nil, nil, nil, nil)
- // PUT:发 email platform quota(openai monthly=20)
- putBody := map[string]any{
- "auth_source_default_email_platform_quotas": map[string]any{
- "openai": map[string]any{
- "monthly": 20,
- },
- },
- }
- rawBody, err := json.Marshal(putBody)
- require.NoError(t, err)
- rec := httptest.NewRecorder()
- c, _ := gin.CreateTestContext(rec)
- c.Request = httptest.NewRequest(http.MethodPut, "/api/v1/admin/settings", bytes.NewReader(rawBody))
- c.Request.Header.Set("Content-Type", "application/json")
- handler.UpdateSettings(c)
- require.Equal(t, http.StatusOK, rec.Code)
- // 验证 DB 中写入了 JSON key
- jsonKey := service.SettingKeyAuthSourcePlatformQuotas("email")
- require.NotEmpty(t, repo.values[jsonKey], "expected JSON key to be written to DB")
- // GET:验证响应中 auth_source_default_email_platform_quotas.openai.monthly = 20
- rec2 := httptest.NewRecorder()
- c2, _ := gin.CreateTestContext(rec2)
- c2.Request = httptest.NewRequest(http.MethodGet, "/api/v1/admin/settings", nil)
- handler.GetSettings(c2)
- require.Equal(t, http.StatusOK, rec2.Code)
- var resp response.Response
- require.NoError(t, json.Unmarshal(rec2.Body.Bytes(), &resp))
- data, ok := resp.Data.(map[string]any)
- require.True(t, ok)
- emailPQ, ok := data["auth_source_default_email_platform_quotas"].(map[string]any)
- require.True(t, ok, "expected auth_source_default_email_platform_quotas to be a map")
- openaiPQ, ok := emailPQ["openai"].(map[string]any)
- require.True(t, ok, "expected openai entry in email platform quotas")
- monthly, ok := openaiPQ["monthly"].(float64)
- require.True(t, ok, "expected monthly to be float64")
- require.Equal(t, float64(20), monthly, "expected openai monthly=20")
- }
|