From 8410b6b79fe107f863028da1bd67c1f676631da2 Mon Sep 17 00:00:00 2001 From: Roman Dmitrienko Date: Thu, 30 Jan 2025 11:25:15 +0300 Subject: [PATCH] test: add API tests and mocks --- api/api_test.go | 215 +++++++++++ api/mocks/LNClient.go | 860 ++++++++++++++++++++++++++++++++++++++++++ api/mocks/Service.go | 225 +++++++++++ 3 files changed, 1300 insertions(+) create mode 100644 api/api_test.go create mode 100644 api/mocks/LNClient.go create mode 100644 api/mocks/Service.go diff --git a/api/api_test.go b/api/api_test.go new file mode 100644 index 00000000..b9ecc54b --- /dev/null +++ b/api/api_test.go @@ -0,0 +1,215 @@ +package api + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/getAlby/hub/api/mocks" + "github.com/getAlby/hub/lnclient" + "github.com/getAlby/hub/service" +) + +func TestGetCustomNodeCommandDefinitions(t *testing.T) { + lnClient := mocks.NewLNClient(t) + svc := mocks.NewService(t) + + mockLNCommandDefs := []lnclient.CustomNodeCommandDef{ + { + Name: "no_args", + Description: "command without args", + Args: nil, + }, + { + Name: "with_args", + Description: "command with args", + Args: []lnclient.CustomNodeCommandArgDef{ + {Name: "arg1", Description: "first argument"}, + {Name: "arg2", Description: "second argument"}, + }, + }, + } + + expectedCommands := []CustomNodeCommandDef{ + { + Name: "no_args", + Description: "command without args", + Args: []CustomNodeCommandArgDef{}, + }, + { + Name: "with_args", + Description: "command with args", + Args: []CustomNodeCommandArgDef{ + {Name: "arg1", Description: "first argument"}, + {Name: "arg2", Description: "second argument"}, + }, + }, + } + + lnClient.On("GetCustomNodeCommandDefinitions").Return(mockLNCommandDefs) + svc.On("GetLNClient").Return(lnClient) + + theAPI := instantiateAPIWithService(svc) + + commands, err := theAPI.GetCustomNodeCommands() + require.NoError(t, err) + require.NotNil(t, commands) + require.ElementsMatch(t, expectedCommands, commands.Commands) +} + +func TestExecuteCustomNodeCommand(t *testing.T) { + type testCase struct { + name string + apiCommandLine string + lnSupportedCommands []lnclient.CustomNodeCommandDef + lnExpectedCommandReq *lnclient.CustomNodeCommandRequest + lnResponse *lnclient.CustomNodeCommandResponse + lnError error + apiExpectedResponse interface{} + apiExpectedErr string + } + + // Successful execution of a command without args. + testCaseOkNoArgs := testCase{ + name: "command without args", + apiCommandLine: "test_command", + lnSupportedCommands: []lnclient.CustomNodeCommandDef{{Name: "test_command"}}, + lnExpectedCommandReq: &lnclient.CustomNodeCommandRequest{Name: "test_command", Args: []lnclient.CustomNodeCommandArg{}}, + lnResponse: &lnclient.CustomNodeCommandResponse{Response: "ok"}, + lnError: nil, + apiExpectedResponse: "ok", + apiExpectedErr: "", + } + + // Successful execution of a command with args. The command line contains + // different arg value styles: with '=' and with space. + testCaseOkWithArgs := testCase{ + name: "command with args", + apiCommandLine: "test_command --arg1=foo --arg2 bar", + lnSupportedCommands: []lnclient.CustomNodeCommandDef{ + { + Name: "test_command", + Args: []lnclient.CustomNodeCommandArgDef{ + {Name: "arg1", Description: "argument one"}, + {Name: "arg2", Description: "argument two"}, + }, + }, + }, + lnExpectedCommandReq: &lnclient.CustomNodeCommandRequest{Name: "test_command", Args: []lnclient.CustomNodeCommandArg{ + {Name: "arg1", Value: "foo"}, + {Name: "arg2", Value: "bar"}, + }}, + lnResponse: &lnclient.CustomNodeCommandResponse{Response: "ok"}, + lnError: nil, + apiExpectedResponse: "ok", + apiExpectedErr: "", + } + + // Successful execution of a command with a possible but unset arg. + testCaseOkWithUnsetArg := testCase{ + name: "command with unset arg", + apiCommandLine: "test_command", + lnSupportedCommands: []lnclient.CustomNodeCommandDef{ + {Name: "test_command", Args: []lnclient.CustomNodeCommandArgDef{{Name: "arg1", Description: "argument one"}}}, + }, + lnExpectedCommandReq: &lnclient.CustomNodeCommandRequest{Name: "test_command", Args: []lnclient.CustomNodeCommandArg{}}, + lnResponse: &lnclient.CustomNodeCommandResponse{Response: "ok"}, + lnError: nil, + apiExpectedResponse: "ok", + apiExpectedErr: "", + } + + // Error: command line is empty. + testCaseErrEmptyCommand := testCase{ + name: "empty command", + apiCommandLine: "", + lnSupportedCommands: nil, + lnExpectedCommandReq: nil, + lnResponse: nil, + lnError: nil, + apiExpectedResponse: nil, + apiExpectedErr: "no command provided", + } + + // Error: command line is malformed, i.e. non-parseable. + testCaseErrMalformedCommand := testCase{ + name: "command with unclosed quote", + apiCommandLine: "test_command\"", + lnSupportedCommands: nil, + lnExpectedCommandReq: nil, + lnResponse: nil, + lnError: nil, + apiExpectedResponse: nil, + apiExpectedErr: "failed to parse node command", + } + + // Error: node does not support this command. + testCaseErrUnknownCommand := testCase{ + name: "unknown command", + apiCommandLine: "test_command_unknown", + lnSupportedCommands: []lnclient.CustomNodeCommandDef{{Name: "test_command"}}, + lnExpectedCommandReq: nil, + lnResponse: nil, + lnError: nil, + apiExpectedResponse: nil, + apiExpectedErr: "unknown command", + } + + // Error: the command is valid but the node fails to execute it. + testCaseErrNodeFailed := testCase{ + name: "node failed to execute command", + apiCommandLine: "test_command", + lnSupportedCommands: []lnclient.CustomNodeCommandDef{{Name: "test_command"}}, + lnExpectedCommandReq: &lnclient.CustomNodeCommandRequest{Name: "test_command", Args: []lnclient.CustomNodeCommandArg{}}, + lnResponse: nil, + lnError: fmt.Errorf("utter failure"), + apiExpectedResponse: nil, + apiExpectedErr: "utter failure", + } + + testCases := []testCase{ + testCaseOkNoArgs, + testCaseOkWithArgs, + testCaseOkWithUnsetArg, + testCaseErrEmptyCommand, + testCaseErrMalformedCommand, + testCaseErrUnknownCommand, + testCaseErrNodeFailed, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + lnClient := mocks.NewLNClient(t) + svc := mocks.NewService(t) + + if tc.lnSupportedCommands != nil { + lnClient.On("GetCustomNodeCommandDefinitions").Return(tc.lnSupportedCommands) + } + + if tc.lnExpectedCommandReq != nil { + lnClient.On("ExecuteCustomNodeCommand", mock.Anything, tc.lnExpectedCommandReq).Return(tc.lnResponse, tc.lnError) + } + + svc.On("GetLNClient").Return(lnClient) + + theAPI := instantiateAPIWithService(svc) + + response, err := theAPI.ExecuteCustomNodeCommand(context.TODO(), tc.apiCommandLine) + require.Equal(t, tc.apiExpectedResponse, response) + if tc.apiExpectedErr == "" { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, tc.apiExpectedErr) + } + }) + } +} + +// instantiateAPIWithService is a helper function that returns a partially +// constructed API instance. It is only suitable for the simplest of test cases. +func instantiateAPIWithService(s service.Service) *api { + return &api{svc: s} +} diff --git a/api/mocks/LNClient.go b/api/mocks/LNClient.go new file mode 100644 index 00000000..da8d59a0 --- /dev/null +++ b/api/mocks/LNClient.go @@ -0,0 +1,860 @@ +// Code generated by mockery v2.51.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + lnclient "github.com/getAlby/hub/lnclient" + mock "github.com/stretchr/testify/mock" +) + +// LNClient is an autogenerated mock type for the LNClient type +type LNClient struct { + mock.Mock +} + +// CloseChannel provides a mock function with given fields: ctx, closeChannelRequest +func (_m *LNClient) CloseChannel(ctx context.Context, closeChannelRequest *lnclient.CloseChannelRequest) (*lnclient.CloseChannelResponse, error) { + ret := _m.Called(ctx, closeChannelRequest) + + if len(ret) == 0 { + panic("no return value specified for CloseChannel") + } + + var r0 *lnclient.CloseChannelResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *lnclient.CloseChannelRequest) (*lnclient.CloseChannelResponse, error)); ok { + return rf(ctx, closeChannelRequest) + } + if rf, ok := ret.Get(0).(func(context.Context, *lnclient.CloseChannelRequest) *lnclient.CloseChannelResponse); ok { + r0 = rf(ctx, closeChannelRequest) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.CloseChannelResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *lnclient.CloseChannelRequest) error); ok { + r1 = rf(ctx, closeChannelRequest) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ConnectPeer provides a mock function with given fields: ctx, connectPeerRequest +func (_m *LNClient) ConnectPeer(ctx context.Context, connectPeerRequest *lnclient.ConnectPeerRequest) error { + ret := _m.Called(ctx, connectPeerRequest) + + if len(ret) == 0 { + panic("no return value specified for ConnectPeer") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *lnclient.ConnectPeerRequest) error); ok { + r0 = rf(ctx, connectPeerRequest) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DisconnectPeer provides a mock function with given fields: ctx, peerId +func (_m *LNClient) DisconnectPeer(ctx context.Context, peerId string) error { + ret := _m.Called(ctx, peerId) + + if len(ret) == 0 { + panic("no return value specified for DisconnectPeer") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, peerId) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ExecuteCustomNodeCommand provides a mock function with given fields: ctx, command +func (_m *LNClient) ExecuteCustomNodeCommand(ctx context.Context, command *lnclient.CustomNodeCommandRequest) (*lnclient.CustomNodeCommandResponse, error) { + ret := _m.Called(ctx, command) + + if len(ret) == 0 { + panic("no return value specified for ExecuteCustomNodeCommand") + } + + var r0 *lnclient.CustomNodeCommandResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *lnclient.CustomNodeCommandRequest) (*lnclient.CustomNodeCommandResponse, error)); ok { + return rf(ctx, command) + } + if rf, ok := ret.Get(0).(func(context.Context, *lnclient.CustomNodeCommandRequest) *lnclient.CustomNodeCommandResponse); ok { + r0 = rf(ctx, command) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.CustomNodeCommandResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *lnclient.CustomNodeCommandRequest) error); ok { + r1 = rf(ctx, command) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBalances provides a mock function with given fields: ctx +func (_m *LNClient) GetBalances(ctx context.Context) (*lnclient.BalancesResponse, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetBalances") + } + + var r0 *lnclient.BalancesResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*lnclient.BalancesResponse, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *lnclient.BalancesResponse); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.BalancesResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCustomNodeCommandDefinitions provides a mock function with no fields +func (_m *LNClient) GetCustomNodeCommandDefinitions() []lnclient.CustomNodeCommandDef { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetCustomNodeCommandDefinitions") + } + + var r0 []lnclient.CustomNodeCommandDef + if rf, ok := ret.Get(0).(func() []lnclient.CustomNodeCommandDef); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]lnclient.CustomNodeCommandDef) + } + } + + return r0 +} + +// GetInfo provides a mock function with given fields: ctx +func (_m *LNClient) GetInfo(ctx context.Context) (*lnclient.NodeInfo, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetInfo") + } + + var r0 *lnclient.NodeInfo + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*lnclient.NodeInfo, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *lnclient.NodeInfo); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.NodeInfo) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetLogOutput provides a mock function with given fields: ctx, maxLen +func (_m *LNClient) GetLogOutput(ctx context.Context, maxLen int) ([]byte, error) { + ret := _m.Called(ctx, maxLen) + + if len(ret) == 0 { + panic("no return value specified for GetLogOutput") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int) ([]byte, error)); ok { + return rf(ctx, maxLen) + } + if rf, ok := ret.Get(0).(func(context.Context, int) []byte); ok { + r0 = rf(ctx, maxLen) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int) error); ok { + r1 = rf(ctx, maxLen) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetNetworkGraph provides a mock function with given fields: ctx, nodeIds +func (_m *LNClient) GetNetworkGraph(ctx context.Context, nodeIds []string) (interface{}, error) { + ret := _m.Called(ctx, nodeIds) + + if len(ret) == 0 { + panic("no return value specified for GetNetworkGraph") + } + + var r0 interface{} + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []string) (interface{}, error)); ok { + return rf(ctx, nodeIds) + } + if rf, ok := ret.Get(0).(func(context.Context, []string) interface{}); ok { + r0 = rf(ctx, nodeIds) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(interface{}) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []string) error); ok { + r1 = rf(ctx, nodeIds) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetNewOnchainAddress provides a mock function with given fields: ctx +func (_m *LNClient) GetNewOnchainAddress(ctx context.Context) (string, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetNewOnchainAddress") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (string, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) string); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetNodeConnectionInfo provides a mock function with given fields: ctx +func (_m *LNClient) GetNodeConnectionInfo(ctx context.Context) (*lnclient.NodeConnectionInfo, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetNodeConnectionInfo") + } + + var r0 *lnclient.NodeConnectionInfo + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*lnclient.NodeConnectionInfo, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *lnclient.NodeConnectionInfo); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.NodeConnectionInfo) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetNodeStatus provides a mock function with given fields: ctx +func (_m *LNClient) GetNodeStatus(ctx context.Context) (*lnclient.NodeStatus, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetNodeStatus") + } + + var r0 *lnclient.NodeStatus + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*lnclient.NodeStatus, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *lnclient.NodeStatus); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.NodeStatus) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetOnchainBalance provides a mock function with given fields: ctx +func (_m *LNClient) GetOnchainBalance(ctx context.Context) (*lnclient.OnchainBalanceResponse, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetOnchainBalance") + } + + var r0 *lnclient.OnchainBalanceResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*lnclient.OnchainBalanceResponse, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *lnclient.OnchainBalanceResponse); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.OnchainBalanceResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPubkey provides a mock function with no fields +func (_m *LNClient) GetPubkey() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetPubkey") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// GetStorageDir provides a mock function with no fields +func (_m *LNClient) GetStorageDir() (string, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetStorageDir") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func() (string, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetSupportedNIP47Methods provides a mock function with no fields +func (_m *LNClient) GetSupportedNIP47Methods() []string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetSupportedNIP47Methods") + } + + var r0 []string + if rf, ok := ret.Get(0).(func() []string); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + return r0 +} + +// GetSupportedNIP47NotificationTypes provides a mock function with no fields +func (_m *LNClient) GetSupportedNIP47NotificationTypes() []string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetSupportedNIP47NotificationTypes") + } + + var r0 []string + if rf, ok := ret.Get(0).(func() []string); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + return r0 +} + +// ListChannels provides a mock function with given fields: ctx +func (_m *LNClient) ListChannels(ctx context.Context) ([]lnclient.Channel, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListChannels") + } + + var r0 []lnclient.Channel + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]lnclient.Channel, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []lnclient.Channel); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]lnclient.Channel) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListPeers provides a mock function with given fields: ctx +func (_m *LNClient) ListPeers(ctx context.Context) ([]lnclient.PeerDetails, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListPeers") + } + + var r0 []lnclient.PeerDetails + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]lnclient.PeerDetails, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []lnclient.PeerDetails); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]lnclient.PeerDetails) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListTransactions provides a mock function with given fields: ctx, from, until, limit, offset, unpaid, invoiceType +func (_m *LNClient) ListTransactions(ctx context.Context, from uint64, until uint64, limit uint64, offset uint64, unpaid bool, invoiceType string) ([]lnclient.Transaction, error) { + ret := _m.Called(ctx, from, until, limit, offset, unpaid, invoiceType) + + if len(ret) == 0 { + panic("no return value specified for ListTransactions") + } + + var r0 []lnclient.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, uint64, uint64, bool, string) ([]lnclient.Transaction, error)); ok { + return rf(ctx, from, until, limit, offset, unpaid, invoiceType) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, uint64, uint64, bool, string) []lnclient.Transaction); ok { + r0 = rf(ctx, from, until, limit, offset, unpaid, invoiceType) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]lnclient.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, uint64, uint64, uint64, bool, string) error); ok { + r1 = rf(ctx, from, until, limit, offset, unpaid, invoiceType) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LookupInvoice provides a mock function with given fields: ctx, paymentHash +func (_m *LNClient) LookupInvoice(ctx context.Context, paymentHash string) (*lnclient.Transaction, error) { + ret := _m.Called(ctx, paymentHash) + + if len(ret) == 0 { + panic("no return value specified for LookupInvoice") + } + + var r0 *lnclient.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*lnclient.Transaction, error)); ok { + return rf(ctx, paymentHash) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *lnclient.Transaction); ok { + r0 = rf(ctx, paymentHash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, paymentHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MakeInvoice provides a mock function with given fields: ctx, amount, description, descriptionHash, expiry +func (_m *LNClient) MakeInvoice(ctx context.Context, amount int64, description string, descriptionHash string, expiry int64) (*lnclient.Transaction, error) { + ret := _m.Called(ctx, amount, description, descriptionHash, expiry) + + if len(ret) == 0 { + panic("no return value specified for MakeInvoice") + } + + var r0 *lnclient.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, int64) (*lnclient.Transaction, error)); ok { + return rf(ctx, amount, description, descriptionHash, expiry) + } + if rf, ok := ret.Get(0).(func(context.Context, int64, string, string, int64) *lnclient.Transaction); ok { + r0 = rf(ctx, amount, description, descriptionHash, expiry) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int64, string, string, int64) error); ok { + r1 = rf(ctx, amount, description, descriptionHash, expiry) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OpenChannel provides a mock function with given fields: ctx, openChannelRequest +func (_m *LNClient) OpenChannel(ctx context.Context, openChannelRequest *lnclient.OpenChannelRequest) (*lnclient.OpenChannelResponse, error) { + ret := _m.Called(ctx, openChannelRequest) + + if len(ret) == 0 { + panic("no return value specified for OpenChannel") + } + + var r0 *lnclient.OpenChannelResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *lnclient.OpenChannelRequest) (*lnclient.OpenChannelResponse, error)); ok { + return rf(ctx, openChannelRequest) + } + if rf, ok := ret.Get(0).(func(context.Context, *lnclient.OpenChannelRequest) *lnclient.OpenChannelResponse); ok { + r0 = rf(ctx, openChannelRequest) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.OpenChannelResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *lnclient.OpenChannelRequest) error); ok { + r1 = rf(ctx, openChannelRequest) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RedeemOnchainFunds provides a mock function with given fields: ctx, toAddress, amount, sendAll +func (_m *LNClient) RedeemOnchainFunds(ctx context.Context, toAddress string, amount uint64, sendAll bool) (string, error) { + ret := _m.Called(ctx, toAddress, amount, sendAll) + + if len(ret) == 0 { + panic("no return value specified for RedeemOnchainFunds") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, uint64, bool) (string, error)); ok { + return rf(ctx, toAddress, amount, sendAll) + } + if rf, ok := ret.Get(0).(func(context.Context, string, uint64, bool) string); ok { + r0 = rf(ctx, toAddress, amount, sendAll) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context, string, uint64, bool) error); ok { + r1 = rf(ctx, toAddress, amount, sendAll) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ResetRouter provides a mock function with given fields: key +func (_m *LNClient) ResetRouter(key string) error { + ret := _m.Called(key) + + if len(ret) == 0 { + panic("no return value specified for ResetRouter") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(key) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SendKeysend provides a mock function with given fields: ctx, amount, destination, customRecords, preimage +func (_m *LNClient) SendKeysend(ctx context.Context, amount uint64, destination string, customRecords []lnclient.TLVRecord, preimage string) (*lnclient.PayKeysendResponse, error) { + ret := _m.Called(ctx, amount, destination, customRecords, preimage) + + if len(ret) == 0 { + panic("no return value specified for SendKeysend") + } + + var r0 *lnclient.PayKeysendResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, string, []lnclient.TLVRecord, string) (*lnclient.PayKeysendResponse, error)); ok { + return rf(ctx, amount, destination, customRecords, preimage) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, string, []lnclient.TLVRecord, string) *lnclient.PayKeysendResponse); ok { + r0 = rf(ctx, amount, destination, customRecords, preimage) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.PayKeysendResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, string, []lnclient.TLVRecord, string) error); ok { + r1 = rf(ctx, amount, destination, customRecords, preimage) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SendPaymentProbes provides a mock function with given fields: ctx, invoice +func (_m *LNClient) SendPaymentProbes(ctx context.Context, invoice string) error { + ret := _m.Called(ctx, invoice) + + if len(ret) == 0 { + panic("no return value specified for SendPaymentProbes") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, invoice) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SendPaymentSync provides a mock function with given fields: ctx, payReq, amount +func (_m *LNClient) SendPaymentSync(ctx context.Context, payReq string, amount *uint64) (*lnclient.PayInvoiceResponse, error) { + ret := _m.Called(ctx, payReq, amount) + + if len(ret) == 0 { + panic("no return value specified for SendPaymentSync") + } + + var r0 *lnclient.PayInvoiceResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, *uint64) (*lnclient.PayInvoiceResponse, error)); ok { + return rf(ctx, payReq, amount) + } + if rf, ok := ret.Get(0).(func(context.Context, string, *uint64) *lnclient.PayInvoiceResponse); ok { + r0 = rf(ctx, payReq, amount) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*lnclient.PayInvoiceResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, *uint64) error); ok { + r1 = rf(ctx, payReq, amount) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SendSpontaneousPaymentProbes provides a mock function with given fields: ctx, amountMsat, nodeId +func (_m *LNClient) SendSpontaneousPaymentProbes(ctx context.Context, amountMsat uint64, nodeId string) error { + ret := _m.Called(ctx, amountMsat, nodeId) + + if len(ret) == 0 { + panic("no return value specified for SendSpontaneousPaymentProbes") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, string) error); ok { + r0 = rf(ctx, amountMsat, nodeId) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Shutdown provides a mock function with no fields +func (_m *LNClient) Shutdown() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Shutdown") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SignMessage provides a mock function with given fields: ctx, message +func (_m *LNClient) SignMessage(ctx context.Context, message string) (string, error) { + ret := _m.Called(ctx, message) + + if len(ret) == 0 { + panic("no return value specified for SignMessage") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (string, error)); ok { + return rf(ctx, message) + } + if rf, ok := ret.Get(0).(func(context.Context, string) string); ok { + r0 = rf(ctx, message) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, message) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateChannel provides a mock function with given fields: ctx, updateChannelRequest +func (_m *LNClient) UpdateChannel(ctx context.Context, updateChannelRequest *lnclient.UpdateChannelRequest) error { + ret := _m.Called(ctx, updateChannelRequest) + + if len(ret) == 0 { + panic("no return value specified for UpdateChannel") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *lnclient.UpdateChannelRequest) error); ok { + r0 = rf(ctx, updateChannelRequest) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdateLastWalletSyncRequest provides a mock function with no fields +func (_m *LNClient) UpdateLastWalletSyncRequest() { + _m.Called() +} + +// NewLNClient creates a new instance of LNClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewLNClient(t interface { + mock.TestingT + Cleanup(func()) +}) *LNClient { + mock := &LNClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/api/mocks/Service.go b/api/mocks/Service.go new file mode 100644 index 00000000..9f295c65 --- /dev/null +++ b/api/mocks/Service.go @@ -0,0 +1,225 @@ +// Code generated by mockery v2.51.1. DO NOT EDIT. + +package mocks + +import ( + alby "github.com/getAlby/hub/alby" + config "github.com/getAlby/hub/config" + + events "github.com/getAlby/hub/events" + + gorm "gorm.io/gorm" + + keys "github.com/getAlby/hub/service/keys" + + lnclient "github.com/getAlby/hub/lnclient" + + mock "github.com/stretchr/testify/mock" + + transactions "github.com/getAlby/hub/transactions" +) + +// Service is an autogenerated mock type for the Service type +type Service struct { + mock.Mock +} + +// GetAlbyOAuthSvc provides a mock function with no fields +func (_m *Service) GetAlbyOAuthSvc() alby.AlbyOAuthService { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetAlbyOAuthSvc") + } + + var r0 alby.AlbyOAuthService + if rf, ok := ret.Get(0).(func() alby.AlbyOAuthService); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(alby.AlbyOAuthService) + } + } + + return r0 +} + +// GetConfig provides a mock function with no fields +func (_m *Service) GetConfig() config.Config { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetConfig") + } + + var r0 config.Config + if rf, ok := ret.Get(0).(func() config.Config); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(config.Config) + } + } + + return r0 +} + +// GetDB provides a mock function with no fields +func (_m *Service) GetDB() *gorm.DB { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetDB") + } + + var r0 *gorm.DB + if rf, ok := ret.Get(0).(func() *gorm.DB); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*gorm.DB) + } + } + + return r0 +} + +// GetEventPublisher provides a mock function with no fields +func (_m *Service) GetEventPublisher() events.EventPublisher { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetEventPublisher") + } + + var r0 events.EventPublisher + if rf, ok := ret.Get(0).(func() events.EventPublisher); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(events.EventPublisher) + } + } + + return r0 +} + +// GetKeys provides a mock function with no fields +func (_m *Service) GetKeys() keys.Keys { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetKeys") + } + + var r0 keys.Keys + if rf, ok := ret.Get(0).(func() keys.Keys); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(keys.Keys) + } + } + + return r0 +} + +// GetLNClient provides a mock function with no fields +func (_m *Service) GetLNClient() lnclient.LNClient { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetLNClient") + } + + var r0 lnclient.LNClient + if rf, ok := ret.Get(0).(func() lnclient.LNClient); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(lnclient.LNClient) + } + } + + return r0 +} + +// GetTransactionsService provides a mock function with no fields +func (_m *Service) GetTransactionsService() transactions.TransactionsService { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetTransactionsService") + } + + var r0 transactions.TransactionsService + if rf, ok := ret.Get(0).(func() transactions.TransactionsService); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(transactions.TransactionsService) + } + } + + return r0 +} + +// IsRelayReady provides a mock function with no fields +func (_m *Service) IsRelayReady() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IsRelayReady") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// Shutdown provides a mock function with no fields +func (_m *Service) Shutdown() { + _m.Called() +} + +// StartApp provides a mock function with given fields: encryptionKey +func (_m *Service) StartApp(encryptionKey string) error { + ret := _m.Called(encryptionKey) + + if len(ret) == 0 { + panic("no return value specified for StartApp") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(encryptionKey) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// StopApp provides a mock function with no fields +func (_m *Service) StopApp() { + _m.Called() +} + +// NewService creates a new instance of Service. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewService(t interface { + mock.TestingT + Cleanup(func()) +}) *Service { + mock := &Service{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +}