补充兑换码开通会员集成测试场景

This commit is contained in:
hello-dd-code
2026-02-28 16:30:34 +08:00
parent 01dd0ccbbe
commit 48f6e9dcad
4 changed files with 197 additions and 0 deletions
@@ -0,0 +1,154 @@
package service
import (
"context"
"errors"
"testing"
"time"
membershipmodel "wx_service/internal/membership/model"
usermodel "wx_service/internal/model"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func setupRedeemTestDB(t *testing.T) *gorm.DB {
t.Helper()
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
t.Fatalf("open sqlite: %v", err)
}
if err := db.AutoMigrate(
&membershipmodel.MembershipRedeemCode{},
&membershipmodel.MembershipRedemption{},
&usermodel.UserMembership{},
); err != nil {
t.Fatalf("auto migrate: %v", err)
}
return db
}
func seedRedeemCode(t *testing.T, db *gorm.DB, plainCode string, durationDays int, expiresAt *time.Time, maxUses int, status string) membershipmodel.MembershipRedeemCode {
t.Helper()
code := normalizeCode(plainCode)
record := membershipmodel.MembershipRedeemCode{
CodeHash: hashCode(code),
CodeSuffix: suffixOf(code, 6),
Plan: "month",
DurationDays: durationDays,
ExpiresAt: expiresAt,
MaxUses: maxUses,
UsedUses: 0,
Status: status,
}
if err := db.Create(&record).Error; err != nil {
t.Fatalf("seed redeem code: %v", err)
}
return record
}
func TestRedeemCodeServiceRedeemSuccessAndRepeat(t *testing.T) {
t.Parallel()
db := setupRedeemTestDB(t)
svc := NewRedeemCodeService(db, "")
user := &usermodel.User{ID: 1, MiniProgramID: 10}
code := "TEST-CODE-001"
seedRedeemCode(t, db, code, 30, nil, 1, "active")
res, err := svc.Redeem(context.Background(), user, code, "127.0.0.1", "ut")
if err != nil {
t.Fatalf("redeem success: %v", err)
}
if res == nil || res.Extended {
t.Fatalf("first redeem should create membership and extended=false")
}
var membership usermodel.UserMembership
if err := db.Where("mini_program_id = ? AND user_id = ?", user.MiniProgramID, user.ID).First(&membership).Error; err != nil {
t.Fatalf("query membership: %v", err)
}
if membership.Status != "active" {
t.Fatalf("membership status=%s, want=active", membership.Status)
}
var storedCode membershipmodel.MembershipRedeemCode
if err := db.Where("code_hash = ?", hashCode(normalizeCode(code))).First(&storedCode).Error; err != nil {
t.Fatalf("query redeem code: %v", err)
}
if storedCode.UsedUses != 1 {
t.Fatalf("used_uses=%d, want=1", storedCode.UsedUses)
}
_, err = svc.Redeem(context.Background(), user, code, "127.0.0.1", "ut")
if !errors.Is(err, ErrRedeemCodeUsedUp) {
t.Fatalf("repeat redeem err=%v, want ErrRedeemCodeUsedUp", err)
}
}
func TestRedeemCodeServiceRedeemExpiredCode(t *testing.T) {
t.Parallel()
db := setupRedeemTestDB(t)
svc := NewRedeemCodeService(db, "")
user := &usermodel.User{ID: 2, MiniProgramID: 10}
expired := time.Now().Add(-1 * time.Hour)
code := "TEST-CODE-EXPIRED"
seedRedeemCode(t, db, code, 30, &expired, 1, "active")
_, err := svc.Redeem(context.Background(), user, code, "127.0.0.1", "ut")
if !errors.Is(err, ErrRedeemCodeExpired) {
t.Fatalf("redeem expired err=%v, want ErrRedeemCodeExpired", err)
}
}
func TestRedeemCodeServiceRedeemInvalidCode(t *testing.T) {
t.Parallel()
db := setupRedeemTestDB(t)
svc := NewRedeemCodeService(db, "")
user := &usermodel.User{ID: 3, MiniProgramID: 10}
_, err := svc.Redeem(context.Background(), user, "NOT-FOUND-CODE", "127.0.0.1", "ut")
if !errors.Is(err, ErrRedeemCodeInvalid) {
t.Fatalf("redeem invalid err=%v, want ErrRedeemCodeInvalid", err)
}
}
func TestRedeemCodeServiceRedeemExtendsActiveMembership(t *testing.T) {
t.Parallel()
db := setupRedeemTestDB(t)
svc := NewRedeemCodeService(db, "")
user := &usermodel.User{ID: 4, MiniProgramID: 10}
firstCode := "TEST-CODE-A"
secondCode := "TEST-CODE-B"
seedRedeemCode(t, db, firstCode, 10, nil, 1, "active")
seedRedeemCode(t, db, secondCode, 15, nil, 1, "active")
firstRes, err := svc.Redeem(context.Background(), user, firstCode, "127.0.0.1", "ut")
if err != nil {
t.Fatalf("first redeem: %v", err)
}
secondRes, err := svc.Redeem(context.Background(), user, secondCode, "127.0.0.1", "ut")
if err != nil {
t.Fatalf("second redeem: %v", err)
}
if secondRes == nil || !secondRes.Extended {
t.Fatalf("second redeem should extend existing membership")
}
if !secondRes.EndsAt.After(firstRes.EndsAt) {
t.Fatalf("second ends_at=%s should be after first ends_at=%s", secondRes.EndsAt, firstRes.EndsAt)
}
}