new-api/controller/promo_code_user_test.go
zizi 0ff2fff94d feat: add promo code management and payment settings
Add default-web promo code CRUD, user/channel concurrency controls, and domestic Alipay/Wxpay billing settings. Harden promo code validation and preserve explicit zero concurrency limits with backend regression coverage.
2026-05-20 21:45:28 +08:00

98 lines
2.8 KiB
Go

package controller
import (
"net/http"
"testing"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/model"
"github.com/stretchr/testify/require"
)
type promoCodeValidateAPIResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
Data validatePromoCodeResponse `json:"data"`
}
func setupPromoCodeControllerTestDB(t *testing.T) {
t.Helper()
db := openTokenControllerTestDB(t)
require.NoError(t, db.AutoMigrate(&model.PromoCode{}, &model.PromoCodeUsage{}))
t.Cleanup(func() {
db.Exec("DELETE FROM promo_code_usages")
db.Exec("DELETE FROM promo_codes")
})
}
func validatePromoCodeForTest(t *testing.T, code string, amount int, userID int) promoCodeValidateAPIResponse {
t.Helper()
ctx, recorder := newAuthenticatedContext(t, http.MethodPost, "/api/user/promo-codes/validate", validatePromoCodeRequest{
Code: code,
Amount: amount,
}, userID)
ValidatePromoCode(ctx)
var response promoCodeValidateAPIResponse
require.NoError(t, common.Unmarshal(recorder.Body.Bytes(), &response))
return response
}
func TestValidatePromoCodeReturnsGenericInvalidReason(t *testing.T) {
setupPromoCodeControllerTestDB(t)
promoCode := &model.PromoCode{
Code: "PROMO_MIN",
BonusAmount: 100,
MaxUses: 0,
MinRechargeAmount: 50,
Status: 1,
}
require.NoError(t, promoCode.Insert())
notFound := validatePromoCodeForTest(t, "missing", 100, 1001)
require.True(t, notFound.Success)
require.False(t, notFound.Data.Valid)
require.Equal(t, invalidPromoCodeReason, notFound.Data.Reason)
belowMinimum := validatePromoCodeForTest(t, "PROMO_MIN", 10, 1001)
require.True(t, belowMinimum.Success)
require.False(t, belowMinimum.Data.Valid)
require.Equal(t, invalidPromoCodeReason, belowMinimum.Data.Reason)
}
func TestValidatePromoCodeRejectsInvalidSyntaxWithoutDetailedReason(t *testing.T) {
setupPromoCodeControllerTestDB(t)
response := validatePromoCodeForTest(t, "invalid code!", 100, 1001)
require.True(t, response.Success)
require.False(t, response.Data.Valid)
require.Equal(t, invalidPromoCodeReason, response.Data.Reason)
require.Zero(t, response.Data.PromoCodeId)
}
func TestValidatePromoCodeReturnsValidPromoCodeDetails(t *testing.T) {
setupPromoCodeControllerTestDB(t)
promoCode := &model.PromoCode{
Code: "PROMO_OK",
BonusAmount: 100,
MaxUses: 0,
MinRechargeAmount: 50,
Status: 1,
}
require.NoError(t, promoCode.Insert())
response := validatePromoCodeForTest(t, "promo_ok", 50, 1001)
require.True(t, response.Success)
require.True(t, response.Data.Valid)
require.Empty(t, response.Data.Reason)
require.Equal(t, promoCode.Id, response.Data.PromoCodeId)
require.Equal(t, 100, response.Data.BonusAmount)
require.Equal(t, "PROMO_OK", response.Data.Code)
}