add order usecase
This commit is contained in:
parent
67ccb9433c
commit
008f40a898
2
go.mod
2
go.mod
|
@ -5,10 +5,12 @@ go 1.22.3
|
||||||
require (
|
require (
|
||||||
code.30cm.net/digimon/library-go/errs v1.2.5
|
code.30cm.net/digimon/library-go/errs v1.2.5
|
||||||
code.30cm.net/digimon/library-go/validator v1.0.0
|
code.30cm.net/digimon/library-go/validator v1.0.0
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0
|
||||||
github.com/go-playground/validator/v10 v10.22.0
|
github.com/go-playground/validator/v10 v10.22.0
|
||||||
github.com/shopspring/decimal v1.4.0
|
github.com/shopspring/decimal v1.4.0
|
||||||
github.com/zeromicro/go-zero v1.7.3
|
github.com/zeromicro/go-zero v1.7.3
|
||||||
go.mongodb.org/mongo-driver v1.17.1
|
go.mongodb.org/mongo-driver v1.17.1
|
||||||
|
go.uber.org/mock v0.5.0
|
||||||
google.golang.org/grpc v1.67.1
|
google.golang.org/grpc v1.67.1
|
||||||
google.golang.org/protobuf v1.35.1
|
google.golang.org/protobuf v1.35.1
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,6 +23,10 @@ const (
|
||||||
|
|
||||||
type OrderType int64
|
type OrderType int64
|
||||||
|
|
||||||
|
const (
|
||||||
|
OrderTypeTest OrderType = 0 // 測試訂單
|
||||||
|
)
|
||||||
|
|
||||||
func (o *OrderType) ToInt() int {
|
func (o *OrderType) ToInt() int {
|
||||||
return int(*o)
|
return int(*o)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-trade-service/internal/domain"
|
||||||
|
"app-cloudep-trade-service/internal/domain/usecase"
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||||
|
@ -23,9 +26,30 @@ func NewCancelOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Cance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CancelOrderQuery 1.建單失敗 9.交易取消 10.交易異常
|
||||||
|
type CancelOrderQuery struct {
|
||||||
|
BusinessID string `json:"business_id" validate:"required"`
|
||||||
|
Status int64 `json:"status" validate:"required,oneof=1 9 10"`
|
||||||
|
}
|
||||||
|
|
||||||
// CancelOrder 取消訂單
|
// CancelOrder 取消訂單
|
||||||
func (l *CancelOrderLogic) CancelOrder(in *trade.CancelOrderReq) (*trade.OKResp, error) {
|
func (l *CancelOrderLogic) CancelOrder(in *trade.CancelOrderReq) (*trade.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&CancelOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
Status: in.GetStatus(),
|
||||||
|
}); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err := l.svcCtx.OrderUseCase.CancelOrder(l.ctx, usecase.CancelOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
Status: domain.OrderStatus(in.GetStatus()),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &trade.OKResp{}, nil
|
return &trade.OKResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-trade-service/internal/domain"
|
||||||
|
"app-cloudep-trade-service/internal/domain/usecase"
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
|
||||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||||
"app-cloudep-trade-service/internal/svc"
|
"app-cloudep-trade-service/internal/svc"
|
||||||
|
@ -23,9 +27,213 @@ func NewCreateOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Creat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type createOrderReq struct { // 訂單ID
|
||||||
|
BusinessID string `json:"business_id" validate:"required"` // 訂單業務流水號
|
||||||
|
OrderType int8 `json:"order_type" validate:"required"` // 訂單類型
|
||||||
|
OrderStatus int8 `json:"order_status" validate:"oneof=0 1 2 3 4 5 6 7 8 9 10 11"` // 訂單狀態
|
||||||
|
Brand string `json:"brand" validate:"required"` // 下單平台
|
||||||
|
OrderUID string `json:"order_uid" validate:"required"` // 下單用戶 UID
|
||||||
|
ReferenceID string `json:"reference_id" validate:"required"` // 訂單來源
|
||||||
|
Count decimal.Decimal `json:"count" validate:"required,decimalGt=0"` // 訂單數量
|
||||||
|
OrderFee decimal.Decimal `json:"order_fee" validate:"required,decimalGte=0"` // 訂單手續費
|
||||||
|
Amount decimal.Decimal `json:"amount" validate:"required,decimalGte=0"` // 單價
|
||||||
|
ReferenceBrand *string `json:"reference_brand,omitempty" validate:"omitempty"` // 訂單來源平台
|
||||||
|
ReferenceUID *string `json:"reference_uid,omitempty" validate:"omitempty"` // 訂單來源用戶 UID
|
||||||
|
WalletStatus *int64 `json:"wallet_status,omitempty" validate:"omitempty,oneof=1 2 3 4 5 6 7"` // 交易金額狀態
|
||||||
|
ThreePartyStatus *int64 `json:"three_party_status,omitempty" validate:"omitempty,oneof=1 2 3"` // 三方請求狀態
|
||||||
|
DirectionType *int64 `json:"direction_type,omitempty" validate:"omitempty,oneof=1 2"` // 交易方向
|
||||||
|
CryptoType *string `json:"crypto_type,omitempty" validate:"omitempty"` // 交易幣種
|
||||||
|
ThirdPartyFee *decimal.Decimal `json:"third_party_fee,omitempty" validate:"omitempty,decimalGte=0"` // 第三方手續費
|
||||||
|
CryptoToUSDTRate *decimal.Decimal `json:"crypto_to_usdt_rate,omitempty" validate:"omitempty,decimalGte=0"` // 交易幣種對 USDT 匯率
|
||||||
|
FiatToUSDRate *decimal.Decimal `json:"fiat_to_usd_rate,omitempty" validate:"omitempty,decimalGte=0"` // 法幣對 USD 匯率
|
||||||
|
FeeCryptoToUSDTRate *decimal.Decimal `json:"fee_crypto_to_usdt_rate,omitempty" validate:"omitempty,decimalGte=0"` // 手續費幣種對 USDT 匯率
|
||||||
|
USDTToCryptoTypeRate *decimal.Decimal `json:"usdt_to_crypto_type_rate,omitempty" validate:"omitempty,decimalGte=0"` // USDT 對交易幣種匯率
|
||||||
|
PaymentFiat *string `json:"payment_fiat,omitempty" validate:"omitempty"` // 支付法幣
|
||||||
|
PaymentUnitPrice *decimal.Decimal `json:"payment_unit_price,omitempty" validate:"omitempty,decimalGte=0"` // crypto 單價
|
||||||
|
PaymentTemplateID *string `json:"payment_template_id,omitempty" validate:"omitempty"` // 支付方式配置 ID
|
||||||
|
OrderArrivalTime *int64 `json:"order_arrival_time,omitempty" validate:"omitempty"` // 訂單到帳時間
|
||||||
|
OrderPaymentTime *int64 `json:"order_payment_time,omitempty" validate:"omitempty"` // 訂單付款時間
|
||||||
|
UnpaidTimeoutSecond *int64 `json:"unpaid_timeout_second,omitempty" validate:"omitempty,decimalGte=0"` // 支付期限秒數
|
||||||
|
ChainType *string `json:"chain_type,omitempty" validate:"omitempty"` // 主網類型
|
||||||
|
TxHash *string `json:"tx_hash,omitempty" validate:"omitempty"` // 交易哈希
|
||||||
|
FromAddress *string `json:"from_address,omitempty" validate:"omitempty"` // 來源地址
|
||||||
|
ToAddress *string `json:"to_address,omitempty" validate:"omitempty"` // 目標地址
|
||||||
|
ChainFee *decimal.Decimal `json:"chain_fee,omitempty" validate:"omitempty,decimalGte=0"` // 鏈上交易手續費
|
||||||
|
ChainFeeCrypto *string `json:"chain_fee_crypto,omitempty" validate:"omitempty"` // 鏈上手續費使用幣別
|
||||||
|
Memo *string `json:"memo,omitempty" validate:"omitempty"` // 鏈上備註
|
||||||
|
OrderNote *string `json:"order_note,omitempty" validate:"omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:gocyclo,gocognit
|
||||||
|
func buildCreateOrderReq(in *trade.CreateOrderReq) (*createOrderReq, error) {
|
||||||
|
createOrderReq := &createOrderReq{
|
||||||
|
BusinessID: in.BusinessId,
|
||||||
|
OrderType: int8(in.OrderType),
|
||||||
|
OrderStatus: int8(in.OrderStatus),
|
||||||
|
Brand: in.Brand,
|
||||||
|
OrderUID: in.OrderUid,
|
||||||
|
ReferenceID: in.ReferenceId,
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
// 只有當 Count, OrderFee, Amount 不為空時才進行轉換和設置
|
||||||
|
if in.Count != "" {
|
||||||
|
createOrderReq.Count, err = decimal.NewFromString(in.Count)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.OrderFee != "" {
|
||||||
|
createOrderReq.OrderFee, err = decimal.NewFromString(in.OrderFee)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.Amount != "" {
|
||||||
|
createOrderReq.Amount, err = decimal.NewFromString(in.Amount)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判斷可選字段,只有不為 nil 才設置
|
||||||
|
if in.ReferenceBrand != nil {
|
||||||
|
createOrderReq.ReferenceBrand = in.ReferenceBrand
|
||||||
|
}
|
||||||
|
if in.ReferenceUid != nil {
|
||||||
|
createOrderReq.ReferenceUID = in.ReferenceUid
|
||||||
|
}
|
||||||
|
if in.WalletStatus != nil {
|
||||||
|
createOrderReq.WalletStatus = in.WalletStatus
|
||||||
|
}
|
||||||
|
if in.ThreePartyStatus != nil {
|
||||||
|
createOrderReq.ThreePartyStatus = in.ThreePartyStatus
|
||||||
|
}
|
||||||
|
if in.DirectionType != nil {
|
||||||
|
createOrderReq.DirectionType = in.DirectionType
|
||||||
|
}
|
||||||
|
if in.CryptoType != nil {
|
||||||
|
createOrderReq.CryptoType = in.CryptoType
|
||||||
|
}
|
||||||
|
if in.ThirdPartyFee != nil && *in.ThirdPartyFee != "" {
|
||||||
|
createOrderReq.ThirdPartyFee = decimalPtrFromString(*in.ThirdPartyFee)
|
||||||
|
}
|
||||||
|
if in.CryptoToUsdtRate != nil && *in.CryptoToUsdtRate != "" {
|
||||||
|
createOrderReq.CryptoToUSDTRate = decimalPtrFromString(*in.CryptoToUsdtRate)
|
||||||
|
}
|
||||||
|
if in.FiatToUsdRate != nil && *in.FiatToUsdRate != "" {
|
||||||
|
createOrderReq.FiatToUSDRate = decimalPtrFromString(*in.FiatToUsdRate)
|
||||||
|
}
|
||||||
|
if in.FeeCryptoToUsdtRate != nil && *in.FeeCryptoToUsdtRate != "" {
|
||||||
|
createOrderReq.FeeCryptoToUSDTRate = decimalPtrFromString(*in.FeeCryptoToUsdtRate)
|
||||||
|
}
|
||||||
|
if in.UsdtToCryptoTypeRate != nil && *in.UsdtToCryptoTypeRate != "" {
|
||||||
|
createOrderReq.USDTToCryptoTypeRate = decimalPtrFromString(*in.UsdtToCryptoTypeRate)
|
||||||
|
}
|
||||||
|
if in.PaymentFiat != nil {
|
||||||
|
createOrderReq.PaymentFiat = in.PaymentFiat
|
||||||
|
}
|
||||||
|
if in.PaymentUnitPrice != nil && *in.PaymentUnitPrice != "" {
|
||||||
|
createOrderReq.PaymentUnitPrice = decimalPtrFromString(*in.PaymentUnitPrice)
|
||||||
|
}
|
||||||
|
if in.PaymentTemplateId != nil {
|
||||||
|
createOrderReq.PaymentTemplateID = in.PaymentTemplateId
|
||||||
|
}
|
||||||
|
if in.OrderArrivalTime != nil {
|
||||||
|
createOrderReq.OrderArrivalTime = in.OrderArrivalTime
|
||||||
|
}
|
||||||
|
if in.OrderPaymentTime != nil {
|
||||||
|
createOrderReq.OrderPaymentTime = in.OrderPaymentTime
|
||||||
|
}
|
||||||
|
if in.UnpaidTimeoutSecond != nil {
|
||||||
|
createOrderReq.UnpaidTimeoutSecond = in.UnpaidTimeoutSecond
|
||||||
|
}
|
||||||
|
if in.ChainType != nil {
|
||||||
|
createOrderReq.ChainType = in.ChainType
|
||||||
|
}
|
||||||
|
if in.TxHash != nil {
|
||||||
|
createOrderReq.TxHash = in.TxHash
|
||||||
|
}
|
||||||
|
if in.FromAddress != nil {
|
||||||
|
createOrderReq.FromAddress = in.FromAddress
|
||||||
|
}
|
||||||
|
if in.ToAddress != nil {
|
||||||
|
createOrderReq.ToAddress = in.ToAddress
|
||||||
|
}
|
||||||
|
if in.ChainFee != nil && *in.ChainFee != "" {
|
||||||
|
createOrderReq.ChainFee = decimalPtrFromString(*in.ChainFee)
|
||||||
|
}
|
||||||
|
if in.ChainFeeCrypto != nil {
|
||||||
|
createOrderReq.ChainFeeCrypto = in.ChainFeeCrypto
|
||||||
|
}
|
||||||
|
if in.Memo != nil {
|
||||||
|
createOrderReq.Memo = in.Memo
|
||||||
|
}
|
||||||
|
if in.OrderNote != nil {
|
||||||
|
createOrderReq.OrderNote = in.OrderNote
|
||||||
|
}
|
||||||
|
|
||||||
|
return createOrderReq, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// toCreateOrderReq 將 createOrderReq 轉換為 CreateOrderReq
|
||||||
|
func toCreateOrderUseCase(req *createOrderReq) usecase.CreateOrderReq {
|
||||||
|
return usecase.CreateOrderReq{
|
||||||
|
BusinessID: req.BusinessID,
|
||||||
|
OrderType: domain.OrderType(req.OrderType),
|
||||||
|
OrderStatus: domain.OrderStatus(req.OrderStatus),
|
||||||
|
Brand: req.Brand,
|
||||||
|
OrderUID: req.OrderUID,
|
||||||
|
ReferenceID: req.ReferenceID,
|
||||||
|
Count: req.Count,
|
||||||
|
OrderFee: req.OrderFee,
|
||||||
|
Amount: req.Amount,
|
||||||
|
WalletStatus: *req.WalletStatus,
|
||||||
|
DirectionType: *req.DirectionType,
|
||||||
|
ReferenceBrand: req.ReferenceBrand,
|
||||||
|
ReferenceUID: req.ReferenceUID,
|
||||||
|
ThreePartyStatus: req.ThreePartyStatus,
|
||||||
|
CryptoType: req.CryptoType,
|
||||||
|
ThirdPartyFee: req.ThirdPartyFee,
|
||||||
|
CryptoToUSDTRate: req.CryptoToUSDTRate,
|
||||||
|
FiatToUSDRate: req.FiatToUSDRate,
|
||||||
|
FeeCryptoToUSDTRate: req.FeeCryptoToUSDTRate,
|
||||||
|
USDTToCryptoTypeRate: req.USDTToCryptoTypeRate,
|
||||||
|
PaymentFiat: req.PaymentFiat,
|
||||||
|
PaymentUnitPrice: req.PaymentUnitPrice,
|
||||||
|
PaymentTemplateID: req.PaymentTemplateID,
|
||||||
|
OrderArrivalTime: req.OrderArrivalTime,
|
||||||
|
OrderPaymentTime: req.OrderPaymentTime,
|
||||||
|
UnpaidTimeoutSecond: req.UnpaidTimeoutSecond,
|
||||||
|
ChainType: req.ChainType,
|
||||||
|
TxHash: req.TxHash,
|
||||||
|
FromAddress: req.FromAddress,
|
||||||
|
ToAddress: req.ToAddress,
|
||||||
|
ChainFee: req.ChainFee,
|
||||||
|
ChainFeeCrypto: req.ChainFeeCrypto,
|
||||||
|
Memo: req.Memo,
|
||||||
|
OrderNote: req.OrderNote,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CreateOrder 建立訂單
|
// CreateOrder 建立訂單
|
||||||
func (l *CreateOrderLogic) CreateOrder(in *trade.CreateOrderReq) (*trade.OKResp, error) {
|
func (l *CreateOrderLogic) CreateOrder(in *trade.CreateOrderReq) (*trade.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
req, err := buildCreateOrderReq(in)
|
||||||
|
if err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(req); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = l.svcCtx.OrderUseCase.CreateOrder(l.ctx, toCreateOrderUseCase(req))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &trade.OKResp{}, nil
|
return &trade.OKResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-trade-service/internal/domain/usecase"
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||||
|
@ -23,9 +25,27 @@ func NewDeleteOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Delet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteOrderQuery 刪除訂單(軟刪除)
|
||||||
|
type DeleteOrderQuery struct {
|
||||||
|
BusinessID string `json:"business_id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteOrder 刪除訂單(軟刪除)
|
// DeleteOrder 刪除訂單(軟刪除)
|
||||||
func (l *DeleteOrderLogic) DeleteOrder(in *trade.DeleteOrderReq) (*trade.OKResp, error) {
|
func (l *DeleteOrderLogic) DeleteOrder(in *trade.DeleteOrderReq) (*trade.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&DeleteOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
}); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err := l.svcCtx.OrderUseCase.DeleteOrder(l.ctx, usecase.DeleteOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &trade.OKResp{}, nil
|
return &trade.OKResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-trade-service/internal/domain/usecase"
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||||
|
@ -23,9 +25,64 @@ func NewGetOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetOrder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetOrderQuery struct {
|
||||||
|
BusinessID string `json:"business_id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetOrder 取得訂單詳情
|
// GetOrder 取得訂單詳情
|
||||||
func (l *GetOrderLogic) GetOrder(in *trade.GetOrderReq) (*trade.GetOrderResp, error) {
|
func (l *GetOrderLogic) GetOrder(in *trade.GetOrderReq) (*trade.GetOrderResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&GetOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
}); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
return &trade.GetOrderResp{}, nil
|
o, err := l.svcCtx.OrderUseCase.GetOrder(l.ctx, usecase.GetOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &trade.GetOrderResp{
|
||||||
|
UpdateTime: o.UpdateTime,
|
||||||
|
CreateTime: o.CreateTime,
|
||||||
|
BusinessId: o.BusinessId,
|
||||||
|
OrderType: int32(o.OrderType),
|
||||||
|
OrderStatus: int32(o.OrderStatus),
|
||||||
|
Brand: o.Brand,
|
||||||
|
OrderUid: o.OrderUid,
|
||||||
|
ReferenceId: o.ReferenceId,
|
||||||
|
Count: o.Count,
|
||||||
|
OrderFee: o.OrderFee,
|
||||||
|
Amount: o.Amount,
|
||||||
|
// 下面的為未來擴充用的欄位
|
||||||
|
ReferenceBrand: o.ReferenceBrand,
|
||||||
|
ReferenceUid: o.ReferenceUid,
|
||||||
|
WalletStatus: o.WalletStatus,
|
||||||
|
ThreePartyStatus: o.ThreePartyStatus,
|
||||||
|
DirectionType: o.DirectionType,
|
||||||
|
CryptoType: o.CryptoType,
|
||||||
|
ThirdPartyFee: o.ThirdPartyFee,
|
||||||
|
CryptoToUsdtRate: o.CryptoToUsdtRate,
|
||||||
|
FiatToUsdRate: o.FiatToUsdRate,
|
||||||
|
FeeCryptoToUsdtRate: o.FeeCryptoToUsdtRate,
|
||||||
|
UsdtToCryptoTypeRate: o.UsdtToCryptoTypeRate,
|
||||||
|
PaymentFiat: o.PaymentFiat,
|
||||||
|
PaymentUnitPrice: o.PaymentUnitPrice,
|
||||||
|
PaymentTemplateId: o.PaymentTemplateId,
|
||||||
|
OrderArrivalTime: o.OrderArrivalTime,
|
||||||
|
OrderPaymentTime: o.OrderPaymentTime,
|
||||||
|
UnpaidTimeoutSecond: o.UnpaidTimeoutSecond,
|
||||||
|
ChainType: o.ChainType,
|
||||||
|
TxHash: o.TxHash,
|
||||||
|
FromAddress: o.FromAddress,
|
||||||
|
ToAddress: o.ToAddress,
|
||||||
|
ChainFee: o.ChainFee,
|
||||||
|
ChainFeeCrypto: o.ChainFeeCrypto,
|
||||||
|
Memo: o.Memo,
|
||||||
|
OrderNote: o.OrderNote,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-trade-service/internal/domain"
|
||||||
|
"app-cloudep-trade-service/internal/domain/usecase"
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||||
|
@ -23,9 +26,132 @@ func NewListOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListOrd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetOrderListReq struct {
|
||||||
|
PageIndex int64 `json:"page_index" validate:"required"`
|
||||||
|
PageSize int64 `json:"page_size" validate:"required"`
|
||||||
|
|
||||||
|
ReferenceID string `json:"reference_id"`
|
||||||
|
ReferenceUID string `json:"reference_uid"`
|
||||||
|
BusinessID string `json:"business_id"`
|
||||||
|
UID string `json:"uid"`
|
||||||
|
OrderType int `json:"order_type"`
|
||||||
|
DirectionType []int64 `json:"direction_type"`
|
||||||
|
OrderStatus []int64 `json:"order_status"`
|
||||||
|
|
||||||
|
StartCreateTime int64 `json:"start_create_time"`
|
||||||
|
EndCreateTime int64 `json:"end_create_time"`
|
||||||
|
StartUpdateTime int64 `json:"start_update_time"`
|
||||||
|
EndUpdateTime int64 `json:"end_update_time"`
|
||||||
|
StartOrderArrivalTime int64 `json:"start_order_arrival_time"`
|
||||||
|
EndOrderArrivalTime int64 `json:"end_order_arrival_time"`
|
||||||
|
StartOrderPaymentTime int64 `json:"start_order_payment_time"`
|
||||||
|
EndOrderPaymentTime int64 `json:"end_order_payment_time"`
|
||||||
|
|
||||||
|
CryptoType string `json:"crypto_type"`
|
||||||
|
TxHash string `json:"tx_hash"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// toGetOrderListReq 將 JSON 標籤結構轉換為無 JSON 標籤結構
|
||||||
|
func toGetOrderListReq(req *trade.ListOrderReq) usecase.GetOrderListReq {
|
||||||
|
return usecase.GetOrderListReq{
|
||||||
|
PageIndex: req.PageIndex,
|
||||||
|
PageSize: req.PageSize,
|
||||||
|
ReferenceID: req.ReferenceId,
|
||||||
|
ReferenceUID: req.ReferenceUid,
|
||||||
|
BusinessID: req.BusinessId,
|
||||||
|
UID: req.Uid,
|
||||||
|
OrderType: domain.OrderType(req.OrderType),
|
||||||
|
DirectionType: i32To64(req.DirectionType),
|
||||||
|
OrderStatus: i32To64(req.OrderStatus),
|
||||||
|
StartCreateTime: req.StartCreateTime,
|
||||||
|
EndCreateTime: req.EndCreateTime,
|
||||||
|
StartUpdateTime: req.StartUpdateTime,
|
||||||
|
EndUpdateTime: req.EndUpdateTime,
|
||||||
|
StartOrderArrivalTime: req.StartOrderArrivalTime,
|
||||||
|
EndOrderArrivalTime: req.EndOrderArrivalTime,
|
||||||
|
StartOrderPaymentTime: req.StartOrderPaymentTime,
|
||||||
|
EndOrderPaymentTime: req.EndOrderPaymentTime,
|
||||||
|
CryptoType: req.CryptoType,
|
||||||
|
TxHash: req.TxHash,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func i32To64(i []int32) []int64 {
|
||||||
|
if len(i) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
result := make([]int64, 0, len(i))
|
||||||
|
for item := range i {
|
||||||
|
result = append(result, int64(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// ListOrder 取得訂單列表
|
// ListOrder 取得訂單列表
|
||||||
func (l *ListOrderLogic) ListOrder(in *trade.ListOrderReq) (*trade.ListOrderResp, error) {
|
func (l *ListOrderLogic) ListOrder(in *trade.ListOrderReq) (*trade.ListOrderResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&GetOrderListReq{
|
||||||
|
PageIndex: in.GetPageIndex(),
|
||||||
|
PageSize: in.GetPageSize(),
|
||||||
|
}); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
return &trade.ListOrderResp{}, nil
|
order, err := l.svcCtx.OrderUseCase.ListOrder(l.ctx, toGetOrderListReq(in))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data := make([]*trade.GetOrderResp, 0, len(order.Data))
|
||||||
|
for _, item := range order.Data {
|
||||||
|
data = append(data, &trade.GetOrderResp{
|
||||||
|
BusinessId: item.BusinessId,
|
||||||
|
OrderType: int32(item.OrderType),
|
||||||
|
OrderStatus: int32(item.OrderStatus),
|
||||||
|
Brand: item.Brand,
|
||||||
|
OrderUid: item.OrderUid,
|
||||||
|
ReferenceId: item.ReferenceId,
|
||||||
|
Count: item.Count,
|
||||||
|
OrderFee: item.OrderFee,
|
||||||
|
Amount: item.Amount,
|
||||||
|
ReferenceBrand: item.ReferenceBrand,
|
||||||
|
ReferenceUid: item.ReferenceUid,
|
||||||
|
WalletStatus: item.WalletStatus,
|
||||||
|
ThreePartyStatus: item.ThreePartyStatus,
|
||||||
|
DirectionType: item.DirectionType,
|
||||||
|
CryptoType: item.CryptoType,
|
||||||
|
ThirdPartyFee: item.ThirdPartyFee,
|
||||||
|
CryptoToUsdtRate: item.CryptoToUsdtRate,
|
||||||
|
FiatToUsdRate: item.FiatToUsdRate,
|
||||||
|
FeeCryptoToUsdtRate: item.FeeCryptoToUsdtRate,
|
||||||
|
UsdtToCryptoTypeRate: item.UsdtToCryptoTypeRate,
|
||||||
|
PaymentFiat: item.PaymentFiat,
|
||||||
|
PaymentUnitPrice: item.PaymentUnitPrice,
|
||||||
|
PaymentTemplateId: item.PaymentTemplateId,
|
||||||
|
OrderArrivalTime: item.OrderArrivalTime,
|
||||||
|
OrderPaymentTime: item.OrderPaymentTime,
|
||||||
|
UnpaidTimeoutSecond: item.UnpaidTimeoutSecond,
|
||||||
|
ChainType: item.ChainType,
|
||||||
|
TxHash: item.TxHash,
|
||||||
|
FromAddress: item.FromAddress,
|
||||||
|
ToAddress: item.ToAddress,
|
||||||
|
ChainFee: item.ChainFee,
|
||||||
|
ChainFeeCrypto: item.ChainFeeCrypto,
|
||||||
|
Memo: item.Memo,
|
||||||
|
OrderNote: item.OrderNote,
|
||||||
|
CreateTime: item.CreateTime,
|
||||||
|
UpdateTime: item.UpdateTime,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return &trade.ListOrderResp{
|
||||||
|
Data: data,
|
||||||
|
Page: &trade.Pager{
|
||||||
|
Index: order.Page.Index,
|
||||||
|
Size: order.Page.Size,
|
||||||
|
Total: order.Page.Total,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-trade-service/internal/domain/usecase"
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||||
|
@ -23,9 +25,34 @@ func NewModifyOrderStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ModifyOrderQuery
|
||||||
|
// 0.建立訂單 1.建單失敗 2.審核中 3.付款中 4.已付款
|
||||||
|
// 5.已付款待轉帳 6.申訴中 7.交易完成
|
||||||
|
// 8.交易失敗 9.交易取消 10.交易異常 11.交易超時
|
||||||
|
|
||||||
|
type ModifyOrderQuery struct {
|
||||||
|
BusinessID string `json:"business_id" validate:"required"`
|
||||||
|
Status int64 `json:"status" validate:"required,oneof=2 3 4 5 6 7 8 11"`
|
||||||
|
}
|
||||||
|
|
||||||
// ModifyOrderStatus 修改訂單狀態
|
// ModifyOrderStatus 修改訂單狀態
|
||||||
func (l *ModifyOrderStatusLogic) ModifyOrderStatus(in *trade.ModifyOrderStatusReq) (*trade.OKResp, error) {
|
func (l *ModifyOrderStatusLogic) ModifyOrderStatus(in *trade.ModifyOrderStatusReq) (*trade.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&ModifyOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
Status: in.GetStatus(),
|
||||||
|
}); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err := l.svcCtx.OrderUseCase.ModifyOrderStatus(l.ctx, &usecase.ModifyOrderQuery{
|
||||||
|
Status: in.GetStatus(),
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &trade.OKResp{}, nil
|
return &trade.OKResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,10 @@ func NewOrderStatusTimeoutLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||||
|
|
||||||
// OrderStatusTimeout 訂單超時任務/cron/order-status/timeout
|
// OrderStatusTimeout 訂單超時任務/cron/order-status/timeout
|
||||||
func (l *OrderStatusTimeoutLogic) OrderStatusTimeout(in *trade.OrderStatusTimeoutReq) (*trade.OKResp, error) {
|
func (l *OrderStatusTimeoutLogic) OrderStatusTimeout(in *trade.OrderStatusTimeoutReq) (*trade.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
err := l.svcCtx.OrderUseCase.OrderStatusTimeout(l.ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &trade.OKResp{}, nil
|
return &trade.OKResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package orderservicelogic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
|
// Source: ./validate.go
|
||||||
|
//
|
||||||
|
// Generated by this command:
|
||||||
|
//
|
||||||
|
// mockgen -source=./validate.go -destination=../../mock/lib/validate.go -package=lib
|
||||||
|
//
|
||||||
|
|
||||||
|
// Package lib is a generated GoMock package.
|
||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
reflect "reflect"
|
||||||
|
|
||||||
|
required "code.30cm.net/digimon/library-go/validator"
|
||||||
|
|
||||||
|
gomock "go.uber.org/mock/gomock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockValidate is a mock of Validate interface.
|
||||||
|
type MockValidate struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockValidateMockRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockValidateMockRecorder is the mock recorder for MockValidate.
|
||||||
|
type MockValidateMockRecorder struct {
|
||||||
|
mock *MockValidate
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockValidate creates a new mock instance.
|
||||||
|
func NewMockValidate(ctrl *gomock.Controller) *MockValidate {
|
||||||
|
mock := &MockValidate{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockValidateMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockValidate) EXPECT() *MockValidateMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindToValidator mocks base method.
|
||||||
|
func (m *MockValidate) BindToValidator(opts ...required.Option) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
varargs := []any{}
|
||||||
|
for _, a := range opts {
|
||||||
|
varargs = append(varargs, a)
|
||||||
|
}
|
||||||
|
ret := m.ctrl.Call(m, "BindToValidator", varargs...)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindToValidator indicates an expected call of BindToValidator.
|
||||||
|
func (mr *MockValidateMockRecorder) BindToValidator(opts ...any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BindToValidator", reflect.TypeOf((*MockValidate)(nil).BindToValidator), opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateAll mocks base method.
|
||||||
|
func (m *MockValidate) ValidateAll(obj any) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "ValidateAll", obj)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateAll indicates an expected call of ValidateAll.
|
||||||
|
func (mr *MockValidateMockRecorder) ValidateAll(obj any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateAll", reflect.TypeOf((*MockValidate)(nil).ValidateAll), obj)
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
|
// Source: ./internal/model/mongo/order_model.go
|
||||||
|
//
|
||||||
|
// Generated by this command:
|
||||||
|
//
|
||||||
|
// mockgen -source=./internal/model/mongo/order_model.go -destination=./internal/mock/model/order_model.go -package=mock
|
||||||
|
//
|
||||||
|
|
||||||
|
// Package mock is a generated GoMock package.
|
||||||
|
package mock
|
||||||
|
|
||||||
|
import (
|
||||||
|
mongo "app-cloudep-trade-service/internal/model/mongo"
|
||||||
|
context "context"
|
||||||
|
reflect "reflect"
|
||||||
|
|
||||||
|
mongo0 "go.mongodb.org/mongo-driver/mongo"
|
||||||
|
gomock "go.uber.org/mock/gomock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockOrderModel is a mock of OrderModel interface.
|
||||||
|
type MockOrderModel struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockOrderModelMockRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockOrderModelMockRecorder is the mock recorder for MockOrderModel.
|
||||||
|
type MockOrderModelMockRecorder struct {
|
||||||
|
mock *MockOrderModel
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockOrderModel creates a new mock instance.
|
||||||
|
func NewMockOrderModel(ctrl *gomock.Controller) *MockOrderModel {
|
||||||
|
mock := &MockOrderModel{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockOrderModelMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockOrderModel) EXPECT() *MockOrderModelMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete mocks base method.
|
||||||
|
func (m *MockOrderModel) Delete(ctx context.Context, id string) (int64, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Delete", ctx, id)
|
||||||
|
ret0, _ := ret[0].(int64)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete indicates an expected call of Delete.
|
||||||
|
func (mr *MockOrderModelMockRecorder) Delete(ctx, id any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockOrderModel)(nil).Delete), ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteByBusinessID mocks base method.
|
||||||
|
func (m *MockOrderModel) DeleteByBusinessID(ctx context.Context, id string) (*mongo0.UpdateResult, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "DeleteByBusinessID", ctx, id)
|
||||||
|
ret0, _ := ret[0].(*mongo0.UpdateResult)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteByBusinessID indicates an expected call of DeleteByBusinessID.
|
||||||
|
func (mr *MockOrderModelMockRecorder) DeleteByBusinessID(ctx, id any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByBusinessID", reflect.TypeOf((*MockOrderModel)(nil).DeleteByBusinessID), ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindOne mocks base method.
|
||||||
|
func (m *MockOrderModel) FindOne(ctx context.Context, id string) (*mongo.Order, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "FindOne", ctx, id)
|
||||||
|
ret0, _ := ret[0].(*mongo.Order)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindOne indicates an expected call of FindOne.
|
||||||
|
func (mr *MockOrderModelMockRecorder) FindOne(ctx, id any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockOrderModel)(nil).FindOne), ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindOneBusinessID mocks base method.
|
||||||
|
func (m *MockOrderModel) FindOneBusinessID(ctx context.Context, id string) (*mongo.Order, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "FindOneBusinessID", ctx, id)
|
||||||
|
ret0, _ := ret[0].(*mongo.Order)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindOneBusinessID indicates an expected call of FindOneBusinessID.
|
||||||
|
func (mr *MockOrderModelMockRecorder) FindOneBusinessID(ctx, id any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneBusinessID", reflect.TypeOf((*MockOrderModel)(nil).FindOneBusinessID), ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert mocks base method.
|
||||||
|
func (m *MockOrderModel) Insert(ctx context.Context, data *mongo.Order) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Insert", ctx, data)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert indicates an expected call of Insert.
|
||||||
|
func (mr *MockOrderModelMockRecorder) Insert(ctx, data any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Insert", reflect.TypeOf((*MockOrderModel)(nil).Insert), ctx, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOrder mocks base method.
|
||||||
|
func (m *MockOrderModel) ListOrder(ctx context.Context, req mongo.GetOrderListReq) ([]mongo.Order, int64, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "ListOrder", ctx, req)
|
||||||
|
ret0, _ := ret[0].([]mongo.Order)
|
||||||
|
ret1, _ := ret[1].(int64)
|
||||||
|
ret2, _ := ret[2].(error)
|
||||||
|
return ret0, ret1, ret2
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOrder indicates an expected call of ListOrder.
|
||||||
|
func (mr *MockOrderModelMockRecorder) ListOrder(ctx, req any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListOrder", reflect.TypeOf((*MockOrderModel)(nil).ListOrder), ctx, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update mocks base method.
|
||||||
|
func (m *MockOrderModel) Update(ctx context.Context, data *mongo.Order) (*mongo0.UpdateResult, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Update", ctx, data)
|
||||||
|
ret0, _ := ret[0].(*mongo0.UpdateResult)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update indicates an expected call of Update.
|
||||||
|
func (mr *MockOrderModelMockRecorder) Update(ctx, data any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockOrderModel)(nil).Update), ctx, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateStatus mocks base method.
|
||||||
|
func (m *MockOrderModel) UpdateStatus(ctx context.Context, data mongo.UpdateStatusReq) (*mongo0.UpdateResult, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "UpdateStatus", ctx, data)
|
||||||
|
ret0, _ := ret[0].(*mongo0.UpdateResult)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateStatus indicates an expected call of UpdateStatus.
|
||||||
|
func (mr *MockOrderModelMockRecorder) UpdateStatus(ctx, data any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStatus", reflect.TypeOf((*MockOrderModel)(nil).UpdateStatus), ctx, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTimeoutOrder mocks base method.
|
||||||
|
func (m *MockOrderModel) UpdateTimeoutOrder(ctx context.Context, req mongo.UpdateTimeoutReq) (*mongo0.UpdateResult, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "UpdateTimeoutOrder", ctx, req)
|
||||||
|
ret0, _ := ret[0].(*mongo0.UpdateResult)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTimeoutOrder indicates an expected call of UpdateTimeoutOrder.
|
||||||
|
func (mr *MockOrderModelMockRecorder) UpdateTimeoutOrder(ctx, req any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTimeoutOrder", reflect.TypeOf((*MockOrderModel)(nil).UpdateTimeoutOrder), ctx, req)
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
|
// Source: ./internal/model/mongo/order_model_gen.go
|
||||||
|
//
|
||||||
|
// Generated by this command:
|
||||||
|
//
|
||||||
|
// mockgen -source=./internal/model/mongo/order_model_gen.go -destination=./internal/mock/model/order_model_gen.go -package=mock
|
||||||
|
//
|
||||||
|
|
||||||
|
// Package mock is a generated GoMock package.
|
||||||
|
package mock
|
||||||
|
|
||||||
|
import (
|
||||||
|
mongo "app-cloudep-trade-service/internal/model/mongo"
|
||||||
|
context "context"
|
||||||
|
reflect "reflect"
|
||||||
|
|
||||||
|
mongo0 "go.mongodb.org/mongo-driver/mongo"
|
||||||
|
gomock "go.uber.org/mock/gomock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockorderModel is a mock of orderModel interface.
|
||||||
|
type MockorderModel struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockorderModelMockRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockorderModelMockRecorder is the mock recorder for MockorderModel.
|
||||||
|
type MockorderModelMockRecorder struct {
|
||||||
|
mock *MockorderModel
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockorderModel creates a new mock instance.
|
||||||
|
func NewMockorderModel(ctrl *gomock.Controller) *MockorderModel {
|
||||||
|
mock := &MockorderModel{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockorderModelMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockorderModel) EXPECT() *MockorderModelMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete mocks base method.
|
||||||
|
func (m *MockorderModel) Delete(ctx context.Context, id string) (int64, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Delete", ctx, id)
|
||||||
|
ret0, _ := ret[0].(int64)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete indicates an expected call of Delete.
|
||||||
|
func (mr *MockorderModelMockRecorder) Delete(ctx, id any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockorderModel)(nil).Delete), ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindOne mocks base method.
|
||||||
|
func (m *MockorderModel) FindOne(ctx context.Context, id string) (*mongo.Order, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "FindOne", ctx, id)
|
||||||
|
ret0, _ := ret[0].(*mongo.Order)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindOne indicates an expected call of FindOne.
|
||||||
|
func (mr *MockorderModelMockRecorder) FindOne(ctx, id any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockorderModel)(nil).FindOne), ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert mocks base method.
|
||||||
|
func (m *MockorderModel) Insert(ctx context.Context, data *mongo.Order) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Insert", ctx, data)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert indicates an expected call of Insert.
|
||||||
|
func (mr *MockorderModelMockRecorder) Insert(ctx, data any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Insert", reflect.TypeOf((*MockorderModel)(nil).Insert), ctx, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update mocks base method.
|
||||||
|
func (m *MockorderModel) Update(ctx context.Context, data *mongo.Order) (*mongo0.UpdateResult, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Update", ctx, data)
|
||||||
|
ret0, _ := ret[0].(*mongo0.UpdateResult)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update indicates an expected call of Update.
|
||||||
|
func (mr *MockorderModelMockRecorder) Update(ctx, data any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockorderModel)(nil).Update), ctx, data)
|
||||||
|
}
|
|
@ -2,7 +2,8 @@ package svc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"app-cloudep-trade-service/internal/config"
|
"app-cloudep-trade-service/internal/config"
|
||||||
model "app-cloudep-trade-service/internal/model/mongo"
|
duc "app-cloudep-trade-service/internal/domain/usecase"
|
||||||
|
"app-cloudep-trade-service/internal/usecase"
|
||||||
|
|
||||||
ers "code.30cm.net/digimon/library-go/errs"
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
"code.30cm.net/digimon/library-go/errs/code"
|
"code.30cm.net/digimon/library-go/errs/code"
|
||||||
|
@ -10,21 +11,28 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
Validate vi.Validate
|
Validate vi.Validate
|
||||||
OrderModel model.OrderModel
|
|
||||||
|
OrderUseCase duc.OrderUseCase
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
// TODO 改成 Trade
|
// TODO 改成 Trade
|
||||||
ers.Scope = code.CloudEPOrder
|
ers.Scope = code.CloudEPOrder
|
||||||
|
|
||||||
|
om := MustOrderModel(c)
|
||||||
|
orderUseCase := usecase.NewOrderUseCase(usecase.OrderUseCaseParam{
|
||||||
|
OrderModel: om,
|
||||||
|
})
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
Validate: vi.MustValidator(
|
Validate: vi.MustValidator(
|
||||||
WithDecimalGt(),
|
WithDecimalGt(),
|
||||||
WithDecimalGte(),
|
WithDecimalGte(),
|
||||||
),
|
),
|
||||||
OrderModel: MustOrderModel(c),
|
|
||||||
|
OrderUseCase: orderUseCase,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +1,73 @@
|
||||||
package usecase
|
package usecase
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-trade-service/internal/domain"
|
||||||
"app-cloudep-trade-service/internal/domain/usecase"
|
"app-cloudep-trade-service/internal/domain/usecase"
|
||||||
|
mockmodel "app-cloudep-trade-service/internal/mock/model"
|
||||||
model "app-cloudep-trade-service/internal/model/mongo"
|
model "app-cloudep-trade-service/internal/model/mongo"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
"github.com/go-playground/assert/v2"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||||
|
"go.uber.org/mock/gomock"
|
||||||
|
"time"
|
||||||
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewOrderUseCase(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
param OrderUseCaseParam
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
want usecase.OrderUseCase
|
|
||||||
}{
|
|
||||||
// TODO: Add test cases.
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if got := NewOrderUseCase(tt.args.param); !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("NewOrderUseCase() = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrderUseCase_CancelOrder(t *testing.T) {
|
func TestOrderUseCase_CancelOrder(t *testing.T) {
|
||||||
type fields struct {
|
ctrl := gomock.NewController(t)
|
||||||
OrderModel model.OrderModel
|
defer ctrl.Finish()
|
||||||
|
|
||||||
|
// 初始化 mock 依賴
|
||||||
|
mockOrderModel := mockmodel.NewMockOrderModel(ctrl)
|
||||||
|
|
||||||
|
orderUseCase := &OrderUseCase{
|
||||||
|
OrderModel: mockOrderModel,
|
||||||
}
|
}
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
cancelOrderQuery := usecase.CancelOrderQuery{
|
||||||
param usecase.CancelOrderQuery
|
BusinessID: "business_123",
|
||||||
|
Status: domain.OrderStatusCancelled, // 使用模擬的狀態
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fields fields
|
mockSetup func()
|
||||||
args args
|
param usecase.CancelOrderQuery
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
// TODO: Add test cases.
|
{
|
||||||
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
o := &OrderUseCase{
|
tt.mockSetup() // 設置每個測試用例的 mock 行為
|
||||||
OrderModel: tt.fields.OrderModel,
|
err := orderUseCase.CancelOrder(context.Background(), tt.param)
|
||||||
}
|
if (err != nil) != tt.wantErr {
|
||||||
if err := o.CancelOrder(tt.args.ctx, tt.args.param); (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("CancelOrder() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("CancelOrder() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -57,27 +75,77 @@ func TestOrderUseCase_CancelOrder(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrderUseCase_CreateOrder(t *testing.T) {
|
func TestOrderUseCase_CreateOrder(t *testing.T) {
|
||||||
type fields struct {
|
mockCtrl := gomock.NewController(t)
|
||||||
OrderModel model.OrderModel
|
defer mockCtrl.Finish()
|
||||||
|
|
||||||
|
// 初始化 mock 依賴
|
||||||
|
mockOrderModel := mockmodel.NewMockOrderModel(mockCtrl)
|
||||||
|
orderUseCase := &OrderUseCase{
|
||||||
|
OrderModel: mockOrderModel,
|
||||||
}
|
}
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
now := time.Now().UTC().UnixNano()
|
||||||
param usecase.CreateOrderReq
|
|
||||||
|
// 構建測試參數
|
||||||
|
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 {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fields fields
|
mockSetup func()
|
||||||
args args
|
param usecase.CreateOrderReq
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
// TODO: Add test cases.
|
{
|
||||||
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
o := &OrderUseCase{
|
tt.mockSetup() // 設置每個測試用例的 mock 行為
|
||||||
OrderModel: tt.fields.OrderModel,
|
err := orderUseCase.CreateOrder(context.Background(), tt.param)
|
||||||
}
|
if (err != nil) != tt.wantErr {
|
||||||
if err := o.CreateOrder(tt.args.ctx, tt.args.param); (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("CreateOrder() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("CreateOrder() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -85,27 +153,50 @@ func TestOrderUseCase_CreateOrder(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrderUseCase_DeleteOrder(t *testing.T) {
|
func TestOrderUseCase_DeleteOrder(t *testing.T) {
|
||||||
type fields struct {
|
ctrl := gomock.NewController(t)
|
||||||
OrderModel model.OrderModel
|
defer ctrl.Finish()
|
||||||
|
|
||||||
|
// 初始化 mock 依賴
|
||||||
|
mockOrderModel := mockmodel.NewMockOrderModel(ctrl)
|
||||||
|
|
||||||
|
orderUseCase := &OrderUseCase{
|
||||||
|
OrderModel: mockOrderModel,
|
||||||
}
|
}
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
// 構建測試參數
|
||||||
param usecase.DeleteOrderQuery
|
deleteOrderQuery := usecase.DeleteOrderQuery{
|
||||||
|
BusinessID: "business_123",
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fields fields
|
mockSetup func()
|
||||||
args args
|
param usecase.DeleteOrderQuery
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
// TODO: Add test cases.
|
{
|
||||||
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
o := &OrderUseCase{
|
tt.mockSetup() // 設置每個測試用例的 mock 行為
|
||||||
OrderModel: tt.fields.OrderModel,
|
err := orderUseCase.DeleteOrder(context.Background(), tt.param)
|
||||||
}
|
if (err != nil) != tt.wantErr {
|
||||||
if err := o.DeleteOrder(tt.args.ctx, tt.args.param); (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("DeleteOrder() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("DeleteOrder() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -113,95 +204,254 @@ func TestOrderUseCase_DeleteOrder(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrderUseCase_GetOrder(t *testing.T) {
|
func TestOrderUseCase_GetOrder(t *testing.T) {
|
||||||
type fields struct {
|
mockCtrl := gomock.NewController(t)
|
||||||
OrderModel model.OrderModel
|
defer mockCtrl.Finish()
|
||||||
|
|
||||||
|
// 初始化 mock 依賴
|
||||||
|
mockOrderModel := mockmodel.NewMockOrderModel(mockCtrl)
|
||||||
|
orderUseCase := &OrderUseCase{
|
||||||
|
OrderModel: mockOrderModel,
|
||||||
}
|
}
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
getOrderQuery := usecase.GetOrderQuery{
|
||||||
param 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 {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fields fields
|
mockSetup func()
|
||||||
args args
|
param usecase.GetOrderQuery
|
||||||
want *usecase.GetOrderResp
|
wantResp *usecase.GetOrderResp
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
// TODO: Add test cases.
|
{
|
||||||
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
o := &OrderUseCase{
|
tt.mockSetup() // 設置每個測試用例的 mock 行為
|
||||||
OrderModel: tt.fields.OrderModel,
|
resp, err := orderUseCase.GetOrder(context.Background(), tt.param)
|
||||||
}
|
|
||||||
got, err := o.GetOrder(tt.args.ctx, tt.args.param)
|
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("GetOrder() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("GetOrder() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(got, tt.want) {
|
assert.Equal(t, tt.wantResp, resp)
|
||||||
t.Errorf("GetOrder() got = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrderUseCase_ListOrder(t *testing.T) {
|
func TestOrderUseCase_ListOrder(t *testing.T) {
|
||||||
type fields struct {
|
mockCtrl := gomock.NewController(t)
|
||||||
OrderModel model.OrderModel
|
defer mockCtrl.Finish()
|
||||||
|
|
||||||
|
mockOrderModel := mockmodel.NewMockOrderModel(mockCtrl)
|
||||||
|
orderUseCase := &OrderUseCase{
|
||||||
|
OrderModel: mockOrderModel,
|
||||||
}
|
}
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
listOrderQuery := usecase.GetOrderListReq{
|
||||||
param 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 {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fields fields
|
mockSetup func()
|
||||||
args args
|
param usecase.GetOrderListReq
|
||||||
want *usecase.ListOrderResp
|
wantResp *usecase.ListOrderResp
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
// TODO: Add test cases.
|
{
|
||||||
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
o := &OrderUseCase{
|
tt.mockSetup()
|
||||||
OrderModel: tt.fields.OrderModel,
|
resp, err := orderUseCase.ListOrder(context.Background(), tt.param)
|
||||||
}
|
|
||||||
got, err := o.ListOrder(tt.args.ctx, tt.args.param)
|
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("ListOrder() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("ListOrder() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(got, tt.want) {
|
assert.Equal(t, tt.wantResp, resp)
|
||||||
t.Errorf("ListOrder() got = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrderUseCase_ModifyOrderStatus(t *testing.T) {
|
func TestOrderUseCase_ModifyOrderStatus(t *testing.T) {
|
||||||
type fields struct {
|
mockCtrl := gomock.NewController(t)
|
||||||
OrderModel model.OrderModel
|
defer mockCtrl.Finish()
|
||||||
|
|
||||||
|
mockOrderModel := mockmodel.NewMockOrderModel(mockCtrl)
|
||||||
|
orderUseCase := &OrderUseCase{
|
||||||
|
OrderModel: mockOrderModel,
|
||||||
}
|
}
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
modifyOrderQuery := &usecase.ModifyOrderQuery{
|
||||||
param *usecase.ModifyOrderQuery
|
BusinessID: "business_123",
|
||||||
|
Status: int64(domain.OrderStatusCancelled),
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fields fields
|
mockSetup func()
|
||||||
args args
|
param *usecase.ModifyOrderQuery
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
// TODO: Add test cases.
|
{
|
||||||
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
o := &OrderUseCase{
|
tt.mockSetup()
|
||||||
OrderModel: tt.fields.OrderModel,
|
err := orderUseCase.ModifyOrderStatus(context.Background(), tt.param)
|
||||||
}
|
if (err != nil) != tt.wantErr {
|
||||||
if err := o.ModifyOrderStatus(tt.args.ctx, tt.args.param); (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("ModifyOrderStatus() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("ModifyOrderStatus() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -209,26 +459,40 @@ func TestOrderUseCase_ModifyOrderStatus(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrderUseCase_OrderStatusTimeout(t *testing.T) {
|
func TestOrderUseCase_OrderStatusTimeout(t *testing.T) {
|
||||||
type fields struct {
|
mockCtrl := gomock.NewController(t)
|
||||||
OrderModel model.OrderModel
|
defer mockCtrl.Finish()
|
||||||
}
|
|
||||||
type args struct {
|
mockOrderModel := mockmodel.NewMockOrderModel(mockCtrl)
|
||||||
ctx context.Context
|
orderUseCase := &OrderUseCase{
|
||||||
|
OrderModel: mockOrderModel,
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fields fields
|
mockSetup func()
|
||||||
args args
|
wantErr bool
|
||||||
wantErr bool
|
|
||||||
}{
|
}{
|
||||||
// TODO: Add test cases.
|
{
|
||||||
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
o := &OrderUseCase{
|
tt.mockSetup()
|
||||||
OrderModel: tt.fields.OrderModel,
|
err := orderUseCase.OrderStatusTimeout(context.Background())
|
||||||
}
|
if (err != nil) != tt.wantErr {
|
||||||
if err := o.OrderStatusTimeout(tt.args.ctx); (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("OrderStatusTimeout() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("OrderStatusTimeout() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package usecase
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-playground/assert/v2"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 測試 Int64Ptr 函數
|
||||||
|
func TestInt64Ptr(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
val int64
|
||||||
|
want *int64
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "non-zero value",
|
||||||
|
val: 123,
|
||||||
|
want: func() *int64 { v := int64(123); return &v }(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "zero value",
|
||||||
|
val: 0,
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := Int64Ptr(tt.val)
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 測試 DecimalToStringPtr 函數
|
||||||
|
func TestDecimalToStringPtr(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
val *decimal.Decimal
|
||||||
|
want *string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "non-nil decimal",
|
||||||
|
val: func() *decimal.Decimal { d := decimal.NewFromFloat(123.45); return &d }(),
|
||||||
|
want: func() *string { s := "123.45"; return &s }(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nil decimal",
|
||||||
|
val: nil,
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := DecimalToStringPtr(tt.val)
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 測試 StringPtr 函數
|
||||||
|
func TestStringPtr(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
val string
|
||||||
|
want *string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "non-empty string",
|
||||||
|
val: "test",
|
||||||
|
want: func() *string { s := "test"; return &s }(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty string",
|
||||||
|
val: "",
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := StringPtr(tt.val)
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue