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) }