package financewithdrawal import ( "context" "testing" "hyapp-admin-server/internal/integration/walletclient" "hyapp-admin-server/internal/model" "hyapp-admin-server/internal/modules/shared" walletv1 "hyapp.local/api/proto/wallet/v1" ) func TestApplyWalletDecisionRoutesPointApprovalToPointSettlement(t *testing.T) { wallet := &fakeAuditWalletClient{} svc := &Service{wallet: wallet} transactionID, err := svc.applyWalletDecision(context.Background(), model.WithdrawalApplicationStatusApproved, "audit:77:approved", "huwaa", 42001, "POINT", 1_000_000, shared.Actor{UserID: 90001}, "paid", 77) if err != nil { t.Fatalf("apply point approval failed: %v", err) } if transactionID != "point-settle-tx" { t.Fatalf("point approval transaction id mismatch: %s", transactionID) } if wallet.settlePoint == nil || wallet.settlePoint.GetCommandId() != "audit:77:approved" || wallet.settlePoint.GetAppCode() != "huwaa" || wallet.settlePoint.GetUserId() != 42001 || wallet.settlePoint.GetAssetType() != "POINT" || wallet.settlePoint.GetGrossPointAmount() != 1_000_000 || wallet.settlePoint.GetFeePointAmount() != 50_000 || wallet.settlePoint.GetNetPointAmount() != 950_000 || wallet.settlePoint.GetOperatorUserId() != 90001 || wallet.settlePoint.GetWithdrawalApplicationId() != "77" { t.Fatalf("SettlePointWithdrawal payload mismatch: %+v", wallet.settlePoint) } if wallet.settleSalary != nil || wallet.releasePoint != nil || wallet.releaseSalary != nil { t.Fatalf("point approval must not call legacy salary or release RPCs: wallet=%+v", wallet) } } func TestApplyWalletDecisionRoutesPointRejectionToPointRelease(t *testing.T) { wallet := &fakeAuditWalletClient{} svc := &Service{wallet: wallet} transactionID, err := svc.applyWalletDecision(context.Background(), model.WithdrawalApplicationStatusRejected, "audit:78:rejected", "huwaa", 42002, "COIN_SELLER_POINT", 2_000_000, shared.Actor{UserID: 90002}, "bad address", 78) if err != nil { t.Fatalf("apply point rejection failed: %v", err) } if transactionID != "point-release-tx" { t.Fatalf("point rejection transaction id mismatch: %s", transactionID) } if wallet.releasePoint == nil || wallet.releasePoint.GetCommandId() != "audit:78:rejected" || wallet.releasePoint.GetAppCode() != "huwaa" || wallet.releasePoint.GetUserId() != 42002 || wallet.releasePoint.GetAssetType() != "COIN_SELLER_POINT" || wallet.releasePoint.GetGrossPointAmount() != 2_000_000 || wallet.releasePoint.GetFeePointAmount() != 100_000 || wallet.releasePoint.GetNetPointAmount() != 1_900_000 || wallet.releasePoint.GetOperatorUserId() != 90002 || wallet.releasePoint.GetReason() != "bad address" || wallet.releasePoint.GetWithdrawalApplicationId() != "78" { t.Fatalf("ReleasePointWithdrawal payload mismatch: %+v", wallet.releasePoint) } if wallet.settlePoint != nil || wallet.settleSalary != nil || wallet.releaseSalary != nil { t.Fatalf("point rejection must not call legacy salary or settle RPCs: wallet=%+v", wallet) } } func TestApplyWalletDecisionKeepsLegacySalaryAssetsOnSalaryRPC(t *testing.T) { wallet := &fakeAuditWalletClient{} svc := &Service{wallet: wallet} transactionID, err := svc.applyWalletDecision(context.Background(), model.WithdrawalApplicationStatusApproved, "audit:79:approved", "lalu", 42003, "HOST_SALARY_USD", 12_345, shared.Actor{UserID: 90003}, "", 79) if err != nil { t.Fatalf("apply salary approval failed: %v", err) } if transactionID != "salary-settle-tx" { t.Fatalf("salary approval transaction id mismatch: %s", transactionID) } if wallet.settleSalary == nil || wallet.settleSalary.GetAppCode() != "lalu" || wallet.settleSalary.GetUserId() != 42003 || wallet.settleSalary.GetSalaryAssetType() != "HOST_SALARY_USD" || wallet.settleSalary.GetSalaryUsdMinor() != 12_345 || wallet.settleSalary.GetWithdrawalApplicationId() != "79" { t.Fatalf("SettleSalaryWithdrawal payload mismatch: %+v", wallet.settleSalary) } if wallet.settlePoint != nil || wallet.releasePoint != nil { t.Fatalf("legacy salary asset must not call point RPCs: wallet=%+v", wallet) } } type fakeAuditWalletClient struct { walletclient.Client settlePoint *walletv1.SettlePointWithdrawalRequest releasePoint *walletv1.ReleasePointWithdrawalRequest settleSalary *walletv1.SettleSalaryWithdrawalRequest releaseSalary *walletv1.ReleaseSalaryWithdrawalRequest } func (f *fakeAuditWalletClient) SettlePointWithdrawal(_ context.Context, req *walletv1.SettlePointWithdrawalRequest) (*walletv1.SettlePointWithdrawalResponse, error) { f.settlePoint = req return &walletv1.SettlePointWithdrawalResponse{TransactionId: "point-settle-tx"}, nil } func (f *fakeAuditWalletClient) ReleasePointWithdrawal(_ context.Context, req *walletv1.ReleasePointWithdrawalRequest) (*walletv1.ReleasePointWithdrawalResponse, error) { f.releasePoint = req return &walletv1.ReleasePointWithdrawalResponse{TransactionId: "point-release-tx"}, nil } func (f *fakeAuditWalletClient) SettleSalaryWithdrawal(_ context.Context, req *walletv1.SettleSalaryWithdrawalRequest) (*walletv1.SettleSalaryWithdrawalResponse, error) { f.settleSalary = req return &walletv1.SettleSalaryWithdrawalResponse{TransactionId: "salary-settle-tx"}, nil } func (f *fakeAuditWalletClient) ReleaseSalaryWithdrawal(_ context.Context, req *walletv1.ReleaseSalaryWithdrawalRequest) (*walletv1.ReleaseSalaryWithdrawalResponse, error) { f.releaseSalary = req return &walletv1.ReleaseSalaryWithdrawalResponse{TransactionId: "salary-release-tx"}, nil }