This commit is contained in:
2026-03-26 13:02:43 +00:00
parent a689f8b9da
commit eb7b519e49
64 changed files with 7081 additions and 5572 deletions

View File

@@ -3,13 +3,14 @@ package app
import (
"context"
"testing"
"strings"
"github.com/google/uuid"
"google.golang.org/grpc/codes"
"gorm.io/gorm"
"stream.api/internal/database/model"
appv1 "stream.api/internal/gen/proto/app/v1"
"stream.api/internal/modules/common"
paymentsmodule "stream.api/internal/modules/payments"
)
func TestRegisterReferralCapture(t *testing.T) {
@@ -18,12 +19,7 @@ func TestRegisterReferralCapture(t *testing.T) {
services := newTestAppServices(t, db)
referrer := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "ref@example.com", Username: ptrString("alice"), Role: ptrString("USER")})
resp, err := services.Register(context.Background(), &appv1.RegisterRequest{
Username: "bob",
Email: "bob@example.com",
Password: "secret123",
RefUsername: ptrString("alice"),
})
resp, err := services.Register(context.Background(), &appv1.RegisterRequest{Username: "bob", Email: "bob@example.com", Password: "secret123", RefUsername: ptrString("alice")})
if err != nil {
t.Fatalf("Register() error = %v", err)
}
@@ -39,13 +35,7 @@ func TestRegisterReferralCapture(t *testing.T) {
t.Run("register với ref invalid hoặc self-ref vẫn tạo user", func(t *testing.T) {
db := newTestDB(t)
services := newTestAppServices(t, db)
resp, err := services.Register(context.Background(), &appv1.RegisterRequest{
Username: "selfie",
Email: "selfie@example.com",
Password: "secret123",
RefUsername: ptrString("selfie"),
})
resp, err := services.Register(context.Background(), &appv1.RegisterRequest{Username: "selfie", Email: "selfie@example.com", Password: "secret123", RefUsername: ptrString("selfie")})
if err != nil {
t.Fatalf("Register() error = %v", err)
}
@@ -61,9 +51,9 @@ func TestResolveSignupReferrerID(t *testing.T) {
db := newTestDB(t)
services := newTestAppServices(t, db)
referrer := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "ref@example.com", Username: ptrString("alice"), Role: ptrString("USER")})
referrerID, err := services.resolveSignupReferrerID(context.Background(), "alice", "bob")
referrerID, err := services.usersModule.ResolveSignupReferrerID(context.Background(), "alice", "bob")
if err != nil {
t.Fatalf("resolveSignupReferrerID() error = %v", err)
t.Fatalf("ResolveSignupReferrerID() error = %v", err)
}
if referrerID == nil || *referrerID != referrer.ID {
t.Fatalf("referrerID = %v, want %s", referrerID, referrer.ID)
@@ -73,9 +63,9 @@ func TestResolveSignupReferrerID(t *testing.T) {
t.Run("invalid hoặc self-ref bị ignore", func(t *testing.T) {
db := newTestDB(t)
services := newTestAppServices(t, db)
referrerID, err := services.resolveSignupReferrerID(context.Background(), "bob", "bob")
referrerID, err := services.usersModule.ResolveSignupReferrerID(context.Background(), "bob", "bob")
if err != nil {
t.Fatalf("resolveSignupReferrerID() error = %v", err)
t.Fatalf("ResolveSignupReferrerID() error = %v", err)
}
if referrerID != nil {
t.Fatalf("referrerID = %v, want nil", referrerID)
@@ -87,9 +77,9 @@ func TestResolveSignupReferrerID(t *testing.T) {
services := newTestAppServices(t, db)
seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "a@example.com", Username: ptrString("alice"), Role: ptrString("USER")})
seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "b@example.com", Username: ptrString("alice"), Role: ptrString("USER")})
referrerID, err := services.resolveSignupReferrerID(context.Background(), "alice", "bob")
referrerID, err := services.usersModule.ResolveSignupReferrerID(context.Background(), "alice", "bob")
if err != nil {
t.Fatalf("resolveSignupReferrerID() error = %v", err)
t.Fatalf("ResolveSignupReferrerID() error = %v", err)
}
if referrerID != nil {
t.Fatalf("referrerID = %v, want nil", referrerID)
@@ -110,11 +100,10 @@ func TestReferralRewardFlow(t *testing.T) {
t.Run("first subscription thưởng 5 phần trăm", func(t *testing.T) {
services, db, referrer, referee, plan := setup(t)
seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: referee.ID, Type: walletTransactionTypeTopup, Amount: 20, Currency: ptrString("USD")})
result, err := services.executePaymentFlow(context.Background(), paymentExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: paymentMethodWallet})
seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: referee.ID, Type: common.WalletTransactionTypeTopup, Amount: 20, Currency: ptrString("USD")})
result, err := services.paymentsModule.ExecutePaymentFlow(context.Background(), paymentsmodule.ExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: common.PaymentMethodWallet})
if err != nil {
t.Fatalf("executePaymentFlow() error = %v", err)
t.Fatalf("ExecutePaymentFlow() error = %v", err)
}
updatedReferee := mustLoadUser(t, db, referee.ID)
if updatedReferee.ReferralRewardPaymentID == nil || *updatedReferee.ReferralRewardPaymentID != result.Payment.ID {
@@ -138,12 +127,12 @@ func TestReferralRewardFlow(t *testing.T) {
t.Run("subscription thứ hai không thưởng lại", func(t *testing.T) {
services, db, referrer, referee, plan := setup(t)
seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: referee.ID, Type: walletTransactionTypeTopup, Amount: 40, Currency: ptrString("USD")})
if _, err := services.executePaymentFlow(context.Background(), paymentExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: paymentMethodWallet}); err != nil {
t.Fatalf("first executePaymentFlow() error = %v", err)
seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: referee.ID, Type: common.WalletTransactionTypeTopup, Amount: 40, Currency: ptrString("USD")})
if _, err := services.paymentsModule.ExecutePaymentFlow(context.Background(), paymentsmodule.ExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: common.PaymentMethodWallet}); err != nil {
t.Fatalf("first ExecutePaymentFlow() error = %v", err)
}
if _, err := services.executePaymentFlow(context.Background(), paymentExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: paymentMethodWallet}); err != nil {
t.Fatalf("second executePaymentFlow() error = %v", err)
if _, err := services.paymentsModule.ExecutePaymentFlow(context.Background(), paymentsmodule.ExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: common.PaymentMethodWallet}); err != nil {
t.Fatalf("second ExecutePaymentFlow() error = %v", err)
}
balance, err := model.GetWalletBalance(context.Background(), db, referrer.ID)
if err != nil {
@@ -174,9 +163,9 @@ func TestReferralRewardFlow(t *testing.T) {
if err := db.Model(&model.User{}).Where("id = ?", referrer.ID).Update("referral_eligible", false).Error; err != nil {
t.Fatalf("update referral_eligible: %v", err)
}
seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: referee.ID, Type: walletTransactionTypeTopup, Amount: 20, Currency: ptrString("USD")})
if _, err := services.executePaymentFlow(context.Background(), paymentExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: paymentMethodWallet}); err != nil {
t.Fatalf("executePaymentFlow() error = %v", err)
seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: referee.ID, Type: common.WalletTransactionTypeTopup, Amount: 20, Currency: ptrString("USD")})
if _, err := services.paymentsModule.ExecutePaymentFlow(context.Background(), paymentsmodule.ExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: common.PaymentMethodWallet}); err != nil {
t.Fatalf("ExecutePaymentFlow() error = %v", err)
}
balance, err := model.GetWalletBalance(context.Background(), db, referrer.ID)
if err != nil {
@@ -192,9 +181,9 @@ func TestReferralRewardFlow(t *testing.T) {
if err := db.Model(&model.User{}).Where("id = ?", referrer.ID).Update("referral_reward_bps", 750).Error; err != nil {
t.Fatalf("update referral_reward_bps: %v", err)
}
seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: referee.ID, Type: walletTransactionTypeTopup, Amount: 20, Currency: ptrString("USD")})
if _, err := services.executePaymentFlow(context.Background(), paymentExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: paymentMethodWallet}); err != nil {
t.Fatalf("executePaymentFlow() error = %v", err)
seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: referee.ID, Type: common.WalletTransactionTypeTopup, Amount: 20, Currency: ptrString("USD")})
if _, err := services.paymentsModule.ExecutePaymentFlow(context.Background(), paymentsmodule.ExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: common.PaymentMethodWallet}); err != nil {
t.Fatalf("ExecutePaymentFlow() error = %v", err)
}
balance, err := model.GetWalletBalance(context.Background(), db, referrer.ID)
if err != nil {
@@ -213,23 +202,10 @@ func TestUpdateAdminUserReferralSettings(t *testing.T) {
referrer := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "ref@example.com", Username: ptrString("alice"), Role: ptrString("USER")})
referee := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "payer@example.com", Username: ptrString("bob"), Role: ptrString("USER"), ReferredByUserID: &referrer.ID, ReferralEligible: ptrBool(true)})
plan := seedTestPlan(t, db, model.Plan{ID: uuid.NewString(), Name: "Pro", Price: 20, Cycle: "monthly", StorageLimit: 100, UploadLimit: 10, QualityLimit: "1080p", IsActive: ptrBool(true)})
seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: referee.ID, Type: walletTransactionTypeTopup, Amount: 20, Currency: ptrString("USD")})
if _, err := services.executePaymentFlow(context.Background(), paymentExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: paymentMethodWallet}); err != nil {
t.Fatalf("executePaymentFlow() error = %v", err)
seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: referee.ID, Type: common.WalletTransactionTypeTopup, Amount: 20, Currency: ptrString("USD")})
if _, err := services.paymentsModule.ExecutePaymentFlow(context.Background(), paymentsmodule.ExecutionInput{UserID: referee.ID, Plan: &plan, TermMonths: 1, PaymentMethod: common.PaymentMethodWallet}); err != nil {
t.Fatalf("ExecutePaymentFlow() error = %v", err)
}
_, err := services.UpdateAdminUserReferralSettings(testActorIncomingContext(admin.ID, "ADMIN"), &appv1.UpdateAdminUserReferralSettingsRequest{
Id: referee.ID,
RefUsername: ptrString("alice"),
})
_, err := services.UpdateAdminUserReferralSettings(testActorIncomingContext(admin.ID, "ADMIN"), &appv1.UpdateAdminUserReferralSettingsRequest{Id: referee.ID, RefUsername: ptrString("alice")})
assertGRPCCode(t, err, codes.InvalidArgument)
}
func containsAny(value string, parts ...string) bool {
for _, part := range parts {
if part != "" && strings.Contains(value, part) {
return true
}
}
return false
}