feat: publish v1.0.0-rc.36-custom.1
Publish Docker image (Multi-arch) / Build & push (amd64) (push) Failing after 9m20s
Release (Linux, macOS, Windows) / Linux Release (push) Failing after 55m7s
Publish Docker image (Multi-arch) / Build & push (arm64) (push) Canceled after 0s
Release (Linux, macOS, Windows) / macOS Release (push) Canceled after 0s
Release (Linux, macOS, Windows) / Windows Release (push) Canceled after 0s
Publish Docker image (Multi-arch) / Create multi-arch manifests (push) Canceled after 0s
Publish Docker image (Multi-arch) / Build & push (amd64) (push) Failing after 9m20s
Release (Linux, macOS, Windows) / Linux Release (push) Failing after 55m7s
Publish Docker image (Multi-arch) / Build & push (arm64) (push) Canceled after 0s
Release (Linux, macOS, Windows) / macOS Release (push) Canceled after 0s
Release (Linux, macOS, Windows) / Windows Release (push) Canceled after 0s
Publish Docker image (Multi-arch) / Create multi-arch manifests (push) Canceled after 0s
This commit is contained in:
commit
bb7968b612
2381 files changed
+551494
No files matched your search
@@ -0,0 +1,203 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/QuantumNous/new-api/common"
|
||||
"github.com/QuantumNous/new-api/model"
|
||||
"github.com/QuantumNous/new-api/setting/operation_setting"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/glebarez/sqlite"
|
||||
"github.com/shopspring/decimal"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
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,
|
||||
wantQuota: 2_147_500_000,
|
||||
},
|
||||
{
|
||||
name: "token amount preserves settlement truncation",
|
||||
displayType: operation_setting.QuotaDisplayTypeTokens,
|
||||
amount: 2_147_500_000,
|
||||
wantQuota: 2_147_500_000,
|
||||
},
|
||||
{
|
||||
name: "token amount above legacy int32 range",
|
||||
displayType: operation_setting.QuotaDisplayTypeTokens,
|
||||
amount: 4_294_500_000,
|
||||
wantQuota: 4_294_500_000,
|
||||
},
|
||||
}
|
||||
|
||||
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.MaxWalletQuota).
|
||||
Div(decimal.NewFromFloat(common.QuotaPerUnit)).
|
||||
Floor().IntPart()
|
||||
|
||||
_, err := validateTopUpQuota(maxAmount)
|
||||
require.NoError(t, err)
|
||||
_, err = validateTopUpQuota(maxAmount + 1)
|
||||
require.EqualError(t, err, fmt.Sprintf("单笔充值数量不能大于 %d", maxAmount))
|
||||
}
|
||||
|
||||
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)
|
||||
maxAmount := decimal.NewFromInt(common.MaxWalletQuota).
|
||||
Div(decimal.NewFromFloat(common.QuotaPerUnit)).
|
||||
Floor().IntPart()
|
||||
ctx.Request = httptest.NewRequest(
|
||||
http.MethodPost,
|
||||
"/api/user/amount",
|
||||
strings.NewReader(fmt.Sprintf(`{"amount":%d}`, maxAmount+1)),
|
||||
)
|
||||
ctx.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
RequestAmount(ctx)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
assert.JSONEq(t, fmt.Sprintf(`{"message":"error","data":"单笔充值数量不能大于 %d"}`, maxAmount), recorder.Body.String())
|
||||
}
|
||||
|
||||
func TestRequestAmountRejectsTopUpThatWouldOverflowWallet(t *testing.T) {
|
||||
oldQuotaPerUnit := common.QuotaPerUnit
|
||||
oldDisplayType := operation_setting.GetGeneralSetting().QuotaDisplayType
|
||||
oldDB := model.DB
|
||||
common.QuotaPerUnit = 500000
|
||||
operation_setting.GetGeneralSetting().QuotaDisplayType = operation_setting.QuotaDisplayTypeUSD
|
||||
|
||||
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, db.AutoMigrate(&model.User{}))
|
||||
model.DB = db
|
||||
t.Cleanup(func() {
|
||||
common.QuotaPerUnit = oldQuotaPerUnit
|
||||
operation_setting.GetGeneralSetting().QuotaDisplayType = oldDisplayType
|
||||
model.DB = oldDB
|
||||
sqlDB, dbErr := db.DB()
|
||||
if dbErr == nil {
|
||||
require.NoError(t, sqlDB.Close())
|
||||
}
|
||||
})
|
||||
|
||||
require.NoError(t, model.DB.Create(&model.User{
|
||||
Id: 42,
|
||||
Username: "topup_capacity_user",
|
||||
Quota: common.MaxWalletQuota - 100_000,
|
||||
Status: common.UserStatusEnabled,
|
||||
}).Error)
|
||||
|
||||
gin.SetMode(gin.TestMode)
|
||||
recorder := httptest.NewRecorder()
|
||||
ctx, _ := gin.CreateTestContext(recorder)
|
||||
ctx.Set("id", 42)
|
||||
ctx.Request = httptest.NewRequest(
|
||||
http.MethodPost,
|
||||
"/api/user/amount",
|
||||
strings.NewReader(`{"amount":1}`),
|
||||
)
|
||||
ctx.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
RequestAmount(ctx)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
assert.JSONEq(t, `{"message":"error","data":"top-up quota limit exceeded"}`, recorder.Body.String())
|
||||
}
|
||||
|
||||
func TestValidateCreditedQuotaRejectsOverflow(t *testing.T) {
|
||||
_, err := validateCreditedQuota(decimal.NewFromInt(int64(common.MaxWalletQuota / 2)))
|
||||
require.NoError(t, err)
|
||||
_, err = validateCreditedQuota(decimal.Zero)
|
||||
require.EqualError(t, err, "充值额度必须大于 0")
|
||||
_, err = validateCreditedQuota(decimal.NewFromInt(common.MaxWalletQuota + 1))
|
||||
require.EqualError(
|
||||
t,
|
||||
err,
|
||||
"充值额度超出系统可表示范围",
|
||||
)
|
||||
}
|
||||
|
||||
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))
|
||||
})
|
||||
|
||||
_, err := validateCreditedQuota(getStripeCreditedQuota(2147, "vip"))
|
||||
require.NoError(t, err)
|
||||
_, err = validateCreditedQuota(getStripeCreditedQuota(2148, "vip"))
|
||||
require.NoError(t, err)
|
||||
_, err = validateCreditedQuota(getStripeCreditedQuota(int64(common.MaxWalletQuota), "vip"))
|
||||
require.Error(t, err)
|
||||
|
||||
require.NoError(t, common.UpdateTopupGroupRatioByJSONString(`{"free":0}`))
|
||||
assert.True(t, decimal.NewFromInt(500000).Equal(getStripeCreditedQuota(1, "free")))
|
||||
}
|
||||
Reference in new issue
Block a user