131 lines
4.4 KiB
Go
131 lines
4.4 KiB
Go
package firstrecharge
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"google.golang.org/grpc"
|
|
walletv1 "hyapp.local/api/proto/wallet/v1"
|
|
"hyapp/pkg/appcode"
|
|
domain "hyapp/services/activity-service/internal/domain/firstrecharge"
|
|
"hyapp/services/activity-service/internal/testutil/mysqltest"
|
|
)
|
|
|
|
func TestFirstRechargeRewardConsumesRechargeFactWithMySQL(t *testing.T) {
|
|
repository := mysqltest.NewRepository(t)
|
|
wallet := &fakeWallet{}
|
|
svc := New(repository, wallet)
|
|
ctx := appcode.WithContext(context.Background(), "lalu")
|
|
|
|
config, err := svc.UpdateConfig(ctx, domain.Config{
|
|
Enabled: true,
|
|
UpdatedByAdminID: 90001,
|
|
Tiers: []domain.Tier{{
|
|
TierCode: "first_099",
|
|
TierName: "首冲 $0.99",
|
|
USDMinorAmount: 99,
|
|
GoogleProductID: "first_recharge_google_099",
|
|
DiscountPercent: 70,
|
|
ResourceGroupID: 88001,
|
|
Status: domain.TierStatusActive,
|
|
SortOrder: 1,
|
|
}, {
|
|
TierCode: "first_199",
|
|
TierName: "首冲 $1.99",
|
|
USDMinorAmount: 199,
|
|
GoogleProductID: "first_recharge_google_199",
|
|
DiscountPercent: 60,
|
|
ResourceGroupID: 88002,
|
|
Status: domain.TierStatusActive,
|
|
SortOrder: 2,
|
|
}},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("UpdateConfig failed: %v", err)
|
|
}
|
|
if len(config.Tiers) != 2 || config.Tiers[0].TierID <= 0 || config.Tiers[1].TierID <= 0 {
|
|
t.Fatalf("tier id was not generated: %+v", config.Tiers)
|
|
}
|
|
|
|
event := domain.RechargeEvent{
|
|
AppCode: "lalu",
|
|
EventID: "evt-recharge-1",
|
|
EventType: domain.RechargeEventWalletRecorded,
|
|
TransactionID: "wtx-recharge-1",
|
|
CommandID: "seller-transfer-1",
|
|
UserID: 42001,
|
|
RechargeCoinAmount: 0,
|
|
RechargeSequence: 2,
|
|
RechargeType: "google",
|
|
RechargeUSDMinor: 99,
|
|
GoogleProductID: "first_recharge_google_099",
|
|
OccurredAtMS: 1710000000000,
|
|
}
|
|
err = svc.ConsumeWalletRechargeEvent(ctx, event)
|
|
if err != nil {
|
|
t.Fatalf("ConsumeWalletRechargeEvent failed: %v", err)
|
|
}
|
|
claim, exists, err := repository.GetFirstRechargeRewardClaimByUser(ctx, 42001)
|
|
if err != nil {
|
|
t.Fatalf("GetFirstRechargeRewardClaimByUser failed: %v", err)
|
|
}
|
|
if !exists || claim.Status != domain.StatusGranted || claim.ResourceGroupID != 88001 || claim.GoogleProductID != "first_recharge_google_099" || claim.RechargeCoinAmount != 0 {
|
|
t.Fatalf("consume result mismatch: exists=%v claim=%+v", exists, claim)
|
|
}
|
|
if len(wallet.grants) != 1 || wallet.grants[0].GroupId != 88001 || wallet.grants[0].TargetUserId != 42001 {
|
|
t.Fatalf("wallet grant mismatch: %+v", wallet.grants)
|
|
}
|
|
|
|
status, err := svc.GetStatus(ctx, 42001)
|
|
if err != nil {
|
|
t.Fatalf("GetStatus failed: %v", err)
|
|
}
|
|
if status.Rewarded || len(status.Tiers) != 1 || status.Tiers[0].GoogleProductID != "first_recharge_google_199" || len(status.Claims) != 1 {
|
|
t.Fatalf("status should keep the unpurchased tier visible: %+v", status)
|
|
}
|
|
|
|
err = svc.ConsumeWalletRechargeEvent(ctx, event)
|
|
if err != nil {
|
|
t.Fatalf("retry ConsumeWalletRechargeEvent failed: %v", err)
|
|
}
|
|
if len(wallet.grants) != 1 {
|
|
t.Fatalf("retry should be idempotent, grants=%d", len(wallet.grants))
|
|
}
|
|
|
|
event.EventID = "evt-recharge-2"
|
|
event.TransactionID = "wtx-recharge-2"
|
|
event.CommandID = "seller-transfer-2"
|
|
event.RechargeUSDMinor = 199
|
|
event.GoogleProductID = "first_recharge_google_199"
|
|
err = svc.ConsumeWalletRechargeEvent(ctx, event)
|
|
if err != nil {
|
|
t.Fatalf("second recharge ConsumeWalletRechargeEvent failed: %v", err)
|
|
}
|
|
if len(wallet.grants) != 2 || wallet.grants[1].GroupId != 88002 {
|
|
t.Fatalf("second tier should be granted, grants=%+v", wallet.grants)
|
|
}
|
|
status, err = svc.GetStatus(ctx, 42001)
|
|
if err != nil {
|
|
t.Fatalf("GetStatus after all tiers failed: %v", err)
|
|
}
|
|
if !status.Rewarded || len(status.Tiers) != 0 || len(status.Claims) != 2 {
|
|
t.Fatalf("status should complete after all tiers are purchased: %+v", status)
|
|
}
|
|
}
|
|
|
|
type fakeWallet struct {
|
|
grants []*walletv1.GrantResourceGroupRequest
|
|
}
|
|
|
|
func (f *fakeWallet) GrantResourceGroup(_ context.Context, req *walletv1.GrantResourceGroupRequest, _ ...grpc.CallOption) (*walletv1.ResourceGrantResponse, error) {
|
|
f.grants = append(f.grants, req)
|
|
return &walletv1.ResourceGrantResponse{Grant: &walletv1.ResourceGrant{
|
|
AppCode: req.GetAppCode(),
|
|
GrantId: "grant-first-recharge",
|
|
CommandId: req.GetCommandId(),
|
|
TargetUserId: req.GetTargetUserId(),
|
|
GrantSource: req.GetGrantSource(),
|
|
Status: "granted",
|
|
}}, nil
|
|
}
|