package client import ( "context" "testing" "github.com/stretchr/testify/require" moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1" connectorv1 "github.com/tech/sendico/pkg/proto/connector/v1" chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1" "google.golang.org/grpc" "google.golang.org/protobuf/types/known/wrapperspb" ) type stubConnectorClient struct { listReq *connectorv1.ListAccountsRequest getReq *connectorv1.GetOperationRequest submitReq *connectorv1.SubmitOperationRequest submitResp *connectorv1.SubmitOperationResponse getResp *connectorv1.GetOperationResponse } func (s *stubConnectorClient) GetCapabilities(ctx context.Context, in *connectorv1.GetCapabilitiesRequest, opts ...grpc.CallOption) (*connectorv1.GetCapabilitiesResponse, error) { return &connectorv1.GetCapabilitiesResponse{}, nil } func (s *stubConnectorClient) OpenAccount(ctx context.Context, in *connectorv1.OpenAccountRequest, opts ...grpc.CallOption) (*connectorv1.OpenAccountResponse, error) { return &connectorv1.OpenAccountResponse{}, nil } func (s *stubConnectorClient) GetAccount(ctx context.Context, in *connectorv1.GetAccountRequest, opts ...grpc.CallOption) (*connectorv1.GetAccountResponse, error) { return &connectorv1.GetAccountResponse{}, nil } func (s *stubConnectorClient) ListAccounts(ctx context.Context, in *connectorv1.ListAccountsRequest, opts ...grpc.CallOption) (*connectorv1.ListAccountsResponse, error) { s.listReq = in return &connectorv1.ListAccountsResponse{}, nil } func (s *stubConnectorClient) GetBalance(ctx context.Context, in *connectorv1.GetBalanceRequest, opts ...grpc.CallOption) (*connectorv1.GetBalanceResponse, error) { return &connectorv1.GetBalanceResponse{}, nil } func (s *stubConnectorClient) SubmitOperation(ctx context.Context, in *connectorv1.SubmitOperationRequest, opts ...grpc.CallOption) (*connectorv1.SubmitOperationResponse, error) { s.submitReq = in if s.submitResp != nil { return s.submitResp, nil } return &connectorv1.SubmitOperationResponse{}, nil } func (s *stubConnectorClient) GetOperation(ctx context.Context, in *connectorv1.GetOperationRequest, opts ...grpc.CallOption) (*connectorv1.GetOperationResponse, error) { s.getReq = in if s.getResp != nil { return s.getResp, nil } return &connectorv1.GetOperationResponse{}, nil } func (s *stubConnectorClient) ListOperations(ctx context.Context, in *connectorv1.ListOperationsRequest, opts ...grpc.CallOption) (*connectorv1.ListOperationsResponse, error) { return &connectorv1.ListOperationsResponse{}, nil } func TestListManagedWallets_ForwardsOrganizationRef(t *testing.T) { stub := &stubConnectorClient{} client := NewWithClient(Config{}, stub) _, err := client.ListManagedWallets(context.Background(), &chainv1.ListManagedWalletsRequest{ OrganizationRef: "org-1", OwnerRefFilter: wrapperspb.String("owner-1"), Asset: &chainv1.Asset{ Chain: chainv1.ChainNetwork_CHAIN_NETWORK_ETHEREUM_MAINNET, TokenSymbol: "USDC", }, }) require.NoError(t, err) require.NotNil(t, stub.listReq) require.Equal(t, "org-1", stub.listReq.GetOrganizationRef()) require.Equal(t, "owner-1", stub.listReq.GetOwnerRefFilter().GetValue()) require.Equal(t, connectorv1.AccountKind_CHAIN_MANAGED_WALLET, stub.listReq.GetKind()) } func TestTransferFromReceipt_PreservesRequestReferences(t *testing.T) { req := &chainv1.SubmitTransferRequest{ IdempotencyKey: "idem-1", OrganizationRef: "org-1", SourceWalletRef: "wallet-src", Amount: &moneyv1.Money{Amount: "12.34", Currency: "USDT"}, IntentRef: "intent-1", OperationRef: "payment-1:hop_2_settlement_fx_convert", PaymentRef: "payment-1", } receipt := &connectorv1.OperationReceipt{ OperationId: "payment-1:hop_2_settlement_fx_convert", ProviderRef: "provider-1", Status: connectorv1.OperationStatus_OPERATION_WAITING, } transfer := transferFromReceipt(req, receipt) require.NotNil(t, transfer) require.Equal(t, "payment-1:hop_2_settlement_fx_convert", transfer.GetTransferRef()) require.Equal(t, "intent-1", transfer.GetIntentRef()) require.Equal(t, "payment-1:hop_2_settlement_fx_convert", transfer.GetOperationRef()) require.Equal(t, "payment-1", transfer.GetPaymentRef()) require.Equal(t, chainv1.TransferStatus_TRANSFER_WAITING, transfer.GetStatus()) } func TestSubmitTransfer_ForwardsOperationAndIntentReferences(t *testing.T) { stub := &stubConnectorClient{ submitResp: &connectorv1.SubmitOperationResponse{ Receipt: &connectorv1.OperationReceipt{ OperationId: "payment-1:hop_2_settlement_fx_convert", Status: connectorv1.OperationStatus_OPERATION_WAITING, ProviderRef: "provider-1", }, }, } client := NewWithClient(Config{}, stub) resp, err := client.SubmitTransfer(context.Background(), &chainv1.SubmitTransferRequest{ IdempotencyKey: "idem-1", OrganizationRef: "org-1", SourceWalletRef: "wallet-src", Destination: &chainv1.TransferDestination{ Destination: &chainv1.TransferDestination_ManagedWalletRef{ ManagedWalletRef: "wallet-dst", }, }, Amount: &moneyv1.Money{Amount: "12.34", Currency: "USDT"}, IntentRef: "intent-1", OperationRef: "payment-1:hop_2_settlement_fx_convert", PaymentRef: "payment-1", }) require.NoError(t, err) require.NotNil(t, stub.submitReq) require.NotNil(t, stub.submitReq.GetOperation()) require.Equal(t, "intent-1", stub.submitReq.GetOperation().GetIntentRef()) require.Equal(t, "payment-1:hop_2_settlement_fx_convert", stub.submitReq.GetOperation().GetOperationRef()) require.NotNil(t, resp.GetTransfer()) require.Equal(t, "payment-1:hop_2_settlement_fx_convert", resp.GetTransfer().GetTransferRef()) require.Equal(t, "payment-1:hop_2_settlement_fx_convert", resp.GetTransfer().GetOperationRef()) require.Equal(t, "intent-1", resp.GetTransfer().GetIntentRef()) } func TestGetTransfer_UsesTransferRefAsOperationID(t *testing.T) { stub := &stubConnectorClient{ getResp: &connectorv1.GetOperationResponse{ Operation: &connectorv1.Operation{ OperationId: "transfer-1", Status: connectorv1.OperationStatus_OPERATION_PROCESSING, }, }, } client := NewWithClient(Config{}, stub) resp, err := client.GetTransfer(context.Background(), &chainv1.GetTransferRequest{TransferRef: "transfer-1"}) require.NoError(t, err) require.NotNil(t, stub.getReq) require.Equal(t, "transfer-1", stub.getReq.GetOperationId()) require.NotNil(t, resp.GetTransfer()) require.Equal(t, "transfer-1", resp.GetTransfer().GetTransferRef()) }