This commit is contained in:
parent
68c7b0a8ec
commit
ac57272018
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -440,6 +441,165 @@ func TestHandleCommission_GiftDaysRecognizesUnlimitedSubscription(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleCommission_IdempotentForRepeatedActivation(t *testing.T) {
|
||||
logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{
|
||||
ReferralPercentage: 10,
|
||||
OnlyFirstPurchase: false,
|
||||
GiftDays: 2,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
referee := seedUser(t, db, 0, false)
|
||||
referer := seedUser(t, db, 0, false)
|
||||
referee.RefererId = referer.Id
|
||||
|
||||
baseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second)
|
||||
refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire)
|
||||
orderInfo := &order.Order{
|
||||
OrderNo: "ORD-IDEMPOTENT-001",
|
||||
Type: OrderTypeSubscribe,
|
||||
IsNew: true,
|
||||
Amount: 100,
|
||||
FeeAmount: 0,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
logic.handleCommission(context.Background(), referee, orderInfo)
|
||||
logic.handleCommission(context.Background(), referee, orderInfo)
|
||||
|
||||
assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 2)
|
||||
assertUserCommission(t, db, referer.Id, 10)
|
||||
assertLogCountForOrder(t, db, modelLog.TypeCommission.Uint8(), orderInfo.OrderNo, 1)
|
||||
assertLogCountForOrder(t, db, modelLog.TypeGift.Uint8(), orderInfo.OrderNo, 1)
|
||||
}
|
||||
|
||||
func TestHandleCommission_NoActiveSubscriptionWritesSkippedGiftLog(t *testing.T) {
|
||||
logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{
|
||||
ReferralPercentage: 10,
|
||||
OnlyFirstPurchase: false,
|
||||
GiftDays: 2,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
referee := seedUser(t, db, 0, false)
|
||||
referer := seedUser(t, db, 0, false)
|
||||
referee.RefererId = referer.Id
|
||||
orderInfo := &order.Order{
|
||||
OrderNo: "ORD-SKIPPED-001",
|
||||
Type: OrderTypeSubscribe,
|
||||
IsNew: true,
|
||||
Amount: 100,
|
||||
FeeAmount: 0,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
logic.handleCommission(context.Background(), referee, orderInfo)
|
||||
|
||||
assertUserCommission(t, db, referer.Id, 10)
|
||||
assertLogCountForOrder(t, db, modelLog.TypeCommission.Uint8(), orderInfo.OrderNo, 1)
|
||||
assertLogCountForOrder(t, db, modelLog.TypeGift.Uint8(), orderInfo.OrderNo, 1)
|
||||
assertGiftLogRemarkContains(t, db, orderInfo.OrderNo, "skipped: no active subscription")
|
||||
}
|
||||
|
||||
func TestHandleCommission_GiftDaysZeroDoesNotWriteGiftLog(t *testing.T) {
|
||||
logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{
|
||||
ReferralPercentage: 10,
|
||||
OnlyFirstPurchase: false,
|
||||
GiftDays: 0,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
referee := seedUser(t, db, 0, false)
|
||||
referer := seedUser(t, db, 0, false)
|
||||
referee.RefererId = referer.Id
|
||||
baseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second)
|
||||
refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire)
|
||||
orderInfo := &order.Order{
|
||||
OrderNo: "ORD-GIFT-ZERO-001",
|
||||
Type: OrderTypeSubscribe,
|
||||
IsNew: true,
|
||||
Amount: 100,
|
||||
FeeAmount: 0,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
logic.handleCommission(context.Background(), referee, orderInfo)
|
||||
|
||||
assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 0)
|
||||
assertUserCommission(t, db, referer.Id, 10)
|
||||
assertLogCountForOrder(t, db, modelLog.TypeCommission.Uint8(), orderInfo.OrderNo, 1)
|
||||
assertLogCountForOrder(t, db, modelLog.TypeGift.Uint8(), orderInfo.OrderNo, 0)
|
||||
}
|
||||
|
||||
func TestHandleCommission_GlobalOnlyFirstPurchaseBlocksCommissionAndGiftForNonFirstOrder(t *testing.T) {
|
||||
logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{
|
||||
ReferralPercentage: 10,
|
||||
OnlyFirstPurchase: true,
|
||||
GiftDays: 2,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
referee := seedUser(t, db, 0, false)
|
||||
referer := seedUser(t, db, 0, false)
|
||||
referee.RefererId = referer.Id
|
||||
baseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second)
|
||||
refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire)
|
||||
orderInfo := &order.Order{
|
||||
OrderNo: "ORD-NONFIRST-GLOBAL-001",
|
||||
Type: OrderTypeRenewal,
|
||||
IsNew: false,
|
||||
Amount: 100,
|
||||
FeeAmount: 0,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
logic.handleCommission(context.Background(), referee, orderInfo)
|
||||
|
||||
assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 0)
|
||||
assertUserCommission(t, db, referer.Id, 0)
|
||||
assertLogCountForOrder(t, db, modelLog.TypeCommission.Uint8(), orderInfo.OrderNo, 0)
|
||||
assertLogCountForOrder(t, db, modelLog.TypeGift.Uint8(), orderInfo.OrderNo, 0)
|
||||
}
|
||||
|
||||
func TestHandleCommission_BothFamilySidesUseCorrectGiftOwners(t *testing.T) {
|
||||
logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{
|
||||
ReferralPercentage: 0,
|
||||
OnlyFirstPurchase: false,
|
||||
GiftDays: 2,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
refereeOwner := seedUser(t, db, 0, false)
|
||||
referee := seedUser(t, db, 0, false)
|
||||
refererOwner := seedUser(t, db, 0, false)
|
||||
referer := seedUser(t, db, 0, false)
|
||||
seedFamily(t, db, refereeOwner.Id, referee.Id)
|
||||
seedFamily(t, db, refererOwner.Id, referer.Id)
|
||||
referee.RefererId = referer.Id
|
||||
|
||||
refereeOwnerBaseExpire := time.Now().Add(72 * time.Hour).Truncate(time.Second)
|
||||
refererOwnerBaseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second)
|
||||
refereeOwnerSub := seedActiveSubscribe(t, db, refereeOwner.Id, refereeOwnerBaseExpire)
|
||||
refererOwnerSub := seedActiveSubscribe(t, db, refererOwner.Id, refererOwnerBaseExpire)
|
||||
orderInfo := &order.Order{
|
||||
OrderNo: "ORD-BOTH-FAMILIES-001",
|
||||
Type: OrderTypeSubscribe,
|
||||
IsNew: true,
|
||||
Amount: 100,
|
||||
FeeAmount: 0,
|
||||
SubscriptionUserId: refereeOwner.Id,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
logic.handleCommission(context.Background(), referee, orderInfo)
|
||||
|
||||
assertExpireIncreasedByDays(t, db, refereeOwnerSub.Id, refereeOwnerBaseExpire, 2)
|
||||
assertExpireIncreasedByDays(t, db, refererOwnerSub.Id, refererOwnerBaseExpire, 2)
|
||||
assertNoSubscribeForUser(t, db, referee.Id)
|
||||
assertNoSubscribeForUser(t, db, referer.Id)
|
||||
assertLogCountForOrder(t, db, modelLog.TypeGift.Uint8(), orderInfo.OrderNo, 2)
|
||||
}
|
||||
|
||||
func setupInviteTestLogic(t *testing.T, inviteCfg config.InviteConfig) (*ActivateOrderLogic, *gorm.DB, func()) {
|
||||
t.Helper()
|
||||
|
||||
@ -596,6 +756,43 @@ func assertUserCommission(t *testing.T, db *gorm.DB, userID int64, expected int6
|
||||
}
|
||||
}
|
||||
|
||||
func assertLogCountForOrder(t *testing.T, db *gorm.DB, logType uint8, orderNo string, expected int64) {
|
||||
t.Helper()
|
||||
var count int64
|
||||
if err := db.Model(&modelLog.SystemLog{}).
|
||||
Where("type = ? AND content LIKE ?", logType, "%"+orderNo+"%").
|
||||
Count(&count).Error; err != nil {
|
||||
t.Fatalf("count logs failed: %v", err)
|
||||
}
|
||||
if count != expected {
|
||||
t.Fatalf("expected log type %d count=%d for order %s, got %d", logType, expected, orderNo, count)
|
||||
}
|
||||
}
|
||||
|
||||
func assertGiftLogRemarkContains(t *testing.T, db *gorm.DB, orderNo string, want string) {
|
||||
t.Helper()
|
||||
var row modelLog.SystemLog
|
||||
if err := db.Model(&modelLog.SystemLog{}).
|
||||
Where("type = ? AND content LIKE ?", modelLog.TypeGift.Uint8(), "%"+orderNo+"%").
|
||||
First(&row).Error; err != nil {
|
||||
t.Fatalf("query gift log failed: %v", err)
|
||||
}
|
||||
if !strings.Contains(row.Content, want) {
|
||||
t.Fatalf("expected gift log content to contain %q, got %s", want, row.Content)
|
||||
}
|
||||
}
|
||||
|
||||
func assertNoSubscribeForUser(t *testing.T, db *gorm.DB, userID int64) {
|
||||
t.Helper()
|
||||
var count int64
|
||||
if err := db.Model(&user.Subscribe{}).Where("user_id = ?", userID).Count(&count).Error; err != nil {
|
||||
t.Fatalf("count subscribes failed: %v", err)
|
||||
}
|
||||
if count != 0 {
|
||||
t.Fatalf("expected user %d to have no direct subscriptions, got %d", userID, count)
|
||||
}
|
||||
}
|
||||
|
||||
func boolPtr(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user