code.vegaprotocol.io/vega@v0.79.0/wallet/service/service_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package service_test 17 18 import ( 19 "context" 20 "io" 21 "net/http" 22 "net/http/httptest" 23 "strings" 24 "testing" 25 "time" 26 27 "code.vegaprotocol.io/vega/wallet/api/mocks" 28 apimocks "code.vegaprotocol.io/vega/wallet/api/mocks" 29 "code.vegaprotocol.io/vega/wallet/network" 30 "code.vegaprotocol.io/vega/wallet/service" 31 v1 "code.vegaprotocol.io/vega/wallet/service/v1" 32 v1mocks "code.vegaprotocol.io/vega/wallet/service/v1/mocks" 33 v2 "code.vegaprotocol.io/vega/wallet/service/v2" 34 "code.vegaprotocol.io/vega/wallet/service/v2/connections" 35 v2connectionsmocks "code.vegaprotocol.io/vega/wallet/service/v2/connections/mocks" 36 v2mocks "code.vegaprotocol.io/vega/wallet/service/v2/mocks" 37 "code.vegaprotocol.io/vega/wallet/wallet" 38 39 "github.com/golang/mock/gomock" 40 "go.uber.org/zap" 41 ) 42 43 type testService struct { 44 *service.Service 45 46 ctrl *gomock.Controller 47 handler *v1mocks.MockWalletHandler 48 nodeForward *v1mocks.MockNodeForward 49 consentRequestsCh chan v1.ConsentRequest 50 auth *v1mocks.MockAuth 51 52 clientAPI *v2mocks.MockClientAPI 53 54 spam *mocks.MockSpamHandler 55 timeService *v2connectionsmocks.MockTimeService 56 walletStore *v2connectionsmocks.MockWalletStore 57 tokenStore *v2connectionsmocks.MockTokenStore 58 sessionStore *v2connectionsmocks.MockSessionStore 59 interactor *apimocks.MockInteractor 60 } 61 62 func (s *testService) serveHTTP(t *testing.T, req *http.Request) (int, http.Header, []byte) { 63 t.Helper() 64 w := httptest.NewRecorder() 65 66 s.ServeHTTP(w, req) 67 68 resp := w.Result() //nolint:bodyclose 69 defer func() { 70 if err := w.Result().Body.Close(); err != nil { 71 t.Logf("couldn't close response body: %v", err) 72 } 73 }() 74 75 body, err := io.ReadAll(resp.Body) 76 if err != nil { 77 t.Fatalf("couldn't read body: %v", err) 78 } 79 80 return resp.StatusCode, resp.Header, body 81 } 82 83 func getTestServiceV1(t *testing.T, consentPolicy string) *testService { 84 t.Helper() 85 86 net := &network.Network{} 87 serviceCfg := service.DefaultConfig() 88 89 ctrl := gomock.NewController(t) 90 91 handler := v1mocks.NewMockWalletHandler(ctrl) 92 auth := v1mocks.NewMockAuth(ctrl) 93 nodeForward := v1mocks.NewMockNodeForward(ctrl) 94 spam := mocks.NewMockSpamHandler(ctrl) 95 96 consentRequestsCh := make(chan v1.ConsentRequest, 1) 97 sentTxs := make(chan v1.SentTransaction, 1) 98 99 ctx, cancelFn := context.WithCancel(context.Background()) 100 101 var policy v1.Policy 102 switch consentPolicy { 103 case "automatic": 104 policy = v1.NewAutomaticConsentPolicy() 105 case "manual": 106 policy = v1.NewExplicitConsentPolicy(ctx, consentRequestsCh, sentTxs) 107 default: 108 t.Fatalf("unknown consent policy: %s", consentPolicy) 109 } 110 111 apiV1 := v1.NewAPI(zap.NewNop(), handler, auth, nodeForward, policy, net, spam) 112 113 s := service.NewService(zap.NewNop(), serviceCfg, apiV1, nil) 114 115 t.Cleanup(func() { 116 if err := s.Stop(context.Background()); err != nil { 117 t.Log("The service couldn't stop properly") 118 } 119 cancelFn() 120 close(consentRequestsCh) 121 close(sentTxs) 122 }) 123 124 return &testService{ 125 Service: s, 126 ctrl: ctrl, 127 128 // V1 129 handler: handler, 130 auth: auth, 131 nodeForward: nodeForward, 132 consentRequestsCh: consentRequestsCh, 133 spam: spam, 134 } 135 } 136 137 type longLivingTokenSetupForTest struct { 138 tokenDescription connections.TokenDescription 139 wallet wallet.Wallet 140 } 141 142 func getTestServiceV2(t *testing.T, tokenSetups ...longLivingTokenSetupForTest) *testService { 143 t.Helper() 144 145 serviceCfg := service.DefaultConfig() 146 147 ctrl := gomock.NewController(t) 148 149 clientAPI := v2mocks.NewMockClientAPI(ctrl) 150 spam := mocks.NewMockSpamHandler(ctrl) 151 timeService := v2connectionsmocks.NewMockTimeService(ctrl) 152 walletStore := v2connectionsmocks.NewMockWalletStore(ctrl) 153 tokenStore := v2connectionsmocks.NewMockTokenStore(ctrl) 154 sessionStore := v2connectionsmocks.NewMockSessionStore(ctrl) 155 interactor := apimocks.NewMockInteractor(ctrl) 156 157 if len(tokenSetups) > 0 { 158 tokenSummaries := make([]connections.TokenSummary, 0, len(tokenSetups)) 159 for _, tokenSetup := range tokenSetups { 160 tokenSummaries = append(tokenSummaries, connections.TokenSummary{ 161 Description: tokenSetup.tokenDescription.Description, 162 Token: tokenSetup.tokenDescription.Token, 163 CreationDate: tokenSetup.tokenDescription.CreationDate, 164 ExpirationDate: tokenSetup.tokenDescription.ExpirationDate, 165 }) 166 tokenStore.EXPECT().DescribeToken(tokenSetup.tokenDescription.Token).AnyTimes().Return(tokenSetup.tokenDescription, nil) 167 walletStore.EXPECT().UnlockWallet(gomock.Any(), tokenSetup.tokenDescription.Wallet.Name, tokenSetup.tokenDescription.Wallet.Passphrase).Times(1).Return(nil) 168 walletStore.EXPECT().GetWallet(gomock.Any(), tokenSetup.tokenDescription.Wallet.Name).Times(1).Return(tokenSetup.wallet, nil) 169 } 170 tokenStore.EXPECT().ListTokens().AnyTimes().Return(tokenSummaries, nil) 171 } else { 172 tokenStore.EXPECT().ListTokens().Times(1).Return(nil, nil) 173 } 174 175 sessionStore.EXPECT().ListSessions(gomock.Any()).Times(1).Return(nil, nil) 176 timeService.EXPECT().Now().AnyTimes().Return(time.Now()) 177 walletStore.EXPECT().OnUpdate(gomock.Any()).Times(1) 178 tokenStore.EXPECT().OnUpdate(gomock.Any()).Times(1) 179 180 connectionsManager, err := connections.NewManager(timeService, walletStore, tokenStore, sessionStore, interactor) 181 if err != nil { 182 t.Fatalf("could not instantiate the connection manager for tests: %v", err) 183 } 184 185 apiV2 := v2.NewAPI(zap.NewNop(), clientAPI, connectionsManager) 186 187 s := service.NewService(zap.NewNop(), serviceCfg, nil, apiV2) 188 189 t.Cleanup(func() { 190 if err := s.Stop(context.Background()); err != nil { 191 t.Log("The service couldn't stop properly") 192 } 193 connectionsManager.EndAllSessionConnections() 194 }) 195 196 return &testService{ 197 Service: s, 198 ctrl: ctrl, 199 200 clientAPI: clientAPI, 201 timeService: timeService, 202 walletStore: walletStore, 203 tokenStore: tokenStore, 204 sessionStore: sessionStore, 205 interactor: interactor, 206 spam: spam, 207 } 208 } 209 210 func buildRequest(t *testing.T, method, path, payload string, headers map[string]string) *http.Request { 211 t.Helper() 212 213 ctx, cancelFn := context.WithTimeout(context.Background(), testRequestTimeout) 214 t.Cleanup(func() { 215 cancelFn() 216 }) 217 218 req, _ := http.NewRequestWithContext(ctx, method, path, strings.NewReader(payload)) 219 for k, v := range headers { 220 req.Header.Set(k, v) 221 } 222 return req 223 }