147 lines
4.2 KiB
Go

package financewithdrawal
import (
"context"
"database/sql"
"strings"
"testing"
"github.com/DATA-DOG/go-sqlmock"
)
func TestCreateApplicationRequiresFreezeCommandID(t *testing.T) {
command := normalizeCreateApplicationCommand(CreateApplicationCommand{
AppCode: "huwaa",
UserID: 42001,
SalaryAssetType: "point",
WithdrawAmount: "9.50",
WithdrawAmountMinor: 1_000_000,
WithdrawAddress: "TQY9pFbZHuR4fUN9WgXPYj5nmB6nQiLQfF",
FreezeTransactionID: "tx-freeze",
CreatedAtMS: 1700000000000,
})
if err := validateCreateApplicationCommand(command); err == nil || !strings.Contains(err.Error(), "freeze_command_id") {
t.Fatalf("missing freeze command id should be rejected, got %v", err)
}
}
func TestCreateApplicationReturnsExistingByAppAndFreezeCommand(t *testing.T) {
db, mock, closeDB := newWriterSQLMock(t)
defer closeDB()
writer := &MySQLWriter{db: db}
mock.ExpectQuery(`(?s)FROM admin_user_withdrawal_applications\s+WHERE app_code = \? AND freeze_command_id = \?`).
WithArgs("huwaa", "cmd-point-freeze").
WillReturnRows(withdrawalApplicationRows().AddRow(
int64(77),
"huwaa",
"42001",
"POINT",
"9.50",
int64(1000000),
MethodUSDTTRC20,
"TQY9pFbZHuR4fUN9WgXPYj5nmB6nQiLQfF",
"cmd-point-freeze",
"tx-freeze",
StatusPending,
int64(1700000000000),
int64(1700000000000),
))
got, err := writer.CreateApplication(context.Background(), CreateApplicationCommand{
AppCode: "huwaa",
UserID: 42001,
SalaryAssetType: "POINT",
WithdrawAmount: "9.50",
WithdrawAmountMinor: 1_000_000,
WithdrawMethod: MethodUSDTTRC20,
WithdrawAddress: "TQY9pFbZHuR4fUN9WgXPYj5nmB6nQiLQfF",
FreezeCommandID: "cmd-point-freeze",
FreezeTransactionID: "tx-new-should-not-insert",
CreatedAtMS: 1700000009999,
})
if err != nil {
t.Fatalf("CreateApplication existing lookup failed: %v", err)
}
if got.ID != 77 || got.AppCode != "huwaa" || got.UserID != 42001 || got.FreezeTransactionID != "tx-freeze" {
t.Fatalf("existing withdrawal application mismatch: %+v", got)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Fatalf("sql expectations mismatch: %v", err)
}
}
func TestCreateApplicationInsertsAfterAppScopedMiss(t *testing.T) {
db, mock, closeDB := newWriterSQLMock(t)
defer closeDB()
writer := &MySQLWriter{db: db}
mock.ExpectQuery(`(?s)FROM admin_user_withdrawal_applications\s+WHERE app_code = \? AND freeze_command_id = \?`).
WithArgs("huwaa", "cmd-point-freeze").
WillReturnRows(withdrawalApplicationRows())
mock.ExpectExec(`(?s)INSERT INTO admin_user_withdrawal_applications`).
WithArgs(
"huwaa",
"42001",
"POINT",
"9.50",
int64(1000000),
MethodUSDTTRC20,
"TQY9pFbZHuR4fUN9WgXPYj5nmB6nQiLQfF",
"cmd-point-freeze",
"tx-freeze",
StatusPending,
int64(1700000000000),
int64(1700000000000),
).
WillReturnResult(sqlmock.NewResult(88, 1))
got, err := writer.CreateApplication(context.Background(), CreateApplicationCommand{
AppCode: "huwaa",
UserID: 42001,
SalaryAssetType: "point",
WithdrawAmount: "9.50",
WithdrawAmountMinor: 1_000_000,
WithdrawAddress: "TQY9pFbZHuR4fUN9WgXPYj5nmB6nQiLQfF",
FreezeCommandID: "cmd-point-freeze",
FreezeTransactionID: "tx-freeze",
CreatedAtMS: 1700000000000,
})
if err != nil {
t.Fatalf("CreateApplication insert failed: %v", err)
}
if got.ID != 88 || got.AppCode != "huwaa" || got.SalaryAssetType != "POINT" || got.WithdrawMethod != MethodUSDTTRC20 {
t.Fatalf("inserted withdrawal application mismatch: %+v", got)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Fatalf("sql expectations mismatch: %v", err)
}
}
func withdrawalApplicationRows() *sqlmock.Rows {
return sqlmock.NewRows([]string{
"id",
"app_code",
"user_id",
"salary_asset_type",
"withdraw_amount",
"withdraw_amount_minor",
"withdraw_method",
"withdraw_address",
"freeze_command_id",
"freeze_transaction_id",
"status",
"created_at_ms",
"updated_at_ms",
})
}
func newWriterSQLMock(t *testing.T) (*sql.DB, sqlmock.Sqlmock, func()) {
t.Helper()
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("create sql mock failed: %v", err)
}
return db, mock, func() { _ = db.Close() }
}