package controller import ( "net/http" "net/http/httptest" "strings" "testing" "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/setting/operation_setting" "github.com/gin-gonic/gin" "github.com/shopspring/decimal" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestTopUpQuotaValidation(t *testing.T) { oldQuotaPerUnit := common.QuotaPerUnit oldDisplayType := operation_setting.GetGeneralSetting().QuotaDisplayType common.QuotaPerUnit = 500000 t.Cleanup(func() { common.QuotaPerUnit = oldQuotaPerUnit operation_setting.GetGeneralSetting().QuotaDisplayType = oldDisplayType }) testCases := []struct { name string displayType string amount int64 wantQuota int wantErr bool }{ { name: "currency amount below limit", displayType: operation_setting.QuotaDisplayTypeUSD, amount: 4294, wantQuota: 2_147_000_000, }, { name: "currency amount above limit", displayType: operation_setting.QuotaDisplayTypeUSD, amount: 4295, wantErr: true, }, { name: "token amount preserves settlement truncation", displayType: operation_setting.QuotaDisplayTypeTokens, amount: common.MaxQuota, wantQuota: 2_147_000_000, }, { name: "token amount above settlement limit", displayType: operation_setting.QuotaDisplayTypeTokens, amount: 2_147_500_000, wantErr: true, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { operation_setting.GetGeneralSetting().QuotaDisplayType = tc.displayType quota, err := getTopUpQuota(tc.amount) if tc.wantErr { require.Error(t, err) return } require.NoError(t, err) assert.Equal(t, tc.wantQuota, quota) }) } } func TestValidateTopUpQuotaReturnsMaximumAmount(t *testing.T) { oldQuotaPerUnit := common.QuotaPerUnit oldDisplayType := operation_setting.GetGeneralSetting().QuotaDisplayType common.QuotaPerUnit = 500000 operation_setting.GetGeneralSetting().QuotaDisplayType = operation_setting.QuotaDisplayTypeUSD t.Cleanup(func() { common.QuotaPerUnit = oldQuotaPerUnit operation_setting.GetGeneralSetting().QuotaDisplayType = oldDisplayType }) maxAmount := decimal.NewFromInt(common.MaxQuota - 1). Div(decimal.NewFromFloat(common.QuotaPerUnit)). Floor().IntPart() require.NoError(t, validateTopUpQuota(maxAmount)) err := validateTopUpQuota(maxAmount + 1) require.EqualError(t, err, "单笔充值数量不能大于 4294") } func TestRequestAmountRejectsTopUpThatCannotBeSettled(t *testing.T) { oldQuotaPerUnit := common.QuotaPerUnit oldDisplayType := operation_setting.GetGeneralSetting().QuotaDisplayType common.QuotaPerUnit = 500000 operation_setting.GetGeneralSetting().QuotaDisplayType = operation_setting.QuotaDisplayTypeUSD t.Cleanup(func() { common.QuotaPerUnit = oldQuotaPerUnit operation_setting.GetGeneralSetting().QuotaDisplayType = oldDisplayType }) gin.SetMode(gin.TestMode) recorder := httptest.NewRecorder() ctx, _ := gin.CreateTestContext(recorder) ctx.Request = httptest.NewRequest( http.MethodPost, "/api/user/amount", strings.NewReader(`{"amount":4295}`), ) ctx.Request.Header.Set("Content-Type", "application/json") RequestAmount(ctx) assert.Equal(t, http.StatusOK, recorder.Code) assert.JSONEq(t, `{"message":"error","data":"单笔充值数量不能大于 4294"}`, recorder.Body.String()) } func TestValidateCreditedQuotaRejectsOverflow(t *testing.T) { require.NoError(t, validateCreditedQuota(decimal.NewFromInt(common.MaxQuota-1))) require.EqualError(t, validateCreditedQuota(decimal.Zero), "充值额度必须大于 0") require.EqualError( t, validateCreditedQuota(decimal.NewFromInt(common.MaxQuota)), "充值额度超出系统可表示范围", ) } func TestStripeCreditedQuotaIncludesGroupRatio(t *testing.T) { oldQuotaPerUnit := common.QuotaPerUnit oldTopupGroupRatio := common.TopupGroupRatio2JSONString() common.QuotaPerUnit = 500000 require.NoError(t, common.UpdateTopupGroupRatioByJSONString(`{"vip":2}`)) t.Cleanup(func() { common.QuotaPerUnit = oldQuotaPerUnit require.NoError(t, common.UpdateTopupGroupRatioByJSONString(oldTopupGroupRatio)) }) require.NoError(t, validateCreditedQuota(getStripeCreditedQuota(2147, "vip"))) require.Error(t, validateCreditedQuota(getStripeCreditedQuota(2148, "vip"))) require.NoError(t, common.UpdateTopupGroupRatioByJSONString(`{"free":0}`)) assert.True(t, decimal.NewFromInt(500000).Equal(getStripeCreditedQuota(1, "free"))) }