529 lines
14 KiB
Go
529 lines
14 KiB
Go
package usecase
|
|
|
|
import (
|
|
"app-cloudep-trade-service/internal/domain"
|
|
"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"
|
|
|
|
"reflect"
|
|
"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: domain.OrderStatusCancelled, // 使用模擬的狀態
|
|
}
|
|
|
|
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: domain.OrderTypeTest,
|
|
OrderStatus: domain.OrderStatusCreated,
|
|
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: domain.OrderTypeTest,
|
|
OrderStatus: domain.OrderStatusCreated,
|
|
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(domain.OrderStatusCreated)},
|
|
}
|
|
|
|
mockOrders := []model.Order{
|
|
{
|
|
BusinessID: "business_123",
|
|
OrderUID: "user_123",
|
|
OrderStatus: domain.OrderStatusCreated,
|
|
// 其他欄位根據需要填充
|
|
},
|
|
}
|
|
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(domain.OrderStatusCancelled),
|
|
}
|
|
|
|
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)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOrderUseCase_convertOrdersToResponses(t *testing.T) {
|
|
type fields struct {
|
|
OrderModel model.OrderModel
|
|
}
|
|
type args struct {
|
|
orders []model.Order
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
want []*usecase.GetOrderResp
|
|
}{
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
o := &OrderUseCase{
|
|
OrderModel: tt.fields.OrderModel,
|
|
}
|
|
if got := o.convertOrdersToResponses(tt.args.orders); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("convertOrdersToResponses() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|