app-cloudep-trade-service/internal/usecase/order_test.go

501 lines
14 KiB
Go

package usecase
import (
"app-cloudep-trade-service/internal/domain/order"
"app-cloudep-trade-service/internal/domain/usecase"
mockmodel "app-cloudep-trade-service/internal/mock/model"
model "app-cloudep-trade-service/internal/model/mongo"
"context"
"errors"
"time"
"github.com/go-playground/assert/v2"
"github.com/shopspring/decimal"
"github.com/zeromicro/go-zero/core/stores/mon"
"go.uber.org/mock/gomock"
"testing"
)
func TestOrderUseCase_CancelOrder(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
// 初始化 mock 依賴
mockOrderModel := mockmodel.NewMockOrderModel(ctrl)
orderUseCase := &OrderUseCase{
OrderModel: mockOrderModel,
}
cancelOrderQuery := usecase.CancelOrderQuery{
BusinessID: "business_123",
Status: order.Cancelled, // 使用模擬的狀態
}
tests := []struct {
name string
mockSetup func()
param usecase.CancelOrderQuery
wantErr bool
}{
{
name: "successful order cancellation",
mockSetup: func() {
mockOrderModel.EXPECT().UpdateStatus(gomock.Any(), model.UpdateStatusReq{
BusinessID: cancelOrderQuery.BusinessID,
Status: cancelOrderQuery.Status.ToInt64(),
}).Return(nil, nil)
},
param: cancelOrderQuery,
wantErr: false,
},
{
name: "failed order cancellation",
mockSetup: func() {
mockOrderModel.EXPECT().UpdateStatus(gomock.Any(), model.UpdateStatusReq{
BusinessID: cancelOrderQuery.BusinessID,
Status: cancelOrderQuery.Status.ToInt64(),
}).Return(nil, errors.New("update error"))
},
param: cancelOrderQuery,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup() // 設置每個測試用例的 mock 行為
err := orderUseCase.CancelOrder(context.Background(), tt.param)
if (err != nil) != tt.wantErr {
t.Errorf("CancelOrder() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestOrderUseCase_CreateOrder(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
// 初始化 mock 依賴
mockOrderModel := mockmodel.NewMockOrderModel(mockCtrl)
orderUseCase := &OrderUseCase{
OrderModel: mockOrderModel,
}
now := time.Now().UTC().UnixNano()
// 構建測試參數
createOrderReq := usecase.CreateOrderReq{
BusinessID: "business_123",
OrderType: order.TestType,
OrderStatus: order.Created,
Brand: "test_brand",
OrderUID: "user_123",
ReferenceID: "reference_123",
Count: decimal.NewFromInt(2),
OrderFee: decimal.NewFromFloat(0.01),
Amount: decimal.NewFromFloat(100.0),
ReferenceBrand: StringPtr("reference_brand"),
ReferenceUID: StringPtr("reference_uid"),
WalletStatus: 1,
ThreePartyStatus: Int64Ptr(2),
DirectionType: 1,
CryptoType: StringPtr("BTC"),
PaymentFiat: StringPtr("USD"),
PaymentTemplateID: StringPtr("template_001"),
OrderArrivalTime: Int64Ptr(now),
OrderPaymentTime: Int64Ptr(now),
UnpaidTimeoutSecond: Int64Ptr(3600),
ChainType: StringPtr("mainnet"),
TxHash: StringPtr("tx_hash_123"),
FromAddress: StringPtr("from_address"),
ToAddress: StringPtr("to_address"),
ChainFeeCrypto: StringPtr("ETH"),
Memo: StringPtr("test memo"),
OrderNote: StringPtr("test order note"),
}
tests := []struct {
name string
mockSetup func()
param usecase.CreateOrderReq
wantErr bool
}{
{
name: "successful order creation",
mockSetup: func() {
mockOrderModel.EXPECT().Insert(gomock.Any(), gomock.Any()).Return(nil)
},
param: createOrderReq,
wantErr: false,
},
{
name: "failed order creation",
mockSetup: func() {
mockOrderModel.EXPECT().Insert(gomock.Any(), gomock.Any()).Return(errors.New("insert error"))
},
param: createOrderReq,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup() // 設置每個測試用例的 mock 行為
err := orderUseCase.CreateOrder(context.Background(), tt.param)
if (err != nil) != tt.wantErr {
t.Errorf("CreateOrder() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestOrderUseCase_DeleteOrder(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
// 初始化 mock 依賴
mockOrderModel := mockmodel.NewMockOrderModel(ctrl)
orderUseCase := &OrderUseCase{
OrderModel: mockOrderModel,
}
// 構建測試參數
deleteOrderQuery := usecase.DeleteOrderQuery{
BusinessID: "business_123",
}
tests := []struct {
name string
mockSetup func()
param usecase.DeleteOrderQuery
wantErr bool
}{
{
name: "successful order deletion",
mockSetup: func() {
mockOrderModel.EXPECT().DeleteByBusinessID(gomock.Any(), deleteOrderQuery.BusinessID).Return(nil, nil)
},
param: deleteOrderQuery,
wantErr: false,
},
{
name: "failed order deletion",
mockSetup: func() {
mockOrderModel.EXPECT().DeleteByBusinessID(gomock.Any(), deleteOrderQuery.BusinessID).Return(nil, errors.New("delete error"))
},
param: deleteOrderQuery,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup() // 設置每個測試用例的 mock 行為
err := orderUseCase.DeleteOrder(context.Background(), tt.param)
if (err != nil) != tt.wantErr {
t.Errorf("DeleteOrder() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestOrderUseCase_GetOrder(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
// 初始化 mock 依賴
mockOrderModel := mockmodel.NewMockOrderModel(mockCtrl)
orderUseCase := &OrderUseCase{
OrderModel: mockOrderModel,
}
getOrderQuery := usecase.GetOrderQuery{
BusinessID: "business_123",
}
// 構建測試用例返回的 Order
mockOrder := &model.Order{
UpdateTime: 123456789,
CreateTime: 123456789,
BusinessID: "business_123",
OrderType: order.TestType,
OrderStatus: order.Created,
Brand: "test_brand",
OrderUID: "user_123",
ReferenceID: "reference_123",
Count: decimal.NewFromInt(2),
OrderFee: decimal.NewFromFloat(0.01),
Amount: decimal.NewFromFloat(100.0),
ReferenceBrand: StringPtr("reference_brand"),
ReferenceUID: StringPtr("reference_uid"),
WalletStatus: 1,
ThreePartyStatus: Int64Ptr(2),
DirectionType: 1,
CryptoType: StringPtr("BTC"),
PaymentFiat: StringPtr("USD"),
PaymentTemplateID: StringPtr("template_001"),
OrderArrivalTime: Int64Ptr(123456789),
OrderPaymentTime: Int64Ptr(123456789),
UnpaidTimeoutSecond: Int64Ptr(3600),
ChainType: StringPtr("mainnet"),
TxHash: StringPtr("tx_hash_123"),
FromAddress: StringPtr("from_address"),
ToAddress: StringPtr("to_address"),
ChainFeeCrypto: StringPtr("ETH"),
Memo: StringPtr("test memo"),
OrderNote: StringPtr("test order note"),
}
tests := []struct {
name string
mockSetup func()
param usecase.GetOrderQuery
wantResp *usecase.GetOrderResp
wantErr bool
}{
{
name: "successful order retrieval",
mockSetup: func() {
mockOrderModel.EXPECT().FindOneBusinessID(gomock.Any(), getOrderQuery.BusinessID).Return(mockOrder, nil)
},
param: getOrderQuery,
wantResp: &usecase.GetOrderResp{ // 构建预期响应
UpdateTime: mockOrder.UpdateTime,
CreateTime: mockOrder.CreateTime,
BusinessID: mockOrder.BusinessID,
OrderType: mockOrder.OrderType,
OrderStatus: mockOrder.OrderStatus,
Brand: mockOrder.Brand,
OrderUID: mockOrder.OrderUID,
ReferenceID: mockOrder.ReferenceID,
Count: mockOrder.Count.String(),
OrderFee: mockOrder.OrderFee.String(),
Amount: mockOrder.Amount.String(),
ReferenceBrand: mockOrder.ReferenceBrand,
ReferenceUID: mockOrder.ReferenceUID,
WalletStatus: Int64Ptr(mockOrder.WalletStatus),
ThreePartyStatus: mockOrder.ThreePartyStatus,
DirectionType: Int64Ptr(mockOrder.DirectionType),
CryptoType: mockOrder.CryptoType,
PaymentFiat: mockOrder.PaymentFiat,
PaymentTemplateID: mockOrder.PaymentTemplateID,
OrderArrivalTime: mockOrder.OrderArrivalTime,
OrderPaymentTime: mockOrder.OrderPaymentTime,
UnpaidTimeoutSecond: mockOrder.UnpaidTimeoutSecond,
ChainType: mockOrder.ChainType,
TxHash: mockOrder.TxHash,
FromAddress: mockOrder.FromAddress,
ToAddress: mockOrder.ToAddress,
ChainFeeCrypto: mockOrder.ChainFeeCrypto,
Memo: mockOrder.Memo,
OrderNote: mockOrder.OrderNote,
},
wantErr: false,
},
{
name: "order not found",
mockSetup: func() {
mockOrderModel.EXPECT().FindOneBusinessID(gomock.Any(), getOrderQuery.BusinessID).Return(nil, mon.ErrNotFound)
},
param: getOrderQuery,
wantResp: nil,
wantErr: true,
},
{
name: "database error",
mockSetup: func() {
mockOrderModel.EXPECT().FindOneBusinessID(gomock.Any(), getOrderQuery.BusinessID).Return(nil, errors.New("database error"))
},
param: getOrderQuery,
wantResp: nil,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup() // 設置每個測試用例的 mock 行為
resp, err := orderUseCase.GetOrder(context.Background(), tt.param)
if (err != nil) != tt.wantErr {
t.Errorf("GetOrder() error = %v, wantErr %v", err, tt.wantErr)
return
}
assert.Equal(t, tt.wantResp, resp)
})
}
}
func TestOrderUseCase_ListOrder(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockOrderModel := mockmodel.NewMockOrderModel(mockCtrl)
orderUseCase := &OrderUseCase{
OrderModel: mockOrderModel,
}
listOrderQuery := usecase.GetOrderListReq{
PageIndex: 1,
PageSize: 10,
BusinessID: "business_123",
OrderStatus: []int64{int64(order.Created)},
}
mockOrders := []model.Order{
{
BusinessID: "business_123",
OrderUID: "user_123",
OrderStatus: order.Created,
// 其他欄位根據需要填充
},
}
mockTotal := int64(1)
tests := []struct {
name string
mockSetup func()
param usecase.GetOrderListReq
wantResp *usecase.ListOrderResp
wantErr bool
}{
{
name: "successful order listing",
mockSetup: func() {
mockOrderModel.EXPECT().ListOrder(gomock.Any(), gomock.Any()).Return(mockOrders, mockTotal, nil)
},
param: listOrderQuery,
wantResp: &usecase.ListOrderResp{
Data: orderUseCase.convertOrdersToResponses(mockOrders),
Page: &usecase.Pager{
Total: mockTotal,
Index: listOrderQuery.PageIndex,
Size: listOrderQuery.PageSize,
},
},
wantErr: false,
},
{
name: "order listing error",
mockSetup: func() {
mockOrderModel.EXPECT().ListOrder(gomock.Any(), gomock.Any()).Return(nil, int64(0), errors.New("listing error"))
},
param: listOrderQuery,
wantResp: nil,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
resp, err := orderUseCase.ListOrder(context.Background(), tt.param)
if (err != nil) != tt.wantErr {
t.Errorf("ListOrder() error = %v, wantErr %v", err, tt.wantErr)
return
}
assert.Equal(t, tt.wantResp, resp)
})
}
}
func TestOrderUseCase_ModifyOrderStatus(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockOrderModel := mockmodel.NewMockOrderModel(mockCtrl)
orderUseCase := &OrderUseCase{
OrderModel: mockOrderModel,
}
modifyOrderQuery := &usecase.ModifyOrderQuery{
BusinessID: "business_123",
Status: int64(order.Cancelled),
}
tests := []struct {
name string
mockSetup func()
param *usecase.ModifyOrderQuery
wantErr bool
}{
{
name: "successful order status modification",
mockSetup: func() {
mockOrderModel.EXPECT().UpdateStatus(gomock.Any(), model.UpdateStatusReq{
BusinessID: modifyOrderQuery.BusinessID,
Status: modifyOrderQuery.Status,
}).Return(nil, nil)
},
param: modifyOrderQuery,
wantErr: false,
},
{
name: "order status modification error",
mockSetup: func() {
mockOrderModel.EXPECT().UpdateStatus(gomock.Any(), model.UpdateStatusReq{
BusinessID: modifyOrderQuery.BusinessID,
Status: modifyOrderQuery.Status,
}).Return(nil, errors.New("update error"))
},
param: modifyOrderQuery,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
err := orderUseCase.ModifyOrderStatus(context.Background(), tt.param)
if (err != nil) != tt.wantErr {
t.Errorf("ModifyOrderStatus() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestOrderUseCase_OrderStatusTimeout(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockOrderModel := mockmodel.NewMockOrderModel(mockCtrl)
orderUseCase := &OrderUseCase{
OrderModel: mockOrderModel,
}
tests := []struct {
name string
mockSetup func()
wantErr bool
}{
{
name: "successful timeout update",
mockSetup: func() {
mockOrderModel.EXPECT().UpdateTimeoutOrder(gomock.Any(), gomock.Any()).Return(nil, nil)
},
wantErr: false,
},
{
name: "timeout update error",
mockSetup: func() {
mockOrderModel.EXPECT().UpdateTimeoutOrder(gomock.Any(), gomock.Any()).Return(nil, errors.New("timeout error"))
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
err := orderUseCase.OrderStatusTimeout(context.Background())
if (err != nil) != tt.wantErr {
t.Errorf("OrderStatusTimeout() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}