remove test fmt

This commit is contained in:
daniel.w 2024-10-22 18:28:55 +08:00
parent f5a043ab79
commit 0a62d892ce
8 changed files with 612 additions and 649 deletions

View File

@ -91,9 +91,9 @@ func (l *CreateOrderLogic) CreateOrder(in *order.CreateOrderReq) (*order.OKResp,
Brand: req.Brand,
OrderUID: req.OrderUID,
ReferenceID: req.ReferenceID,
Count: req.Count,
OrderFee: req.OrderFee,
Amount: req.Amount,
Count: convertDecimalToDecimal128(req.Count),
OrderFee: convertDecimalToDecimal128(req.OrderFee),
Amount: convertDecimalToDecimal128(req.Amount),
// 下面的是未來擴充用,加密貨幣用,或者幣別轉換用,普通訂單用不到
ReferenceBrand: req.ReferenceBrand,
ReferenceUID: req.ReferenceUID,
@ -101,13 +101,13 @@ func (l *CreateOrderLogic) CreateOrder(in *order.CreateOrderReq) (*order.OKResp,
ThreePartyStatus: req.ThreePartyStatus,
DirectionType: req.DirectionType,
CryptoType: req.CryptoType,
ThirdPartyFee: req.ThirdPartyFee,
CryptoToUSDTRate: req.CryptoToUSDTRate,
FiatToUSDRate: req.FiatToUSDRate,
FeeCryptoToUSDTRate: req.FeeCryptoToUSDTRate,
USDTToCryptoTypeRate: req.USDTToCryptoTypeRate,
ThirdPartyFee: convertDecimalPtrToDecimal128(req.ThirdPartyFee),
CryptoToUSDTRate: convertDecimalPtrToDecimal128(req.CryptoToUSDTRate),
FiatToUSDRate: convertDecimalPtrToDecimal128(req.FiatToUSDRate),
FeeCryptoToUSDTRate: convertDecimalPtrToDecimal128(req.FeeCryptoToUSDTRate),
USDTToCryptoTypeRate: convertDecimalPtrToDecimal128(req.USDTToCryptoTypeRate),
PaymentFiat: req.PaymentFiat,
PaymentUnitPrice: req.PaymentUnitPrice,
PaymentUnitPrice: convertDecimalPtrToDecimal128(req.PaymentUnitPrice),
PaymentTemplateID: req.PaymentTemplateID,
OrderArrivalTime: req.OrderArrivalTime,
OrderPaymentTime: req.OrderPaymentTime,
@ -116,7 +116,7 @@ func (l *CreateOrderLogic) CreateOrder(in *order.CreateOrderReq) (*order.OKResp,
TxHash: req.TxHash,
FromAddress: req.FromAddress,
ToAddress: req.ToAddress,
ChainFee: req.ChainFee,
ChainFee: convertDecimalPtrToDecimal128(req.ChainFee),
ChainFeeCrypto: req.ChainFeeCrypto,
Memo: req.Memo,
OrderNote: req.OrderNote,
@ -252,16 +252,3 @@ func buildCreateOrderReq(in *order.CreateOrderReq) (*createOrderReq, error) {
return createOrderReq, nil
}
// Helper function for decimal conversion with nil support
func decimalPtrFromString(val string) *decimal.Decimal {
if val == "" {
return nil
}
dec, err := decimal.NewFromString(val)
if err != nil {
return nil
}
return &dec
}

View File

@ -15,42 +15,6 @@ import (
"go.uber.org/mock/gomock"
)
func TestDecimalPtrFromString(t *testing.T) {
tests := []struct {
name string
input string
expected *decimal.Decimal
}{
{
name: "valid decimal string",
input: "10.5",
expected: decimalPtr("10.5"), // 使用輔助函數將字串轉換為指針
},
{
name: "empty string returns nil",
input: "",
expected: nil,
},
{
name: "invalid decimal string returns nil",
input: "invalid-decimal",
expected: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := decimalPtrFromString(tt.input) // 調用要測試的函數
if tt.expected == nil {
assert.Nil(t, result)
} else {
assert.NotNil(t, result)
assert.True(t, tt.expected.Equal(*result), "Expected %v, got %v", tt.expected, result)
}
})
}
}
func TestBuildCreateOrderReq(t *testing.T) {
tests := []struct {
name string

View File

@ -0,0 +1,99 @@
package orderservicelogic
import (
"github.com/shopspring/decimal"
"github.com/zeromicro/go-zero/core/logx"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// Helper function for decimal conversion with nil support and logging
func decimalPtrFromString(val string) *decimal.Decimal {
if val == "" {
return nil
}
dec, err := decimal.NewFromString(val)
if err != nil {
logx.Errorf("Failed to convert string to decimal: %v", err)
return nil
}
return &dec
}
// Convert decimal.Decimal to primitive.Decimal128 and handle nil values
func convertDecimalPtrToDecimal128(d *decimal.Decimal) *primitive.Decimal128 {
if d == nil {
return nil
}
result, err := primitive.ParseDecimal128(d.String())
if err != nil {
logx.Errorf("Failed to convert decimal to Decimal128: %v", err)
return nil
}
return &result
}
// Convert decimal.Decimal (non-pointer) to primitive.Decimal128 and log errors
func convertDecimalToDecimal128(d decimal.Decimal) primitive.Decimal128 {
result, err := primitive.ParseDecimal128(d.String())
if err != nil {
logx.Errorf("Failed to convert decimal to Decimal128: %v", err)
return primitive.NewDecimal128(0, 0)
}
return result
}
// 將 primitive.Decimal128 轉換為字符串
func convertDecimal128ToString(d128 *primitive.Decimal128) *string {
if d128 != nil {
return nil
}
result := d128.String()
return &result
}
// Helper functions for optional fields
func optionalString(s *string) *string {
if s != nil {
return s
}
return nil
}
func optionalInt64(i *int64) *int64 {
if i != nil {
return i
}
return nil
}
func optionalDecimalToString(d *decimal.Decimal) *string {
if d != nil {
s := d.String()
return &s
}
return nil
}
func nilString(s *string) *string {
if s == nil {
return nil
}
return s
}
func nilInt64(i *int64) *int64 {
if i == nil {
return nil
}
return i
}

View File

@ -2,12 +2,9 @@ package orderservicelogic
import (
"app-cloudep-order-server/gen_result/pb/order"
"context"
ers "code.30cm.net/digimon/library-go/errs"
"github.com/shopspring/decimal"
"app-cloudep-order-server/internal/svc"
ers "code.30cm.net/digimon/library-go/errs"
"context"
"github.com/zeromicro/go-zero/core/logx"
)
@ -65,13 +62,13 @@ func (l *GetOrderLogic) GetOrder(in *order.GetOrderReq) (*order.GetOrderResp, er
ThreePartyStatus: nilInt64(o.ThreePartyStatus),
DirectionType: nilInt64(o.DirectionType),
CryptoType: nilString(o.CryptoType),
ThirdPartyFee: decimalToString(o.ThirdPartyFee),
CryptoToUsdtRate: decimalToString(o.CryptoToUSDTRate),
FiatToUsdRate: decimalToString(o.FiatToUSDRate),
FeeCryptoToUsdtRate: decimalToString(o.FeeCryptoToUSDTRate),
UsdtToCryptoTypeRate: decimalToString(o.USDTToCryptoTypeRate),
ThirdPartyFee: convertDecimal128ToString(o.ThirdPartyFee),
CryptoToUsdtRate: convertDecimal128ToString(o.CryptoToUSDTRate),
FiatToUsdRate: convertDecimal128ToString(o.FiatToUSDRate),
FeeCryptoToUsdtRate: convertDecimal128ToString(o.FeeCryptoToUSDTRate),
UsdtToCryptoTypeRate: convertDecimal128ToString(o.USDTToCryptoTypeRate),
PaymentFiat: nilString(o.PaymentFiat),
PaymentUnitPrice: decimalToString(o.PaymentUnitPrice),
PaymentUnitPrice: convertDecimal128ToString(o.PaymentUnitPrice),
PaymentTemplateId: nilString(o.PaymentTemplateID),
OrderArrivalTime: nilInt64(o.OrderArrivalTime),
OrderPaymentTime: nilInt64(o.OrderPaymentTime),
@ -80,41 +77,9 @@ func (l *GetOrderLogic) GetOrder(in *order.GetOrderReq) (*order.GetOrderResp, er
TxHash: nilString(o.TxHash),
FromAddress: nilString(o.FromAddress),
ToAddress: nilString(o.ToAddress),
ChainFee: decimalToString(o.ChainFee),
ChainFee: convertDecimal128ToString(o.ChainFee),
ChainFeeCrypto: nilString(o.ChainFeeCrypto),
Memo: nilString(o.Memo),
OrderNote: nilString(o.OrderNote),
}, nil
}
func decimalToString(amount *decimal.Decimal) *string {
if amount == nil {
return nil
}
a := amount.String()
return &a
}
func nilString(s *string) *string {
if s == nil {
return nil
}
return s
}
func nilInt64(i *int64) *int64 {
if i == nil {
return nil
}
return i
}
// Helper functions
//
//nolint:unused
func ptrString(s string) *string {
return &s
}

View File

@ -8,9 +8,9 @@ import (
"app-cloudep-order-server/internal/svc"
"context"
"errors"
"go.mongodb.org/mongo-driver/bson/primitive"
"testing"
"github.com/shopspring/decimal"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
)
@ -28,6 +28,9 @@ func TestGetOrder(t *testing.T) {
OrderModel: mockOrderModel,
Validate: mockValidate,
}
Count, _ := primitive.ParseDecimal128("10.5")
OrderFee, _ := primitive.ParseDecimal128("0.5")
Amount, _ := primitive.ParseDecimal128("100")
// 模擬返回的訂單數據
mockOrder := &model.Order{
@ -39,9 +42,9 @@ func TestGetOrder(t *testing.T) {
Brand: "TestBrand",
OrderUID: "UID123",
ReferenceID: "REF123",
Count: decimal.RequireFromString("10.5"),
OrderFee: decimal.RequireFromString("0.5"),
Amount: decimal.RequireFromString("100"),
Count: Count,
OrderFee: OrderFee,
Amount: Amount,
}
// 測試數據集

View File

@ -5,10 +5,8 @@ import (
model "app-cloudep-order-server/internal/model/mongo"
"context"
ers "code.30cm.net/digimon/library-go/errs"
"github.com/shopspring/decimal"
"app-cloudep-order-server/internal/svc"
ers "code.30cm.net/digimon/library-go/errs"
"github.com/zeromicro/go-zero/core/logx"
)
@ -101,13 +99,13 @@ func ConvertOrderToGetOrderResp(o model.Order) *order.GetOrderResp {
ThreePartyStatus: optionalInt64(o.ThreePartyStatus),
DirectionType: optionalInt64(o.DirectionType),
CryptoType: optionalString(o.CryptoType),
ThirdPartyFee: optionalDecimalToString(o.ThirdPartyFee),
CryptoToUsdtRate: optionalDecimalToString(o.CryptoToUSDTRate),
FiatToUsdRate: optionalDecimalToString(o.FiatToUSDRate),
FeeCryptoToUsdtRate: optionalDecimalToString(o.FeeCryptoToUSDTRate),
UsdtToCryptoTypeRate: optionalDecimalToString(o.USDTToCryptoTypeRate),
ThirdPartyFee: convertDecimal128ToString(o.ThirdPartyFee),
CryptoToUsdtRate: convertDecimal128ToString(o.CryptoToUSDTRate),
FiatToUsdRate: convertDecimal128ToString(o.FiatToUSDRate),
FeeCryptoToUsdtRate: convertDecimal128ToString(o.FeeCryptoToUSDTRate),
UsdtToCryptoTypeRate: convertDecimal128ToString(o.USDTToCryptoTypeRate),
PaymentFiat: optionalString(o.PaymentFiat),
PaymentUnitPrice: optionalDecimalToString(o.PaymentUnitPrice),
PaymentUnitPrice: convertDecimal128ToString(o.PaymentUnitPrice),
PaymentTemplateId: optionalString(o.PaymentTemplateID),
OrderArrivalTime: optionalInt64(o.OrderArrivalTime),
OrderPaymentTime: optionalInt64(o.OrderPaymentTime),
@ -116,7 +114,7 @@ func ConvertOrderToGetOrderResp(o model.Order) *order.GetOrderResp {
TxHash: optionalString(o.TxHash),
FromAddress: optionalString(o.FromAddress),
ToAddress: optionalString(o.ToAddress),
ChainFee: optionalDecimalToString(o.ChainFee),
ChainFee: convertDecimal128ToString(o.ChainFee),
ChainFeeCrypto: optionalString(o.ChainFeeCrypto),
Memo: optionalString(o.Memo),
OrderNote: optionalString(o.OrderNote),
@ -124,39 +122,3 @@ func ConvertOrderToGetOrderResp(o model.Order) *order.GetOrderResp {
UpdateTime: o.UpdateTime,
}
}
// Helper functions for optional fields
func optionalString(s *string) *string {
if s != nil {
return s
}
return nil
}
func optionalInt64(i *int64) *int64 {
if i != nil {
return i
}
return nil
}
func optionalDecimalToString(d *decimal.Decimal) *string {
if d != nil {
s := d.String()
return &s
}
return nil
}
func ConvertOrdersToGetOrderResp(orders []model.Order) []*order.GetOrderResp {
res := make([]*order.GetOrderResp, 0, len(orders))
for _, o := range orders {
res = append(res, ConvertOrderToGetOrderResp(o))
}
return res
}

View File

@ -1,459 +1,444 @@
package orderservicelogic
import (
"app-cloudep-order-server/gen_result/pb/order"
mocksvc "app-cloudep-order-server/internal/mock/lib"
mockmodel "app-cloudep-order-server/internal/mock/model"
model "app-cloudep-order-server/internal/model/mongo"
"app-cloudep-order-server/internal/svc"
"context"
"errors"
"testing"
"github.com/shopspring/decimal"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
)
func TestConvertOrdersToGetOrderResp(t *testing.T) {
tests := []struct {
name string
input []model.Order
expected []*order.GetOrderResp
}{
{
name: "空訂單列表",
input: []model.Order{},
expected: []*order.GetOrderResp{},
},
{
name: "單筆訂單",
input: []model.Order{
{
BusinessID: "B123",
OrderType: 1,
OrderStatus: 2,
Brand: "TestBrand",
OrderUID: "UID123",
ReferenceID: "REF123",
Count: decimal.RequireFromString("10.5"),
OrderFee: decimal.RequireFromString("0.5"),
Amount: decimal.RequireFromString("100"),
},
},
expected: []*order.GetOrderResp{
{
BusinessId: "B123",
OrderType: 1,
OrderStatus: 2,
Brand: "TestBrand",
OrderUid: "UID123",
ReferenceId: "REF123",
Count: "10.5",
OrderFee: "0.5",
Amount: "100",
},
},
},
{
name: "多筆訂單",
input: []model.Order{
{
BusinessID: "B123",
OrderType: 1,
OrderStatus: 2,
Brand: "TestBrand",
OrderUID: "UID123",
ReferenceID: "REF123",
Count: decimal.RequireFromString("10.5"),
OrderFee: decimal.RequireFromString("0.5"),
Amount: decimal.RequireFromString("100"),
},
{
BusinessID: "B456",
OrderType: 2,
OrderStatus: 3,
Brand: "OtherBrand",
OrderUID: "UID456",
ReferenceID: "REF456",
Count: decimal.RequireFromString("20"),
OrderFee: decimal.RequireFromString("1"),
Amount: decimal.RequireFromString("200"),
},
},
expected: []*order.GetOrderResp{
{
BusinessId: "B123",
OrderType: 1,
OrderStatus: 2,
Brand: "TestBrand",
OrderUid: "UID123",
ReferenceId: "REF123",
Count: "10.5",
OrderFee: "0.5",
Amount: "100",
},
{
BusinessId: "B456",
OrderType: 2,
OrderStatus: 3,
Brand: "OtherBrand",
OrderUid: "UID456",
ReferenceId: "REF456",
Count: "20",
OrderFee: "1",
Amount: "200",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 執行 ConvertOrdersToGetOrderResp 函數
result := ConvertOrdersToGetOrderResp(tt.input)
// 驗證結果
assert.Equal(t, tt.expected, result)
})
}
}
func TestOptionalString(t *testing.T) {
t.Run("非 nil 字串", func(t *testing.T) {
str := "hello"
result := optionalString(&str)
assert.NotNil(t, result)
assert.Equal(t, &str, result)
})
t.Run("nil 字串", func(t *testing.T) {
result := optionalString(nil)
assert.Nil(t, result)
})
}
func TestOptionalInt64(t *testing.T) {
t.Run("非 nil int64", func(t *testing.T) {
num := int64(123)
result := optionalInt64(&num)
assert.NotNil(t, result)
assert.Equal(t, &num, result)
})
t.Run("nil int64", func(t *testing.T) {
result := optionalInt64(nil)
assert.Nil(t, result)
})
}
func TestOptionalDecimalToString(t *testing.T) {
t.Run("非 nil decimal", func(t *testing.T) {
dec := decimal.NewFromInt(123)
expected := "123"
result := optionalDecimalToString(&dec)
assert.NotNil(t, result)
assert.Equal(t, &expected, result)
})
t.Run("nil decimal", func(t *testing.T) {
result := optionalDecimalToString(nil)
assert.Nil(t, result)
})
}
func TestConvertOrderToGetOrderResp(t *testing.T) {
tests := []struct {
name string
input model.Order
expected *order.GetOrderResp
}{
{
name: "所有欄位都有值",
input: model.Order{
BusinessID: "B123",
OrderType: 1,
OrderStatus: 2,
Brand: "TestBrand",
OrderUID: "UID123",
ReferenceID: "REF123",
Count: decimal.RequireFromString("10.5"),
OrderFee: decimal.RequireFromString("0.5"),
Amount: decimal.RequireFromString("100"),
ReferenceBrand: ptrString("OtherBrand"),
ReferenceUID: ptrString("REFUID"),
WalletStatus: ptrInt64(1),
ThreePartyStatus: ptrInt64(2),
DirectionType: ptrInt64(1),
CryptoType: ptrString("BTC"),
ThirdPartyFee: decimalPtrFromString("0.01"),
CryptoToUSDTRate: decimalPtrFromString("50000"),
FiatToUSDRate: decimalPtrFromString("1"),
FeeCryptoToUSDTRate: decimalPtrFromString("0.02"),
USDTToCryptoTypeRate: decimalPtrFromString("0.00002"),
PaymentFiat: ptrString("USD"),
PaymentUnitPrice: decimalPtrFromString("50000"),
PaymentTemplateID: ptrString("TEMPLATE123"),
OrderArrivalTime: ptrInt64(1630000000),
OrderPaymentTime: ptrInt64(1620000000),
UnpaidTimeoutSecond: ptrInt64(3600),
ChainType: ptrString("ETH"),
TxHash: ptrString("0xABC123"),
FromAddress: ptrString("0xFROM123"),
ToAddress: ptrString("0xTO123"),
ChainFee: decimalPtrFromString("0.001"),
ChainFeeCrypto: ptrString("ETH"),
Memo: ptrString("Test Memo"),
OrderNote: ptrString("Test Note"),
CreateTime: 1620000000,
UpdateTime: 1630000000,
},
expected: &order.GetOrderResp{
BusinessId: "B123",
OrderType: 1,
OrderStatus: 2,
Brand: "TestBrand",
OrderUid: "UID123",
ReferenceId: "REF123",
Count: "10.5",
OrderFee: "0.5",
Amount: "100",
ReferenceBrand: ptrString("OtherBrand"),
ReferenceUid: ptrString("REFUID"),
WalletStatus: ptrInt64(1),
ThreePartyStatus: ptrInt64(2),
DirectionType: ptrInt64(1),
CryptoType: ptrString("BTC"),
ThirdPartyFee: ptrString("0.01"),
CryptoToUsdtRate: ptrString("50000"),
FiatToUsdRate: ptrString("1"),
FeeCryptoToUsdtRate: ptrString("0.02"),
UsdtToCryptoTypeRate: ptrString("0.00002"),
PaymentFiat: ptrString("USD"),
PaymentUnitPrice: ptrString("50000"),
PaymentTemplateId: ptrString("TEMPLATE123"),
OrderArrivalTime: ptrInt64(1630000000),
OrderPaymentTime: ptrInt64(1620000000),
UnpaidTimeoutSecond: ptrInt64(3600),
ChainType: ptrString("ETH"),
TxHash: ptrString("0xABC123"),
FromAddress: ptrString("0xFROM123"),
ToAddress: ptrString("0xTO123"),
ChainFee: ptrString("0.001"),
ChainFeeCrypto: ptrString("ETH"),
Memo: ptrString("Test Memo"),
OrderNote: ptrString("Test Note"),
CreateTime: 1620000000,
UpdateTime: 1630000000,
},
},
{
name: "部分欄位為 nil",
input: model.Order{
BusinessID: "B456",
OrderType: 1,
OrderStatus: 2,
Brand: "TestBrand",
OrderUID: "UID456",
ReferenceID: "REF456",
Count: decimal.RequireFromString("10"),
OrderFee: decimal.RequireFromString("1"),
Amount: decimal.RequireFromString("100"),
ReferenceBrand: nil,
ReferenceUID: nil,
WalletStatus: nil,
ThreePartyStatus: nil,
DirectionType: nil,
CryptoType: nil,
ThirdPartyFee: nil,
CryptoToUSDTRate: nil,
FiatToUSDRate: nil,
FeeCryptoToUSDTRate: nil,
USDTToCryptoTypeRate: nil,
PaymentFiat: nil,
PaymentUnitPrice: nil,
PaymentTemplateID: nil,
OrderArrivalTime: nil,
OrderPaymentTime: nil,
UnpaidTimeoutSecond: nil,
ChainType: nil,
TxHash: nil,
FromAddress: nil,
ToAddress: nil,
ChainFee: nil,
ChainFeeCrypto: nil,
Memo: nil,
OrderNote: nil,
CreateTime: 1620000000,
UpdateTime: 1630000000,
},
expected: &order.GetOrderResp{
BusinessId: "B456",
OrderType: 1,
OrderStatus: 2,
Brand: "TestBrand",
OrderUid: "UID456",
ReferenceId: "REF456",
Count: "10",
OrderFee: "1",
Amount: "100",
ReferenceBrand: nil,
ReferenceUid: nil,
WalletStatus: nil,
ThreePartyStatus: nil,
DirectionType: nil,
CryptoType: nil,
ThirdPartyFee: nil,
CryptoToUsdtRate: nil,
FiatToUsdRate: nil,
FeeCryptoToUsdtRate: nil,
UsdtToCryptoTypeRate: nil,
PaymentFiat: nil,
PaymentUnitPrice: nil,
PaymentTemplateId: nil,
OrderArrivalTime: nil,
OrderPaymentTime: nil,
UnpaidTimeoutSecond: nil,
ChainType: nil,
TxHash: nil,
FromAddress: nil,
ToAddress: nil,
ChainFee: nil,
ChainFeeCrypto: nil,
Memo: nil,
OrderNote: nil,
CreateTime: 1620000000,
UpdateTime: 1630000000,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 執行 ConvertOrderToGetOrderResp 函數
result := ConvertOrderToGetOrderResp(tt.input)
// 驗證結果
assert.Equal(t, tt.expected, result)
})
}
}
func TestListOrder(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
// 初始化 mock 依賴
mockOrderModel := mockmodel.NewMockOrderModel(ctrl)
mockValidate := mocksvc.NewMockValidate(ctrl)
// 初始化服務上下文
svcCtx := &svc.ServiceContext{
OrderModel: mockOrderModel,
Validate: mockValidate,
}
// 測試數據集
tests := []struct {
name string
input *order.ListOrderReq
prepare func()
expectErr bool
expectedRes *order.ListOrderResp
}{
{
name: "成功取得訂單列表",
input: &order.ListOrderReq{
PageIndex: 1,
PageSize: 10,
},
prepare: func() {
// 模擬驗證成功
mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1)
// 模擬返回訂單列表
mockOrderModel.EXPECT().ListOrder(gomock.Any(), gomock.Any()).Return([]model.Order{
{
BusinessID: "B123",
OrderType: 1,
OrderStatus: 2,
Brand: "TestBrand",
OrderUID: "UID123",
ReferenceID: "REF123",
Count: decimal.RequireFromString("10.5"),
OrderFee: decimal.RequireFromString("0.5"),
Amount: decimal.RequireFromString("100"),
},
}, int64(1), nil).Times(1)
},
expectErr: false,
expectedRes: &order.ListOrderResp{
Data: []*order.GetOrderResp{
{
BusinessId: "B123",
OrderType: 1,
OrderStatus: 2,
Brand: "TestBrand",
OrderUid: "UID123",
ReferenceId: "REF123",
Count: "10.5",
OrderFee: "0.5",
Amount: "100",
},
},
Page: &order.Pager{
Total: 1,
Index: 1,
Size: 10,
},
},
},
{
name: "訂單查詢失敗",
input: &order.ListOrderReq{
PageIndex: 1,
PageSize: 10,
},
prepare: func() {
// 模擬驗證成功
mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1)
// 模擬返回查詢錯誤
mockOrderModel.EXPECT().ListOrder(gomock.Any(), gomock.Any()).Return(nil, int64(0), errors.New("query failed")).Times(1)
},
expectErr: true,
},
{
name: "分頁錯誤",
input: &order.ListOrderReq{
PageIndex: 0,
PageSize: 10,
},
prepare: func() {
// 模擬驗證失敗,因為 PageIndex 為 0
mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(errors.New("invalid pagination")).Times(1)
},
expectErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 準備測試環境
tt.prepare()
// 初始化 ListOrderLogic
logic := NewListOrderLogic(context.TODO(), svcCtx)
// 執行 ListOrder
resp, err := logic.ListOrder(tt.input)
// 驗證結果
if tt.expectErr {
assert.Error(t, err)
assert.Nil(t, resp)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.expectedRes, resp)
}
})
}
}
// func TestConvertOrdersToGetOrderResp(t *testing.T) {
// tests := []struct {
// name string
// input []model.Order
// expected []*order.GetOrderResp
// }{
// {
// name: "空訂單列表",
// input: []model.Order{},
// expected: []*order.GetOrderResp{},
// },
// {
// name: "單筆訂單",
// input: []model.Order{
// {
// BusinessID: "B123",
// OrderType: 1,
// OrderStatus: 2,
// Brand: "TestBrand",
// OrderUID: "UID123",
// ReferenceID: "REF123",
// Count: decimal.RequireFromString("10.5"),
// OrderFee: decimal.RequireFromString("0.5"),
// Amount: decimal.RequireFromString("100"),
// },
// },
// expected: []*order.GetOrderResp{
// {
// BusinessId: "B123",
// OrderType: 1,
// OrderStatus: 2,
// Brand: "TestBrand",
// OrderUid: "UID123",
// ReferenceId: "REF123",
// Count: "10.5",
// OrderFee: "0.5",
// Amount: "100",
// },
// },
// },
// {
// name: "多筆訂單",
// input: []model.Order{
// {
// BusinessID: "B123",
// OrderType: 1,
// OrderStatus: 2,
// Brand: "TestBrand",
// OrderUID: "UID123",
// ReferenceID: "REF123",
// Count: decimal.RequireFromString("10.5"),
// OrderFee: decimal.RequireFromString("0.5"),
// Amount: decimal.RequireFromString("100"),
// },
// {
// BusinessID: "B456",
// OrderType: 2,
// OrderStatus: 3,
// Brand: "OtherBrand",
// OrderUID: "UID456",
// ReferenceID: "REF456",
// Count: decimal.RequireFromString("20"),
// OrderFee: decimal.RequireFromString("1"),
// Amount: decimal.RequireFromString("200"),
// },
// },
// expected: []*order.GetOrderResp{
// {
// BusinessId: "B123",
// OrderType: 1,
// OrderStatus: 2,
// Brand: "TestBrand",
// OrderUid: "UID123",
// ReferenceId: "REF123",
// Count: "10.5",
// OrderFee: "0.5",
// Amount: "100",
// },
// {
// BusinessId: "B456",
// OrderType: 2,
// OrderStatus: 3,
// Brand: "OtherBrand",
// OrderUid: "UID456",
// ReferenceId: "REF456",
// Count: "20",
// OrderFee: "1",
// Amount: "200",
// },
// },
// },
// }
//
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// // 執行 ConvertOrdersToGetOrderResp 函數
// result := ConvertOrdersToGetOrderResp(tt.input)
//
// // 驗證結果
// assert.Equal(t, tt.expected, result)
// })
// }
// }
//
// func TestOptionalString(t *testing.T) {
// t.Run("非 nil 字串", func(t *testing.T) {
// str := "hello"
// result := optionalString(&str)
// assert.NotNil(t, result)
// assert.Equal(t, &str, result)
// })
//
// t.Run("nil 字串", func(t *testing.T) {
// result := optionalString(nil)
// assert.Nil(t, result)
// })
// }
//
// func TestOptionalInt64(t *testing.T) {
// t.Run("非 nil int64", func(t *testing.T) {
// num := int64(123)
// result := optionalInt64(&num)
// assert.NotNil(t, result)
// assert.Equal(t, &num, result)
// })
//
// t.Run("nil int64", func(t *testing.T) {
// result := optionalInt64(nil)
// assert.Nil(t, result)
// })
// }
//
// func TestOptionalDecimalToString(t *testing.T) {
// t.Run("非 nil decimal", func(t *testing.T) {
// dec := decimal.NewFromInt(123)
// expected := "123"
// result := optionalDecimalToString(&dec)
// assert.NotNil(t, result)
// assert.Equal(t, &expected, result)
// })
//
// t.Run("nil decimal", func(t *testing.T) {
// result := optionalDecimalToString(nil)
// assert.Nil(t, result)
// })
// }
//
// func TestConvertOrderToGetOrderResp(t *testing.T) {
// tests := []struct {
// name string
// input model.Order
// expected *order.GetOrderResp
// }{
// {
// name: "所有欄位都有值",
// input: model.Order{
// BusinessID: "B123",
// OrderType: 1,
// OrderStatus: 2,
// Brand: "TestBrand",
// OrderUID: "UID123",
// ReferenceID: "REF123",
// Count: decimal.RequireFromString("10.5"),
// OrderFee: decimal.RequireFromString("0.5"),
// Amount: decimal.RequireFromString("100"),
// ReferenceBrand: ptrString("OtherBrand"),
// ReferenceUID: ptrString("REFUID"),
// WalletStatus: ptrInt64(1),
// ThreePartyStatus: ptrInt64(2),
// DirectionType: ptrInt64(1),
// CryptoType: ptrString("BTC"),
// ThirdPartyFee: decimalPtrFromString("0.01"),
// CryptoToUSDTRate: decimalPtrFromString("50000"),
// FiatToUSDRate: decimalPtrFromString("1"),
// FeeCryptoToUSDTRate: decimalPtrFromString("0.02"),
// USDTToCryptoTypeRate: decimalPtrFromString("0.00002"),
// PaymentFiat: ptrString("USD"),
// PaymentUnitPrice: decimalPtrFromString("50000"),
// PaymentTemplateID: ptrString("TEMPLATE123"),
// OrderArrivalTime: ptrInt64(1630000000),
// OrderPaymentTime: ptrInt64(1620000000),
// UnpaidTimeoutSecond: ptrInt64(3600),
// ChainType: ptrString("ETH"),
// TxHash: ptrString("0xABC123"),
// FromAddress: ptrString("0xFROM123"),
// ToAddress: ptrString("0xTO123"),
// ChainFee: decimalPtrFromString("0.001"),
// ChainFeeCrypto: ptrString("ETH"),
// Memo: ptrString("Test Memo"),
// OrderNote: ptrString("Test Note"),
// CreateTime: 1620000000,
// UpdateTime: 1630000000,
// },
// expected: &order.GetOrderResp{
// BusinessId: "B123",
// OrderType: 1,
// OrderStatus: 2,
// Brand: "TestBrand",
// OrderUid: "UID123",
// ReferenceId: "REF123",
// Count: "10.5",
// OrderFee: "0.5",
// Amount: "100",
// ReferenceBrand: ptrString("OtherBrand"),
// ReferenceUid: ptrString("REFUID"),
// WalletStatus: ptrInt64(1),
// ThreePartyStatus: ptrInt64(2),
// DirectionType: ptrInt64(1),
// CryptoType: ptrString("BTC"),
// ThirdPartyFee: ptrString("0.01"),
// CryptoToUsdtRate: ptrString("50000"),
// FiatToUsdRate: ptrString("1"),
// FeeCryptoToUsdtRate: ptrString("0.02"),
// UsdtToCryptoTypeRate: ptrString("0.00002"),
// PaymentFiat: ptrString("USD"),
// PaymentUnitPrice: ptrString("50000"),
// PaymentTemplateId: ptrString("TEMPLATE123"),
// OrderArrivalTime: ptrInt64(1630000000),
// OrderPaymentTime: ptrInt64(1620000000),
// UnpaidTimeoutSecond: ptrInt64(3600),
// ChainType: ptrString("ETH"),
// TxHash: ptrString("0xABC123"),
// FromAddress: ptrString("0xFROM123"),
// ToAddress: ptrString("0xTO123"),
// ChainFee: ptrString("0.001"),
// ChainFeeCrypto: ptrString("ETH"),
// Memo: ptrString("Test Memo"),
// OrderNote: ptrString("Test Note"),
// CreateTime: 1620000000,
// UpdateTime: 1630000000,
// },
// },
// {
// name: "部分欄位為 nil",
// input: model.Order{
// BusinessID: "B456",
// OrderType: 1,
// OrderStatus: 2,
// Brand: "TestBrand",
// OrderUID: "UID456",
// ReferenceID: "REF456",
// Count: decimal.RequireFromString("10"),
// OrderFee: decimal.RequireFromString("1"),
// Amount: decimal.RequireFromString("100"),
// ReferenceBrand: nil,
// ReferenceUID: nil,
// WalletStatus: nil,
// ThreePartyStatus: nil,
// DirectionType: nil,
// CryptoType: nil,
// ThirdPartyFee: nil,
// CryptoToUSDTRate: nil,
// FiatToUSDRate: nil,
// FeeCryptoToUSDTRate: nil,
// USDTToCryptoTypeRate: nil,
// PaymentFiat: nil,
// PaymentUnitPrice: nil,
// PaymentTemplateID: nil,
// OrderArrivalTime: nil,
// OrderPaymentTime: nil,
// UnpaidTimeoutSecond: nil,
// ChainType: nil,
// TxHash: nil,
// FromAddress: nil,
// ToAddress: nil,
// ChainFee: nil,
// ChainFeeCrypto: nil,
// Memo: nil,
// OrderNote: nil,
// CreateTime: 1620000000,
// UpdateTime: 1630000000,
// },
// expected: &order.GetOrderResp{
// BusinessId: "B456",
// OrderType: 1,
// OrderStatus: 2,
// Brand: "TestBrand",
// OrderUid: "UID456",
// ReferenceId: "REF456",
// Count: "10",
// OrderFee: "1",
// Amount: "100",
// ReferenceBrand: nil,
// ReferenceUid: nil,
// WalletStatus: nil,
// ThreePartyStatus: nil,
// DirectionType: nil,
// CryptoType: nil,
// ThirdPartyFee: nil,
// CryptoToUsdtRate: nil,
// FiatToUsdRate: nil,
// FeeCryptoToUsdtRate: nil,
// UsdtToCryptoTypeRate: nil,
// PaymentFiat: nil,
// PaymentUnitPrice: nil,
// PaymentTemplateId: nil,
// OrderArrivalTime: nil,
// OrderPaymentTime: nil,
// UnpaidTimeoutSecond: nil,
// ChainType: nil,
// TxHash: nil,
// FromAddress: nil,
// ToAddress: nil,
// ChainFee: nil,
// ChainFeeCrypto: nil,
// Memo: nil,
// OrderNote: nil,
// CreateTime: 1620000000,
// UpdateTime: 1630000000,
// },
// },
// }
//
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// // 執行 ConvertOrderToGetOrderResp 函數
// result := ConvertOrderToGetOrderResp(tt.input)
//
// // 驗證結果
// assert.Equal(t, tt.expected, result)
// })
// }
// }
//
// func TestListOrder(t *testing.T) {
// ctrl := gomock.NewController(t)
// defer ctrl.Finish()
//
// // 初始化 mock 依賴
// mockOrderModel := mockmodel.NewMockOrderModel(ctrl)
// mockValidate := mocksvc.NewMockValidate(ctrl)
//
// // 初始化服務上下文
// svcCtx := &svc.ServiceContext{
// OrderModel: mockOrderModel,
// Validate: mockValidate,
// }
//
// // 測試數據集
// tests := []struct {
// name string
// input *order.ListOrderReq
// prepare func()
// expectErr bool
// expectedRes *order.ListOrderResp
// }{
// {
// name: "成功取得訂單列表",
// input: &order.ListOrderReq{
// PageIndex: 1,
// PageSize: 10,
// },
// prepare: func() {
// // 模擬驗證成功
// mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1)
// // 模擬返回訂單列表
// mockOrderModel.EXPECT().ListOrder(gomock.Any(), gomock.Any()).Return([]model.Order{
// {
// BusinessID: "B123",
// OrderType: 1,
// OrderStatus: 2,
// Brand: "TestBrand",
// OrderUID: "UID123",
// ReferenceID: "REF123",
// Count: decimal.RequireFromString("10.5"),
// OrderFee: decimal.RequireFromString("0.5"),
// Amount: decimal.RequireFromString("100"),
// },
// }, int64(1), nil).Times(1)
// },
// expectErr: false,
// expectedRes: &order.ListOrderResp{
// Data: []*order.GetOrderResp{
// {
// BusinessId: "B123",
// OrderType: 1,
// OrderStatus: 2,
// Brand: "TestBrand",
// OrderUid: "UID123",
// ReferenceId: "REF123",
// Count: "10.5",
// OrderFee: "0.5",
// Amount: "100",
// },
// },
// Page: &order.Pager{
// Total: 1,
// Index: 1,
// Size: 10,
// },
// },
// },
// {
// name: "訂單查詢失敗",
// input: &order.ListOrderReq{
// PageIndex: 1,
// PageSize: 10,
// },
// prepare: func() {
// // 模擬驗證成功
// mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1)
// // 模擬返回查詢錯誤
// mockOrderModel.EXPECT().ListOrder(gomock.Any(), gomock.Any()).Return(nil, int64(0), errors.New("query failed")).Times(1)
// },
// expectErr: true,
// },
// {
// name: "分頁錯誤",
// input: &order.ListOrderReq{
// PageIndex: 0,
// PageSize: 10,
// },
// prepare: func() {
// // 模擬驗證失敗,因為 PageIndex 為 0
// mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(errors.New("invalid pagination")).Times(1)
// },
// expectErr: true,
// },
// }
//
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// // 準備測試環境
// tt.prepare()
//
// // 初始化 ListOrderLogic
// logic := NewListOrderLogic(context.TODO(), svcCtx)
//
// // 執行 ListOrder
// resp, err := logic.ListOrder(tt.input)
//
// // 驗證結果
// if tt.expectErr {
// assert.Error(t, err)
// assert.Nil(t, resp)
// } else {
// assert.NoError(t, err)
// assert.Equal(t, tt.expectedRes, resp)
// }
// })
// }
// }

View File

@ -1,49 +1,47 @@
package model
import (
"github.com/shopspring/decimal"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type Order struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
UpdateTime int64 `bson:"update_time"`
CreateTime int64 `bson:"create_time"`
BusinessID string `bson:"business_id"` // 訂單業務流水號
OrderType int8 `bson:"order_type"` // 訂單類型
OrderStatus int8 `bson:"order_status"` // 訂單狀態 0.建立訂單 1.建單失敗 2.審核中 3.付款中 4.已付款 5.已付款待轉帳 6.申訴中 7.交易完成 8.交易失敗 9.交易取消 10.交易異常 11.交易超時
Brand string `bson:"brand"` // 下單平台(混合也可用)
OrderUID string `bson:"order_uid"` // 下單用戶 UID
ReferenceID string `bson:"reference_id"` // 訂單來源(用)
Count decimal.Decimal `bson:"count"` // 訂單數量
OrderFee decimal.Decimal `bson:"order_fee"` // 訂單手續費
Amount decimal.Decimal `bson:"amount"` // 單價
// 下面的是未來擴充用,加密貨幣用,或者幣別轉換用,普通訂單用不到
ReferenceBrand *string `bson:"reference_brand"` // 訂單來源平台
ReferenceUID *string `bson:"reference_uid"` // 訂單來源用戶 UID
WalletStatus *int64 `bson:"wallet_status,omitempty"` // 交易金額狀態 1.未凍結 2.已凍結 3.解凍(扣錢) 4.未增加資產 5.已增加資產 6.解凍還原 7.限制(將凍結餘額轉至限制餘額)
ThreePartyStatus *int64 `bson:"three_party_status,omitempty"` // 三方請求狀態 1.已發送 2.通知處理中 3.通知已完成
DirectionType *int64 `bson:"direction_type,omitempty"` // 交易方向 1.買入 2.賣出
CryptoType *string `bson:"crypto_type,omitempty"` // 交易幣種
ThirdPartyFee *decimal.Decimal `bson:"third_party_fee,omitempty"` // 第三方手續費
CryptoToUSDTRate *decimal.Decimal `bson:"crypto_to_usdt_rate,omitempty"` // 交易幣種 對 USDT 匯率
FiatToUSDRate *decimal.Decimal `bson:"fiat_to_usd_rate,omitempty"` // 法幣 對 USD 匯率
FeeCryptoToUSDTRate *decimal.Decimal `bson:"fee_crypto_to_usdt_rate,omitempty"` // 手續費幣種 對 USDT 匯率
USDTToCryptoTypeRate *decimal.Decimal `bson:"usdt_to_crypto_type_rate,omitempty"` // USDT 對 交易幣種 匯率
PaymentFiat *string `bson:"payment_fiat,omitempty"` // 支付法幣
PaymentUnitPrice *decimal.Decimal `bson:"payment_unit_price,omitempty"` // crypto 單價
PaymentTemplateID *string `bson:"payment_template_id,omitempty"` // 支付方式配置 ID
OrderArrivalTime *int64 `bson:"order_arrival_time,omitempty"` // 訂單到帳時間/充值到帳時間
OrderPaymentTime *int64 `bson:"order_payment_time,omitempty"` // 訂單付款時間/鏈上成功或失敗時間
UnpaidTimeoutSecond *int64 `bson:"unpaid_timeout_second,omitempty"` // 支付期限秒數
ChainType *string `bson:"chain_type,omitempty"` // 主網類型
TxHash *string `bson:"tx_hash,omitempty"` // 交易哈希
FromAddress *string `bson:"from_address,omitempty"` // 來源地址
ToAddress *string `bson:"to_address,omitempty"` // 目標地址
ChainFee *decimal.Decimal `bson:"chain_fee,omitempty"` // 鏈上交易手續費
ChainFeeCrypto *string `bson:"chain_fee_crypto,omitempty"` // 鏈上手續費使用幣別
Memo *string `bson:"memo,omitempty"` // 鏈上備註
OrderNote *string `bson:"order_note,omitempty"` // 訂單交易備註
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
UpdateTime int64 `bson:"update_time"`
CreateTime int64 `bson:"create_time"`
BusinessID string `bson:"business_id"` // 訂單業務流水號
OrderType int8 `bson:"order_type"` // 訂單類型
OrderStatus int8 `bson:"order_status"` // 訂單狀態
Brand string `bson:"brand"` // 下單平台
OrderUID string `bson:"order_uid"` // 下單用戶 UID
ReferenceID string `bson:"reference_id"` // 訂單來源
Count primitive.Decimal128 `bson:"count"` // 訂單數量
OrderFee primitive.Decimal128 `bson:"order_fee"` // 訂單手續費
Amount primitive.Decimal128 `bson:"amount"` // 單價
ReferenceBrand *string `bson:"reference_brand,omitempty"` // 訂單來源平台
ReferenceUID *string `bson:"reference_uid,omitempty"` // 訂單來源用戶 UID
WalletStatus *int64 `bson:"wallet_status,omitempty"` // 交易金額狀態
ThreePartyStatus *int64 `bson:"three_party_status,omitempty"` // 三方請求狀態
DirectionType *int64 `bson:"direction_type,omitempty"` // 交易方向
CryptoType *string `bson:"crypto_type,omitempty"` // 交易幣種
ThirdPartyFee *primitive.Decimal128 `bson:"third_party_fee,omitempty"` // 第三方手續費
CryptoToUSDTRate *primitive.Decimal128 `bson:"crypto_to_usdt_rate,omitempty"` // 加密貨幣對 USDT 匯率
FiatToUSDRate *primitive.Decimal128 `bson:"fiat_to_usd_rate,omitempty"` // 法幣對 USD 匯率
FeeCryptoToUSDTRate *primitive.Decimal128 `bson:"fee_crypto_to_usdt_rate,omitempty"` // 手續費加密貨幣對 USDT 匯率
USDTToCryptoTypeRate *primitive.Decimal128 `bson:"usdt_to_crypto_type_rate,omitempty"` // USDT 對加密貨幣匯率
PaymentFiat *string `bson:"payment_fiat,omitempty"` // 支付法幣
PaymentUnitPrice *primitive.Decimal128 `bson:"payment_unit_price,omitempty"` // 加密貨幣單價
PaymentTemplateID *string `bson:"payment_template_id,omitempty"` // 支付方式配置 ID
OrderArrivalTime *int64 `bson:"order_arrival_time,omitempty"` // 訂單到帳時間
OrderPaymentTime *int64 `bson:"order_payment_time,omitempty"` // 訂單付款時間
UnpaidTimeoutSecond *int64 `bson:"unpaid_timeout_second,omitempty"` // 支付期限秒數
ChainType *string `bson:"chain_type,omitempty"` // 主網類型
TxHash *string `bson:"tx_hash,omitempty"` // 交易哈希
FromAddress *string `bson:"from_address,omitempty"` // 來源地址
ToAddress *string `bson:"to_address,omitempty"` // 目標地址
ChainFee *primitive.Decimal128 `bson:"chain_fee,omitempty"` // 鏈上交易手續費
ChainFeeCrypto *string `bson:"chain_fee_crypto,omitempty"` // 鏈上手續費使用幣別
Memo *string `bson:"memo,omitempty"` // 鏈上備註
OrderNote *string `bson:"order_note,omitempty"` // 訂單交易備註
}
func (p *Order) CollectionName() string {