diff --git a/internal/rpc/client_test.go b/internal/rpc/client_test.go index dfff458..2002b8a 100644 --- a/internal/rpc/client_test.go +++ b/internal/rpc/client_test.go @@ -8,9 +8,9 @@ import ( "github.com/stellar/go/clients/horizonclient" hProtocol "github.com/stellar/go/protocols/horizon" - "github.com/stellar/go/txnbuild" effects "github.com/stellar/go/protocols/horizon/effects" operations "github.com/stellar/go/protocols/horizon/operations" + "github.com/stellar/go/txnbuild" "github.com/stretchr/testify/assert" ) @@ -21,147 +21,263 @@ type mockHorizonClient struct { func (m *mockHorizonClient) TransactionDetail(hash string) (hProtocol.Transaction, error) { return m.TransactionDetailFunc(hash) } -func (m *mockHorizonClient) AccountData(request horizonclient.AccountRequest) (hProtocol.AccountData, error) { return hProtocol.AccountData{}, nil } -func (m *mockHorizonClient) AccountDetail(request horizonclient.AccountRequest) (hProtocol.Account, error) { return hProtocol.Account{}, nil } -func (m *mockHorizonClient) Accounts(request horizonclient.AccountsRequest) (hProtocol.AccountsPage, error) { return hProtocol.AccountsPage{}, nil } -func (m *mockHorizonClient) Effects(request horizonclient.EffectRequest) (effects.EffectsPage, error) { return effects.EffectsPage{}, nil } -func (m *mockHorizonClient) Assets(request horizonclient.AssetRequest) (hProtocol.AssetsPage, error) { return hProtocol.AssetsPage{}, nil } -func (m *mockHorizonClient) Ledgers(request horizonclient.LedgerRequest) (hProtocol.LedgersPage, error) { return hProtocol.LedgersPage{}, nil } -func (m *mockHorizonClient) LedgerDetail(sequence uint32) (hProtocol.Ledger, error) { return hProtocol.Ledger{}, nil } +func (m *mockHorizonClient) AccountData(request horizonclient.AccountRequest) (hProtocol.AccountData, error) { + return hProtocol.AccountData{}, nil +} +func (m *mockHorizonClient) AccountDetail(request horizonclient.AccountRequest) (hProtocol.Account, error) { + return hProtocol.Account{}, nil +} +func (m *mockHorizonClient) Accounts(request horizonclient.AccountsRequest) (hProtocol.AccountsPage, error) { + return hProtocol.AccountsPage{}, nil +} +func (m *mockHorizonClient) Effects(request horizonclient.EffectRequest) (effects.EffectsPage, error) { + return effects.EffectsPage{}, nil +} +func (m *mockHorizonClient) Assets(request horizonclient.AssetRequest) (hProtocol.AssetsPage, error) { + return hProtocol.AssetsPage{}, nil +} +func (m *mockHorizonClient) Ledgers(request horizonclient.LedgerRequest) (hProtocol.LedgersPage, error) { + return hProtocol.LedgersPage{}, nil +} +func (m *mockHorizonClient) LedgerDetail(sequence uint32) (hProtocol.Ledger, error) { + return hProtocol.Ledger{}, nil +} func (m *mockHorizonClient) FeeStats() (hProtocol.FeeStats, error) { return hProtocol.FeeStats{}, nil } -func (m *mockHorizonClient) Offers(request horizonclient.OfferRequest) (hProtocol.OffersPage, error) { return hProtocol.OffersPage{}, nil } -func (m *mockHorizonClient) OfferDetails(offerID string) (hProtocol.Offer, error) { return hProtocol.Offer{}, nil } -func (m *mockHorizonClient) Operations(request horizonclient.OperationRequest) (operations.OperationsPage, error) { return operations.OperationsPage{}, nil } +func (m *mockHorizonClient) Offers(request horizonclient.OfferRequest) (hProtocol.OffersPage, error) { + return hProtocol.OffersPage{}, nil +} +func (m *mockHorizonClient) OfferDetails(offerID string) (hProtocol.Offer, error) { + return hProtocol.Offer{}, nil +} +func (m *mockHorizonClient) Operations(request horizonclient.OperationRequest) (operations.OperationsPage, error) { + return operations.OperationsPage{}, nil +} func (m *mockHorizonClient) OperationDetail(id string) (operations.Operation, error) { var op operations.Operation return op, nil } -func (m *mockHorizonClient) StreamPayments(ctx context.Context, request horizonclient.OperationRequest, handler horizonclient.OperationHandler) error { return nil } -func (m *mockHorizonClient) SubmitTransactionXDR(transactionXdr string) (hProtocol.Transaction, error) { return hProtocol.Transaction{}, nil } -func (m *mockHorizonClient) SubmitFeeBumpTransactionWithOptions(transaction *txnbuild.FeeBumpTransaction, opts horizonclient.SubmitTxOpts) (hProtocol.Transaction, error) { return hProtocol.Transaction{}, nil } -func (m *mockHorizonClient) SubmitTransactionWithOptions(transaction *txnbuild.Transaction, opts horizonclient.SubmitTxOpts) (hProtocol.Transaction, error) { return hProtocol.Transaction{}, nil } -func (m *mockHorizonClient) SubmitFeeBumpTransaction(transaction *txnbuild.FeeBumpTransaction) (hProtocol.Transaction, error) { return hProtocol.Transaction{}, nil } -func (m *mockHorizonClient) SubmitTransaction(transaction *txnbuild.Transaction) (hProtocol.Transaction, error) { return hProtocol.Transaction{}, nil } -func (m *mockHorizonClient) AsyncSubmitTransactionXDR(transactionXdr string) (hProtocol.AsyncTransactionSubmissionResponse, error) { return hProtocol.AsyncTransactionSubmissionResponse{}, nil } -func (m *mockHorizonClient) AsyncSubmitFeeBumpTransactionWithOptions(transaction *txnbuild.FeeBumpTransaction, opts horizonclient.SubmitTxOpts) (hProtocol.AsyncTransactionSubmissionResponse, error) { return hProtocol.AsyncTransactionSubmissionResponse{}, nil } -func (m *mockHorizonClient) AsyncSubmitTransactionWithOptions(transaction *txnbuild.Transaction, opts horizonclient.SubmitTxOpts) (hProtocol.AsyncTransactionSubmissionResponse, error) { return hProtocol.AsyncTransactionSubmissionResponse{}, nil } -func (m *mockHorizonClient) AsyncSubmitFeeBumpTransaction(transaction *txnbuild.FeeBumpTransaction) (hProtocol.AsyncTransactionSubmissionResponse, error) { return hProtocol.AsyncTransactionSubmissionResponse{}, nil } -func (m *mockHorizonClient) AsyncSubmitTransaction(transaction *txnbuild.Transaction) (hProtocol.AsyncTransactionSubmissionResponse, error) { return hProtocol.AsyncTransactionSubmissionResponse{}, nil } -func (m *mockHorizonClient) Transactions(request horizonclient.TransactionRequest) (hProtocol.TransactionsPage, error) { return hProtocol.TransactionsPage{}, nil } -func (m *mockHorizonClient) OrderBook(request horizonclient.OrderBookRequest) (hProtocol.OrderBookSummary, error) { return hProtocol.OrderBookSummary{}, nil } -func (m *mockHorizonClient) Paths(request horizonclient.PathsRequest) (hProtocol.PathsPage, error) { return hProtocol.PathsPage{}, nil } -func (m *mockHorizonClient) Payments(request horizonclient.OperationRequest) (operations.OperationsPage, error) { return operations.OperationsPage{}, nil } -func (m *mockHorizonClient) TradeAggregations(request horizonclient.TradeAggregationRequest) (hProtocol.TradeAggregationsPage, error) { return hProtocol.TradeAggregationsPage{}, nil } -func (m *mockHorizonClient) Trades(request horizonclient.TradeRequest) (hProtocol.TradesPage, error) { return hProtocol.TradesPage{}, nil } -func (m *mockHorizonClient) Fund(addr string) (hProtocol.Transaction, error) { return hProtocol.Transaction{}, nil } -func (m *mockHorizonClient) StreamTransactions(ctx context.Context, request horizonclient.TransactionRequest, handler horizonclient.TransactionHandler) error { return nil } -func (m *mockHorizonClient) StreamTrades(ctx context.Context, request horizonclient.TradeRequest, handler horizonclient.TradeHandler) error { return nil } -func (m *mockHorizonClient) StreamEffects(ctx context.Context, request horizonclient.EffectRequest, handler horizonclient.EffectHandler) error { return nil } -func (m *mockHorizonClient) StreamOperations(ctx context.Context, request horizonclient.OperationRequest, handler horizonclient.OperationHandler) error { return nil } -func (m *mockHorizonClient) StreamOffers(ctx context.Context, request horizonclient.OfferRequest, handler horizonclient.OfferHandler) error { return nil } -func (m *mockHorizonClient) StreamLedgers(ctx context.Context, request horizonclient.LedgerRequest, handler horizonclient.LedgerHandler) error { return nil } -func (m *mockHorizonClient) StreamOrderBooks(ctx context.Context, request horizonclient.OrderBookRequest, handler horizonclient.OrderBookHandler) error { return nil } +func (m *mockHorizonClient) StreamPayments(ctx context.Context, request horizonclient.OperationRequest, handler horizonclient.OperationHandler) error { + return nil +} +func (m *mockHorizonClient) SubmitTransactionXDR(transactionXdr string) (hProtocol.Transaction, error) { + return hProtocol.Transaction{}, nil +} +func (m *mockHorizonClient) SubmitFeeBumpTransactionWithOptions(transaction *txnbuild.FeeBumpTransaction, opts horizonclient.SubmitTxOpts) (hProtocol.Transaction, error) { + return hProtocol.Transaction{}, nil +} +func (m *mockHorizonClient) SubmitTransactionWithOptions(transaction *txnbuild.Transaction, opts horizonclient.SubmitTxOpts) (hProtocol.Transaction, error) { + return hProtocol.Transaction{}, nil +} +func (m *mockHorizonClient) SubmitFeeBumpTransaction(transaction *txnbuild.FeeBumpTransaction) (hProtocol.Transaction, error) { + return hProtocol.Transaction{}, nil +} +func (m *mockHorizonClient) SubmitTransaction(transaction *txnbuild.Transaction) (hProtocol.Transaction, error) { + return hProtocol.Transaction{}, nil +} +func (m *mockHorizonClient) AsyncSubmitTransactionXDR(transactionXdr string) (hProtocol.AsyncTransactionSubmissionResponse, error) { + return hProtocol.AsyncTransactionSubmissionResponse{}, nil +} +func (m *mockHorizonClient) AsyncSubmitFeeBumpTransactionWithOptions(transaction *txnbuild.FeeBumpTransaction, opts horizonclient.SubmitTxOpts) (hProtocol.AsyncTransactionSubmissionResponse, error) { + return hProtocol.AsyncTransactionSubmissionResponse{}, nil +} +func (m *mockHorizonClient) AsyncSubmitTransactionWithOptions(transaction *txnbuild.Transaction, opts horizonclient.SubmitTxOpts) (hProtocol.AsyncTransactionSubmissionResponse, error) { + return hProtocol.AsyncTransactionSubmissionResponse{}, nil +} +func (m *mockHorizonClient) AsyncSubmitFeeBumpTransaction(transaction *txnbuild.FeeBumpTransaction) (hProtocol.AsyncTransactionSubmissionResponse, error) { + return hProtocol.AsyncTransactionSubmissionResponse{}, nil +} +func (m *mockHorizonClient) AsyncSubmitTransaction(transaction *txnbuild.Transaction) (hProtocol.AsyncTransactionSubmissionResponse, error) { + return hProtocol.AsyncTransactionSubmissionResponse{}, nil +} +func (m *mockHorizonClient) Transactions(request horizonclient.TransactionRequest) (hProtocol.TransactionsPage, error) { + return hProtocol.TransactionsPage{}, nil +} +func (m *mockHorizonClient) OrderBook(request horizonclient.OrderBookRequest) (hProtocol.OrderBookSummary, error) { + return hProtocol.OrderBookSummary{}, nil +} +func (m *mockHorizonClient) Paths(request horizonclient.PathsRequest) (hProtocol.PathsPage, error) { + return hProtocol.PathsPage{}, nil +} +func (m *mockHorizonClient) Payments(request horizonclient.OperationRequest) (operations.OperationsPage, error) { + return operations.OperationsPage{}, nil +} +func (m *mockHorizonClient) TradeAggregations(request horizonclient.TradeAggregationRequest) (hProtocol.TradeAggregationsPage, error) { + return hProtocol.TradeAggregationsPage{}, nil +} +func (m *mockHorizonClient) Trades(request horizonclient.TradeRequest) (hProtocol.TradesPage, error) { + return hProtocol.TradesPage{}, nil +} +func (m *mockHorizonClient) Fund(addr string) (hProtocol.Transaction, error) { + return hProtocol.Transaction{}, nil +} +func (m *mockHorizonClient) StreamTransactions(ctx context.Context, request horizonclient.TransactionRequest, handler horizonclient.TransactionHandler) error { + return nil +} +func (m *mockHorizonClient) StreamTrades(ctx context.Context, request horizonclient.TradeRequest, handler horizonclient.TradeHandler) error { + return nil +} +func (m *mockHorizonClient) StreamEffects(ctx context.Context, request horizonclient.EffectRequest, handler horizonclient.EffectHandler) error { + return nil +} +func (m *mockHorizonClient) StreamOperations(ctx context.Context, request horizonclient.OperationRequest, handler horizonclient.OperationHandler) error { + return nil +} +func (m *mockHorizonClient) StreamOffers(ctx context.Context, request horizonclient.OfferRequest, handler horizonclient.OfferHandler) error { + return nil +} +func (m *mockHorizonClient) StreamLedgers(ctx context.Context, request horizonclient.LedgerRequest, handler horizonclient.LedgerHandler) error { + return nil +} +func (m *mockHorizonClient) StreamOrderBooks(ctx context.Context, request horizonclient.OrderBookRequest, handler horizonclient.OrderBookHandler) error { + return nil +} func (m *mockHorizonClient) Root() (hProtocol.Root, error) { return hProtocol.Root{}, nil } -func (m *mockHorizonClient) NextAccountsPage(page hProtocol.AccountsPage) (hProtocol.AccountsPage, error) { return hProtocol.AccountsPage{}, nil } -func (m *mockHorizonClient) NextAssetsPage(page hProtocol.AssetsPage) (hProtocol.AssetsPage, error) { return hProtocol.AssetsPage{}, nil } -func (m *mockHorizonClient) PrevAssetsPage(page hProtocol.AssetsPage) (hProtocol.AssetsPage, error) { return hProtocol.AssetsPage{}, nil } -func (m *mockHorizonClient) NextLedgersPage(page hProtocol.LedgersPage) (hProtocol.LedgersPage, error) { return hProtocol.LedgersPage{}, nil } -func (m *mockHorizonClient) PrevLedgersPage(page hProtocol.LedgersPage) (hProtocol.LedgersPage, error) { return hProtocol.LedgersPage{}, nil } -func (m *mockHorizonClient) NextEffectsPage(page effects.EffectsPage) (effects.EffectsPage, error) { return effects.EffectsPage{}, nil } -func (m *mockHorizonClient) PrevEffectsPage(page effects.EffectsPage) (effects.EffectsPage, error) { return effects.EffectsPage{}, nil } -func (m *mockHorizonClient) NextTransactionsPage(page hProtocol.TransactionsPage) (hProtocol.TransactionsPage, error) { return hProtocol.TransactionsPage{}, nil } -func (m *mockHorizonClient) PrevTransactionsPage(page hProtocol.TransactionsPage) (hProtocol.TransactionsPage, error) { return hProtocol.TransactionsPage{}, nil } -func (m *mockHorizonClient) NextOperationsPage(page operations.OperationsPage) (operations.OperationsPage, error) { return operations.OperationsPage{}, nil } -func (m *mockHorizonClient) PrevOperationsPage(page operations.OperationsPage) (operations.OperationsPage, error) { return operations.OperationsPage{}, nil } -func (m *mockHorizonClient) NextPaymentsPage(page operations.OperationsPage) (operations.OperationsPage, error) { return operations.OperationsPage{}, nil } -func (m *mockHorizonClient) PrevPaymentsPage(page operations.OperationsPage) (operations.OperationsPage, error) { return operations.OperationsPage{}, nil } -func (m *mockHorizonClient) NextOffersPage(page hProtocol.OffersPage) (hProtocol.OffersPage, error) { return hProtocol.OffersPage{}, nil } -func (m *mockHorizonClient) PrevOffersPage(page hProtocol.OffersPage) (hProtocol.OffersPage, error) { return hProtocol.OffersPage{}, nil } -func (m *mockHorizonClient) NextTradesPage(page hProtocol.TradesPage) (hProtocol.TradesPage, error) { return hProtocol.TradesPage{}, nil } -func (m *mockHorizonClient) PrevTradesPage(page hProtocol.TradesPage) (hProtocol.TradesPage, error) { return hProtocol.TradesPage{}, nil } +func (m *mockHorizonClient) NextAccountsPage(page hProtocol.AccountsPage) (hProtocol.AccountsPage, error) { + return hProtocol.AccountsPage{}, nil +} +func (m *mockHorizonClient) NextAssetsPage(page hProtocol.AssetsPage) (hProtocol.AssetsPage, error) { + return hProtocol.AssetsPage{}, nil +} +func (m *mockHorizonClient) PrevAssetsPage(page hProtocol.AssetsPage) (hProtocol.AssetsPage, error) { + return hProtocol.AssetsPage{}, nil +} +func (m *mockHorizonClient) NextLedgersPage(page hProtocol.LedgersPage) (hProtocol.LedgersPage, error) { + return hProtocol.LedgersPage{}, nil +} +func (m *mockHorizonClient) PrevLedgersPage(page hProtocol.LedgersPage) (hProtocol.LedgersPage, error) { + return hProtocol.LedgersPage{}, nil +} +func (m *mockHorizonClient) NextEffectsPage(page effects.EffectsPage) (effects.EffectsPage, error) { + return effects.EffectsPage{}, nil +} +func (m *mockHorizonClient) PrevEffectsPage(page effects.EffectsPage) (effects.EffectsPage, error) { + return effects.EffectsPage{}, nil +} +func (m *mockHorizonClient) NextTransactionsPage(page hProtocol.TransactionsPage) (hProtocol.TransactionsPage, error) { + return hProtocol.TransactionsPage{}, nil +} +func (m *mockHorizonClient) PrevTransactionsPage(page hProtocol.TransactionsPage) (hProtocol.TransactionsPage, error) { + return hProtocol.TransactionsPage{}, nil +} +func (m *mockHorizonClient) NextOperationsPage(page operations.OperationsPage) (operations.OperationsPage, error) { + return operations.OperationsPage{}, nil +} +func (m *mockHorizonClient) PrevOperationsPage(page operations.OperationsPage) (operations.OperationsPage, error) { + return operations.OperationsPage{}, nil +} +func (m *mockHorizonClient) NextPaymentsPage(page operations.OperationsPage) (operations.OperationsPage, error) { + return operations.OperationsPage{}, nil +} +func (m *mockHorizonClient) PrevPaymentsPage(page operations.OperationsPage) (operations.OperationsPage, error) { + return operations.OperationsPage{}, nil +} +func (m *mockHorizonClient) NextOffersPage(page hProtocol.OffersPage) (hProtocol.OffersPage, error) { + return hProtocol.OffersPage{}, nil +} +func (m *mockHorizonClient) PrevOffersPage(page hProtocol.OffersPage) (hProtocol.OffersPage, error) { + return hProtocol.OffersPage{}, nil +} +func (m *mockHorizonClient) NextTradesPage(page hProtocol.TradesPage) (hProtocol.TradesPage, error) { + return hProtocol.TradesPage{}, nil +} +func (m *mockHorizonClient) PrevTradesPage(page hProtocol.TradesPage) (hProtocol.TradesPage, error) { + return hProtocol.TradesPage{}, nil +} func (m *mockHorizonClient) HomeDomainForAccount(aid string) (string, error) { return "", nil } -func (m *mockHorizonClient) NextTradeAggregationsPage(page hProtocol.TradeAggregationsPage) (hProtocol.TradeAggregationsPage, error) { return hProtocol.TradeAggregationsPage{}, nil } -func (m *mockHorizonClient) PrevTradeAggregationsPage(page hProtocol.TradeAggregationsPage) (hProtocol.TradeAggregationsPage, error) { return hProtocol.TradeAggregationsPage{}, nil } -func (m *mockHorizonClient) LiquidityPoolDetail(request horizonclient.LiquidityPoolRequest) (hProtocol.LiquidityPool, error) { return hProtocol.LiquidityPool{}, nil } -func (m *mockHorizonClient) LiquidityPools(request horizonclient.LiquidityPoolsRequest) (hProtocol.LiquidityPoolsPage, error) { return hProtocol.LiquidityPoolsPage{}, nil } -func (m *mockHorizonClient) NextLiquidityPoolsPage(page hProtocol.LiquidityPoolsPage) (hProtocol.LiquidityPoolsPage, error) { return hProtocol.LiquidityPoolsPage{}, nil } -func (m *mockHorizonClient) PrevLiquidityPoolsPage(page hProtocol.LiquidityPoolsPage) (hProtocol.LiquidityPoolsPage, error) { return hProtocol.LiquidityPoolsPage{}, nil } +func (m *mockHorizonClient) NextTradeAggregationsPage(page hProtocol.TradeAggregationsPage) (hProtocol.TradeAggregationsPage, error) { + return hProtocol.TradeAggregationsPage{}, nil +} +func (m *mockHorizonClient) PrevTradeAggregationsPage(page hProtocol.TradeAggregationsPage) (hProtocol.TradeAggregationsPage, error) { + return hProtocol.TradeAggregationsPage{}, nil +} +func (m *mockHorizonClient) LiquidityPoolDetail(request horizonclient.LiquidityPoolRequest) (hProtocol.LiquidityPool, error) { + return hProtocol.LiquidityPool{}, nil +} +func (m *mockHorizonClient) LiquidityPools(request horizonclient.LiquidityPoolsRequest) (hProtocol.LiquidityPoolsPage, error) { + return hProtocol.LiquidityPoolsPage{}, nil +} +func (m *mockHorizonClient) NextLiquidityPoolsPage(page hProtocol.LiquidityPoolsPage) (hProtocol.LiquidityPoolsPage, error) { + return hProtocol.LiquidityPoolsPage{}, nil +} +func (m *mockHorizonClient) PrevLiquidityPoolsPage(page hProtocol.LiquidityPoolsPage) (hProtocol.LiquidityPoolsPage, error) { + return hProtocol.LiquidityPoolsPage{}, nil +} type testClient struct { *Client } func newTestClient(mock horizonclient.ClientInterface) *testClient { - return &testClient{ - &Client{Horizon: mock.(*mockHorizonClient)}, - } + return &testClient{ + &Client{Horizon: mock.(*mockHorizonClient)}, + } } func TestGetTransaction(t *testing.T) { - tests := []struct { - name string - hash string - mockFunc func(hash string) (hProtocol.Transaction, error) - expectErr bool - }{ - { - name: "success", - hash: "abc123", - mockFunc: func(hash string) (hProtocol.Transaction, error) { - return hProtocol.Transaction{ - EnvelopeXdr: "envelope-xdr", - ResultXdr: "result-xdr", - ResultMetaXdr: "meta-xdr", - }, nil - }, - expectErr: false, - }, - { - name: "error", - hash: "fail", - mockFunc: func(hash string) (hProtocol.Transaction, error) { - return hProtocol.Transaction{}, errors.New("not found") - }, - expectErr: true, - }, - } + tests := []struct { + name string + hash string + mockFunc func(hash string) (hProtocol.Transaction, error) + expectErr bool + }{ + { + name: "success", + hash: "abc123", + mockFunc: func(hash string) (hProtocol.Transaction, error) { + return hProtocol.Transaction{ + EnvelopeXdr: "envelope-xdr", + ResultXdr: "result-xdr", + ResultMetaXdr: "meta-xdr", + }, nil + }, + expectErr: false, + }, + { + name: "error", + hash: "fail", + mockFunc: func(hash string) (hProtocol.Transaction, error) { + return hProtocol.Transaction{}, errors.New("not found") + }, + expectErr: true, + }, + } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - mock := &mockHorizonClient{TransactionDetailFunc: tt.mockFunc} - c := newTestClient(mock) - ctx := context.Background() - resp, err := c.GetTransaction(ctx, tt.hash) - if tt.expectErr { - assert.Error(t, err) - assert.Nil(t, resp) - } else { - assert.NoError(t, err) - assert.NotNil(t, resp) - assert.Equal(t, "envelope-xdr", resp.EnvelopeXdr) - assert.Equal(t, "result-xdr", resp.ResultXdr) - assert.Equal(t, "meta-xdr", resp.ResultMetaXdr) - } - }) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mock := &mockHorizonClient{TransactionDetailFunc: tt.mockFunc} + c := newTestClient(mock) + ctx := context.Background() + resp, err := c.GetTransaction(ctx, tt.hash) + if tt.expectErr { + assert.Error(t, err) + assert.Nil(t, resp) + } else { + assert.NoError(t, err) + assert.NotNil(t, resp) + assert.Equal(t, "envelope-xdr", resp.EnvelopeXdr) + assert.Equal(t, "result-xdr", resp.ResultXdr) + assert.Equal(t, "meta-xdr", resp.ResultMetaXdr) + } + }) + } } func TestGetTransaction_Timeout(t *testing.T) { - var testCtx context.Context - mock := &mockHorizonClient{ - TransactionDetailFunc: func(hash string) (hProtocol.Transaction, error) { - select { - case <-time.After(2 * time.Second): - return hProtocol.Transaction{}, nil - case <-testCtx.Done(): - return hProtocol.Transaction{}, testCtx.Err() - } - }, - } - c := newTestClient(mock) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) - defer cancel() - testCtx = ctx - _, err := c.GetTransaction(ctx, "timeout") - assert.Error(t, err) + var testCtx context.Context + mock := &mockHorizonClient{ + TransactionDetailFunc: func(hash string) (hProtocol.Transaction, error) { + select { + case <-time.After(2 * time.Second): + return hProtocol.Transaction{}, nil + case <-testCtx.Done(): + return hProtocol.Transaction{}, testCtx.Err() + } + }, + } + c := newTestClient(mock) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + defer cancel() + testCtx = ctx + _, err := c.GetTransaction(ctx, "timeout") + assert.Error(t, err) } diff --git a/internal/simulator/interface.go b/internal/simulator/interface.go new file mode 100644 index 0000000..b967d72 --- /dev/null +++ b/internal/simulator/interface.go @@ -0,0 +1,5 @@ +package simulator + +type Runner interface { + Run(req *SimulationRequest) (*SimulationResponse, error) +} diff --git a/internal/simulator/mock_runner.go b/internal/simulator/mock_runner.go new file mode 100644 index 0000000..be90f0e --- /dev/null +++ b/internal/simulator/mock_runner.go @@ -0,0 +1,28 @@ +package simulator + +type MockRunner struct { + RunFunc func(req *SimulationRequest) (*SimulationResponse, error) +} + +func (m *MockRunner) Run(req *SimulationRequest) (*SimulationResponse, error) { + if m.RunFunc != nil { + return m.RunFunc(req) + } + return &SimulationResponse{Status: "success"}, nil +} + +func NewMockRunner(fn func(req *SimulationRequest) (*SimulationResponse, error)) *MockRunner { + return &MockRunner{RunFunc: fn} +} + +func NewDefaultMockRunner() *MockRunner { + return &MockRunner{ + RunFunc: func(req *SimulationRequest) (*SimulationResponse, error) { + return &SimulationResponse{ + Status: "success", + Events: []string{}, + Logs: []string{}, + }, nil + }, + } +} diff --git a/internal/simulator/mock_runner_test.go b/internal/simulator/mock_runner_test.go new file mode 100644 index 0000000..72a166b --- /dev/null +++ b/internal/simulator/mock_runner_test.go @@ -0,0 +1,88 @@ +package simulator + +import ( + "errors" + "testing" +) + +func TestMockRunnerDefault(t *testing.T) { + mock := NewDefaultMockRunner() + + req := &SimulationRequest{ + EnvelopeXdr: "test", + } + + resp, err := mock.Run(req) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if resp.Status != "success" { + t.Errorf("expected success status, got %s", resp.Status) + } +} + +func TestMockRunnerCustom(t *testing.T) { + customErr := errors.New("custom error") + mock := NewMockRunner(func(req *SimulationRequest) (*SimulationResponse, error) { + return nil, customErr + }) + + req := &SimulationRequest{ + EnvelopeXdr: "test", + } + + resp, err := mock.Run(req) + if err != customErr { + t.Errorf("expected custom error, got %v", err) + } + if resp != nil { + t.Error("expected nil response with error") + } +} + +func TestMockRunnerCustomResponse(t *testing.T) { + expectedResp := &SimulationResponse{ + Status: "failed", + Error: "test error", + Events: []string{"event1", "event2"}, + } + mock := NewMockRunner(func(req *SimulationRequest) (*SimulationResponse, error) { + return expectedResp, nil + }) + + req := &SimulationRequest{ + EnvelopeXdr: "test", + } + + resp, err := mock.Run(req) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if resp.Status != expectedResp.Status { + t.Errorf("expected status %s, got %s", expectedResp.Status, resp.Status) + } + if len(resp.Events) != 2 { + t.Errorf("expected 2 events, got %d", len(resp.Events)) + } +} + +func TestRunnerInterface(t *testing.T) { + var runner Runner + runner = NewDefaultMockRunner() + + if runner == nil { + t.Error("runner should not be nil") + } + + req := &SimulationRequest{ + EnvelopeXdr: "test", + } + + resp, err := runner.Run(req) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if resp == nil { + t.Error("response should not be nil") + } +} diff --git a/internal/simulator/runner.go b/internal/simulator/runner.go index 568d364..14af156 100644 --- a/internal/simulator/runner.go +++ b/internal/simulator/runner.go @@ -11,17 +11,17 @@ import ( "github.com/dotandev/hintents/internal/logger" ) -// Runner handles the execution of the Rust simulator binary -type Runner struct { +// ConcreteRunner handles the execution of the Rust simulator binary +type ConcreteRunner struct { BinaryPath string } // NewRunner creates a new simulator runner. // It checks for the binary in common locations. -func NewRunner() (*Runner, error) { +func NewRunner() (*ConcreteRunner, error) { // 1. Check environment variable if envPath := os.Getenv("ERST_SIMULATOR_PATH"); envPath != "" { - return &Runner{BinaryPath: envPath}, nil + return &ConcreteRunner{BinaryPath: envPath}, nil } // 2. Check current directory (for Docker/Production) @@ -29,26 +29,26 @@ func NewRunner() (*Runner, error) { if err == nil { localPath := filepath.Join(cwd, "erst-sim") if _, err := os.Stat(localPath); err == nil { - return &Runner{BinaryPath: localPath}, nil + return &ConcreteRunner{BinaryPath: localPath}, nil } } // 3. Check development path (assuming running from sdk root) devPath := filepath.Join("simulator", "target", "release", "erst-sim") if _, err := os.Stat(devPath); err == nil { - return &Runner{BinaryPath: devPath}, nil + return &ConcreteRunner{BinaryPath: devPath}, nil } // 4. Check global PATH if path, err := exec.LookPath("erst-sim"); err == nil { - return &Runner{BinaryPath: path}, nil + return &ConcreteRunner{BinaryPath: path}, nil } return nil, fmt.Errorf("simulator binary 'erst-sim' not found. Please build it or set ERST_SIMULATOR_PATH") } // Run executes the simulation with the given request -func (r *Runner) Run(req *SimulationRequest) (*SimulationResponse, error) { +func (r *ConcreteRunner) Run(req *SimulationRequest) (*SimulationResponse, error) { logger.Logger.Debug("Starting simulation", "binary", r.BinaryPath) // Serialize Request