diff --git a/broadcast/broadcast-client/client_builder_mocks.go b/broadcast/broadcast-client/client_builder_mocks.go index 97736ea..0973078 100644 --- a/broadcast/broadcast-client/client_builder_mocks.go +++ b/broadcast/broadcast-client/client_builder_mocks.go @@ -5,16 +5,19 @@ import ( "github.com/bitcoin-sv/go-broadcast-client/broadcast/internal/arc/mocks" ) +// MockType is an enum that is used as parameter to WithMockArc +// client builder in order to create different types of mock. type MockType int const ( - MockSuccess MockType = iota + 1 + MockSuccess MockType = iota MockFailure MockTimeout - MockAlreadyOnChain - MockInMempool ) +// WithMockArc creates a mock client for testing purposes. It takes mock type as argument +// and creates a mock client that satisfies the client interface with methods that return +// success or specific error based on this mock type argument. func (cb *builder) WithMockArc(config ArcClientConfig, mockType MockType) *builder { var clientToReturn broadcast_api.Client @@ -25,8 +28,8 @@ func (cb *builder) WithMockArc(config ArcClientConfig, mockType MockType) *build case MockFailure: clientToReturn = mocks.NewArcClientMockFailure() break - case MockAlreadyOnChain: - clientToReturn = mocks.NewArcClientMockOnChain() + case MockTimeout: + clientToReturn = mocks.NewArcClientMockTimeout() break default: clientToReturn = mocks.NewArcClientMock() diff --git a/broadcast/errors.go b/broadcast/errors.go index 0938b76..0bde65f 100644 --- a/broadcast/errors.go +++ b/broadcast/errors.go @@ -18,7 +18,7 @@ import ( // It should be returned for all defined clients in the future. var ErrClientUndefined = errors.New("client is undefined") -// ErrAllBroadcastersFailed is returned when all configured broadcasters failed to broadcast the transaction. +// ErrAllBroadcastersFailed is returned when all configured broadcasters failed to query or broadcast the transaction. var ErrAllBroadcastersFailed = errors.New("all broadcasters failed") // ErrURLEmpty is returned when the API URL is empty. diff --git a/broadcast/internal/arc/mocks/arc_client_mock_no_response.go b/broadcast/internal/arc/mocks/arc_client_mock_no_response.go index 19cb3c0..c9ea8b8 100644 --- a/broadcast/internal/arc/mocks/arc_client_mock_no_response.go +++ b/broadcast/internal/arc/mocks/arc_client_mock_no_response.go @@ -9,31 +9,32 @@ import ( type ArcClientMockFailure struct{} -// GetFeeQuote implements broadcast.Client. +// GetFeeQuote returns an error. func (*ArcClientMockFailure) GetFeeQuote(ctx context.Context) ([]*broadcast_api.FeeQuote, error) { return nil, broadcast.ErrNoMinerResponse } -// GetPolicyQuote implements broadcast.Client. +// GetPolicyQuote returns an error. func (*ArcClientMockFailure) GetPolicyQuote(ctx context.Context) ([]*broadcast_api.PolicyQuoteResponse, error) { return nil, broadcast.ErrNoMinerResponse } -// QueryTransaction implements broadcast.Client. +// QueryTransaction returns an error. func (*ArcClientMockFailure) QueryTransaction(ctx context.Context, txID string) (*broadcast_api.QueryTxResponse, error) { return nil, broadcast.ErrAllBroadcastersFailed } -// SubmitBatchTransactions implements broadcast.Client. +// SubmitBatchTransactions returns an error. func (*ArcClientMockFailure) SubmitBatchTransactions(ctx context.Context, tx []*broadcast_api.Transaction, opts ...broadcast_api.TransactionOptFunc) (*broadcast_api.SubmitBatchTxResponse, error) { return nil, broadcast.ErrAllBroadcastersFailed } -// SubmitTransaction implements broadcast.Client. +// SubmitTransaction returns an error. func (*ArcClientMockFailure) SubmitTransaction(ctx context.Context, tx *broadcast_api.Transaction, opts ...broadcast_api.TransactionOptFunc) (*broadcast_api.SubmitTxResponse, error) { return nil, broadcast.ErrAllBroadcastersFailed } +// NewArcClientMockFailure creates a new mock arc client that returns an error from all its methods. func NewArcClientMockFailure() broadcast_api.Client { return &ArcClientMockFailure{} } diff --git a/broadcast/internal/arc/mocks/arc_client_mock_on_chain.go b/broadcast/internal/arc/mocks/arc_client_mock_on_chain.go deleted file mode 100644 index 04edc7d..0000000 --- a/broadcast/internal/arc/mocks/arc_client_mock_on_chain.go +++ /dev/null @@ -1,26 +0,0 @@ -package mocks - -import ( - "context" - - broadcast_api "github.com/bitcoin-sv/go-broadcast-client/broadcast" -) - -type ArcClientMockOnChain struct { - ArcClientMock -} - -func (*ArcClientMockOnChain) SubmitTransaction(ctx context.Context, tx *broadcast_api.Transaction, opts ...broadcast_api.TransactionOptFunc) (*broadcast_api.SubmitTxResponse, error) { - return &broadcast_api.SubmitTxResponse{ - BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, - SubmittedTx: &broadcast_api.SubmittedTx{ - Status: 200, - Title: "OK", - TxStatus: "CONFIRMED", - }, - }, nil -} - -func NewArcClientMockOnChain() broadcast_api.Client { - return &ArcClientMockOnChain{} -} diff --git a/broadcast/internal/arc/mocks/arc_client_mock_success.go b/broadcast/internal/arc/mocks/arc_client_mock_success.go index 53c3d90..462df76 100644 --- a/broadcast/internal/arc/mocks/arc_client_mock_success.go +++ b/broadcast/internal/arc/mocks/arc_client_mock_success.go @@ -13,7 +13,7 @@ const ( type ArcClientMock struct{} -// GetFeeQuote implements broadcast.ClientMock. +// GetFeeQuote returns a successful FeeQuote response. func (*ArcClientMock) GetFeeQuote(ctx context.Context) ([]*broadcast_api.FeeQuote, error) { quote1 := &broadcast_api.FeeQuote{ BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, @@ -40,7 +40,7 @@ func (*ArcClientMock) GetFeeQuote(ctx context.Context) ([]*broadcast_api.FeeQuot return quotes, nil } -// GetPolicyQuote implements broadcast.ClientMock. +// GetPolicyQuote return a successful PolicyQuoteResponse. func (*ArcClientMock) GetPolicyQuote(ctx context.Context) ([]*broadcast_api.PolicyQuoteResponse, error) { policy1 := &broadcast_api.PolicyQuoteResponse{ BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, @@ -77,7 +77,7 @@ func (*ArcClientMock) GetPolicyQuote(ctx context.Context) ([]*broadcast_api.Poli return policies, nil } -// QueryTransaction implements broadcast.ClientMock. +// QueryTransaction returns a successful QueryTxResponse. func (*ArcClientMock) QueryTransaction(ctx context.Context, txID string) (*broadcast_api.QueryTxResponse, error) { return &broadcast_api.QueryTxResponse{ BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, @@ -87,7 +87,7 @@ func (*ArcClientMock) QueryTransaction(ctx context.Context, txID string) (*broad }, nil } -// SubmitTransaction implements broadcast.ClientMock. +// SubmitTransaction returns a successful SubmitTxResponse. func (*ArcClientMock) SubmitTransaction(ctx context.Context, tx *broadcast_api.Transaction, opts ...broadcast_api.TransactionOptFunc) (*broadcast_api.SubmitTxResponse, error) { return &broadcast_api.SubmitTxResponse{ BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, @@ -99,7 +99,7 @@ func (*ArcClientMock) SubmitTransaction(ctx context.Context, tx *broadcast_api.T }, nil } -// SubmitBatchTransactions implements broadcast.ClientMock. +// SubmitBatchTransactions returns a successful SubmitBatchTxResponse. func (*ArcClientMock) SubmitBatchTransactions(ctx context.Context, tx []*broadcast_api.Transaction, opts ...broadcast_api.TransactionOptFunc) (*broadcast_api.SubmitBatchTxResponse, error) { return &broadcast_api.SubmitBatchTxResponse{ BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, diff --git a/broadcast/internal/arc/mocks/arc_client_mock_timeout.go b/broadcast/internal/arc/mocks/arc_client_mock_timeout.go new file mode 100644 index 0000000..21aa84b --- /dev/null +++ b/broadcast/internal/arc/mocks/arc_client_mock_timeout.go @@ -0,0 +1,125 @@ +package mocks + +import ( + "context" + "time" + + broadcast_api "github.com/bitcoin-sv/go-broadcast-client/broadcast" +) + +const defaultMockTimeout = 20 * time.Second + +type ArcClientMockTimeout struct{} + +// GetFeeQuote returns a successful FeeQuote response after a long time. +func (*ArcClientMockTimeout) GetFeeQuote(ctx context.Context) ([]*broadcast_api.FeeQuote, error) { + quote1 := &broadcast_api.FeeQuote{ + BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, + MiningFee: broadcast_api.MiningFeeResponse{ + Bytes: 1000, + Satoshis: 1, + }, + Timestamp: "2023-09-05T17:03:49.537230128Z", + } + + quote2 := &broadcast_api.FeeQuote{ + BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl2}, + MiningFee: broadcast_api.MiningFeeResponse{ + Bytes: 1000, + Satoshis: 2, + }, + Timestamp: "2023-09-05T17:05:29.736256927Z", + } + + quotes := make([]*broadcast_api.FeeQuote, 2) + quotes = append(quotes, quote1) + quotes = append(quotes, quote2) + + time.Sleep(defaultMockTimeout) + return quotes, nil +} + +// GetPolicyQuote return a successful PolicyQuoteResponse after a long time. +func (*ArcClientMockTimeout) GetPolicyQuote(ctx context.Context) ([]*broadcast_api.PolicyQuoteResponse, error) { + policy1 := &broadcast_api.PolicyQuoteResponse{ + BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, + Policy: broadcast_api.PolicyResponse{ + MaxScriptSizePolicy: 100000000, + MaxTxSigOpsCountPolicy: 4294967295, + MaxTxSizePolicy: 100000000, + MiningFee: broadcast_api.MiningFeeResponse{ + Bytes: 1000, + Satoshis: 1, + }, + }, + Timestamp: "2023-09-05T17:03:49.537230128Z", + } + + policy2 := &broadcast_api.PolicyQuoteResponse{ + BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl2}, + Policy: broadcast_api.PolicyResponse{ + MaxScriptSizePolicy: 100000000, + MaxTxSigOpsCountPolicy: 4294967295, + MaxTxSizePolicy: 220000000, + MiningFee: broadcast_api.MiningFeeResponse{ + Bytes: 1000, + Satoshis: 2, + }, + }, + Timestamp: "2023-09-05T17:05:29.736256927Z", + } + + policies := make([]*broadcast_api.PolicyQuoteResponse, 2) + policies = append(policies, policy1) + policies = append(policies, policy2) + + time.Sleep(defaultMockTimeout) + return policies, nil +} + +// QueryTransaction returns a successful QueryTxResponse after a long time. +func (*ArcClientMockTimeout) QueryTransaction(ctx context.Context, txID string) (*broadcast_api.QueryTxResponse, error) { + return &broadcast_api.QueryTxResponse{ + BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, + Timestamp: "2023-09-05T17:05:29.736256927Z", + TxID: txID, + TxStatus: "SEEN_ON_NETWORK", + }, nil +} + +// SubmitTransaction returns a successful SubmitTxResponse after a long time. +func (*ArcClientMockTimeout) SubmitTransaction(ctx context.Context, tx *broadcast_api.Transaction, opts ...broadcast_api.TransactionOptFunc) (*broadcast_api.SubmitTxResponse, error) { + time.Sleep(defaultMockTimeout) + return &broadcast_api.SubmitTxResponse{ + BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, + SubmittedTx: &broadcast_api.SubmittedTx{ + Status: 200, + Title: "OK", + TxStatus: "SENT_TO_NETWORK", + }, + }, nil +} + +// SubmitBatchTransactions returns a successful SubmitBatchTxResponse after a long time. +func (*ArcClientMockTimeout) SubmitBatchTransactions(ctx context.Context, tx []*broadcast_api.Transaction, opts ...broadcast_api.TransactionOptFunc) (*broadcast_api.SubmitBatchTxResponse, error) { + time.Sleep(defaultMockTimeout) + return &broadcast_api.SubmitBatchTxResponse{ + BaseResponse: broadcast_api.BaseResponse{Miner: MockedApiUrl1}, + Transactions: []*broadcast_api.SubmittedTx{ + { + Status: 200, + Title: "OK", + TxStatus: "SENT_TO_NETWORK", + }, + { + Status: 200, + Title: "OK", + TxStatus: "SENT_TO_NETWORK", + }, + }, + }, nil +} + +func NewArcClientMockTimeout() broadcast_api.Client { + return &ArcClientMockTimeout{} +}