github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/protocol/mediator/service_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package mediator
     8  
     9  import (
    10  	"encoding/json"
    11  	"errors"
    12  	"fmt"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/google/uuid"
    17  	"github.com/stretchr/testify/require"
    18  
    19  	"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
    20  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
    21  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
    22  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/messagepickup"
    23  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
    24  	"github.com/hyperledger/aries-framework-go/pkg/doc/did"
    25  	vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
    26  	mockdispatcher "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/dispatcher"
    27  	mockmessagep "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/messagepickup"
    28  	mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/mock/diddoc"
    29  	mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
    30  	mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider"
    31  	mockstore "github.com/hyperledger/aries-framework-go/pkg/mock/storage"
    32  	mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr"
    33  	"github.com/hyperledger/aries-framework-go/pkg/store/connection"
    34  	"github.com/hyperledger/aries-framework-go/spi/storage"
    35  )
    36  
    37  const (
    38  	MYDID    = "myDID"
    39  	THEIRDID = "theirDID"
    40  	ENDPOINT = "http://router.example.com"
    41  )
    42  
    43  type updateResult struct {
    44  	action string
    45  	result string
    46  }
    47  
    48  func TestServiceNew(t *testing.T) {
    49  	t.Run("test new service - success", func(t *testing.T) {
    50  		svc, err := New(&mockprovider.Provider{
    51  			ServiceMap: map[string]interface{}{
    52  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
    53  			},
    54  			StorageProviderValue:              mem.NewProvider(),
    55  			ProtocolStateStorageProviderValue: mem.NewProvider(),
    56  		})
    57  		require.NoError(t, err)
    58  		require.Equal(t, Coordination, svc.Name())
    59  	})
    60  
    61  	t.Run("test new service name - failure", func(t *testing.T) {
    62  		svc, err := New(&mockprovider.Provider{
    63  			StorageProviderValue: &mockstore.MockStoreProvider{
    64  				ErrOpenStoreHandle: fmt.Errorf("error opening the store"),
    65  			},
    66  		})
    67  		require.Error(t, err)
    68  		require.Contains(t, err.Error(), "open route coordination store")
    69  		require.Nil(t, svc)
    70  	})
    71  }
    72  
    73  func TestService_Initialize(t *testing.T) {
    74  	t.Run("Success", func(t *testing.T) {
    75  		prov := &mockprovider.Provider{
    76  			ServiceMap: map[string]interface{}{
    77  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
    78  			},
    79  			StorageProviderValue:              mem.NewProvider(),
    80  			ProtocolStateStorageProviderValue: mem.NewProvider(),
    81  		}
    82  		svc := Service{}
    83  
    84  		err := svc.Initialize(prov)
    85  		require.NoError(t, err)
    86  
    87  		// second init is no-op
    88  		err = svc.Initialize(prov)
    89  		require.NoError(t, err)
    90  	})
    91  
    92  	t.Run("failure, not given a valid provider", func(t *testing.T) {
    93  		svc := Service{}
    94  
    95  		err := svc.Initialize("not a provider")
    96  		require.Error(t, err)
    97  		require.Contains(t, err.Error(), "expected provider of type")
    98  	})
    99  }
   100  
   101  func TestServiceAccept(t *testing.T) {
   102  	s := &Service{}
   103  
   104  	require.Equal(t, true, s.Accept(RequestMsgType))
   105  	require.Equal(t, true, s.Accept(GrantMsgType))
   106  	require.Equal(t, true, s.Accept(KeylistUpdateMsgType))
   107  	require.Equal(t, true, s.Accept(KeylistUpdateResponseMsgType))
   108  	require.Equal(t, true, s.Accept(service.ForwardMsgType))
   109  	require.Equal(t, false, s.Accept("unsupported msg type"))
   110  }
   111  
   112  func TestServiceHandleInbound(t *testing.T) {
   113  	t.Run("test handle inbound ", func(t *testing.T) {
   114  		svc, err := New(&mockprovider.Provider{
   115  			ServiceMap: map[string]interface{}{
   116  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   117  			},
   118  			StorageProviderValue:              mem.NewProvider(),
   119  			ProtocolStateStorageProviderValue: mem.NewProvider(),
   120  		})
   121  		require.NoError(t, err)
   122  
   123  		msgID := randomID()
   124  
   125  		id, err := svc.HandleInbound(&service.DIDCommMsgMap{"@id": msgID}, service.EmptyDIDCommContext())
   126  		require.NoError(t, err)
   127  		require.Equal(t, msgID, id)
   128  	})
   129  }
   130  
   131  func TestServiceHandleOutbound(t *testing.T) {
   132  	t.Run("outbound route-request", func(t *testing.T) {
   133  		msgID := make(chan string)
   134  
   135  		provider := &mockprovider.Provider{
   136  			ServiceMap: map[string]interface{}{
   137  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   138  			},
   139  			StorageProviderValue:              mem.NewProvider(),
   140  			ProtocolStateStorageProviderValue: mem.NewProvider(),
   141  			KMSValue:                          &mockkms.KeyManager{},
   142  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
   143  				ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error {
   144  					require.Equal(t, myDID, MYDID)
   145  					require.Equal(t, theirDID, THEIRDID)
   146  
   147  					reqMsgMap, ok := msg.(service.DIDCommMsgMap)
   148  					require.True(t, ok)
   149  
   150  					request := &Request{}
   151  
   152  					err := reqMsgMap.Decode(request)
   153  					require.NoError(t, err)
   154  
   155  					msgID <- request.ID
   156  					return nil
   157  				},
   158  			},
   159  		}
   160  		connRec := &connection.Record{
   161  			ConnectionID: "conn", MyDID: MYDID, TheirDID: THEIRDID, State: "completed",
   162  		}
   163  
   164  		r, err := connection.NewRecorder(provider)
   165  		require.NoError(t, err)
   166  		err = r.SaveConnectionRecord(connRec)
   167  		require.NoError(t, err)
   168  
   169  		svc, err := New(provider)
   170  		require.NoError(t, err)
   171  
   172  		go func() {
   173  			id := <-msgID
   174  			require.NoError(t, svc.saveGrant(generateGrantMsgPayload(t, id)))
   175  		}()
   176  	})
   177  
   178  	t.Run("rejects invalid msg types", func(t *testing.T) {
   179  		_, err := (&Service{}).HandleOutbound(service.NewDIDCommMsgMap(&Request{
   180  			Type: "invalid",
   181  		}), "myDID", "theirDID")
   182  		require.Error(t, err)
   183  	})
   184  
   185  	t.Run("rejects unsupported route protocol messages", func(t *testing.T) {
   186  		_, err := (&Service{}).HandleOutbound(service.NewDIDCommMsgMap(&Request{
   187  			Type: GrantMsgType,
   188  		}), "myDID", "theirDID")
   189  		require.Error(t, err)
   190  	})
   191  
   192  	t.Run("wraps error getting connection ID", func(t *testing.T) {
   193  		expected := errors.New("test")
   194  		s, err := New(&mockprovider.Provider{
   195  			ServiceMap: map[string]interface{}{
   196  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   197  			},
   198  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   199  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   200  		})
   201  		require.NoError(t, err)
   202  		s.connectionLookup = &connectionsStub{
   203  			getConnIDByDIDs: func(string, string) (string, error) {
   204  				return "", expected
   205  			},
   206  		}
   207  		_, err = s.HandleOutbound(service.NewDIDCommMsgMap(
   208  			&Request{Type: RequestMsgType}),
   209  			"myDID", "theirDID",
   210  		)
   211  		require.Error(t, err)
   212  		require.True(t, errors.Is(err, expected))
   213  	})
   214  
   215  	t.Run("wraps error getting connection record", func(t *testing.T) {
   216  		expected := errors.New("test")
   217  		s, err := New(&mockprovider.Provider{
   218  			ServiceMap: map[string]interface{}{
   219  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   220  			},
   221  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   222  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   223  		})
   224  		require.NoError(t, err)
   225  		s.connectionLookup = &connectionsStub{
   226  			getConnRecord: func(string) (*connection.Record, error) {
   227  				return nil, expected
   228  			},
   229  		}
   230  		_, err = s.HandleOutbound(service.NewDIDCommMsgMap(
   231  			&Request{Type: RequestMsgType}),
   232  			"myDID", "theirDID",
   233  		)
   234  		require.Error(t, err)
   235  		require.True(t, errors.Is(err, expected))
   236  	})
   237  }
   238  
   239  func TestServiceRequestMsg(t *testing.T) {
   240  	t.Run("test service handle inbound request msg - success", func(t *testing.T) {
   241  		svc, err := New(&mockprovider.Provider{
   242  			ServiceMap: map[string]interface{}{
   243  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   244  			},
   245  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   246  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   247  			KMSValue:                          &mockkms.KeyManager{},
   248  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   249  		})
   250  		require.NoError(t, err)
   251  
   252  		err = svc.RegisterActionEvent(make(chan service.DIDCommAction))
   253  		require.NoError(t, err)
   254  
   255  		msgID := randomID()
   256  
   257  		id, err := svc.HandleInbound(generateRequestMsgPayload(t, msgID), service.EmptyDIDCommContext())
   258  		require.NoError(t, err)
   259  		require.Equal(t, msgID, id)
   260  	})
   261  
   262  	t.Run("test service handle request msg - success", func(t *testing.T) {
   263  		svc, err := New(&mockprovider.Provider{
   264  			ServiceMap: map[string]interface{}{
   265  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   266  			},
   267  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   268  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   269  			KMSValue:                          &mockkms.KeyManager{},
   270  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   271  		})
   272  		require.NoError(t, err)
   273  
   274  		msg := &service.DIDCommMsgMap{"@id": map[int]int{}}
   275  
   276  		err = svc.handleInboundRequest(&callback{
   277  			msg:      msg,
   278  			myDID:    MYDID,
   279  			theirDID: THEIRDID,
   280  		})
   281  		require.Error(t, err)
   282  		require.Contains(t, err.Error(), "route request message unmarshal")
   283  	})
   284  
   285  	t.Run("test service handle request msg - verify outbound message", func(t *testing.T) {
   286  		endpoint := "ws://agent.example.com"
   287  		svc, err := New(&mockprovider.Provider{
   288  			ServiceMap: map[string]interface{}{
   289  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   290  			},
   291  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   292  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   293  			KMSValue:                          &mockkms.KeyManager{},
   294  			ServiceEndpointValue:              endpoint,
   295  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
   296  				ValidateSend: func(msg interface{}, senderVerKey string, des *service.Destination) error {
   297  					res, err := json.Marshal(msg)
   298  					require.NoError(t, err)
   299  
   300  					grant := &Grant{}
   301  					err = json.Unmarshal(res, grant)
   302  					require.NoError(t, err)
   303  
   304  					require.Equal(t, endpoint, grant.Endpoint)
   305  					require.Equal(t, 1, len(grant.RoutingKeys))
   306  
   307  					return nil
   308  				},
   309  			},
   310  			MediaTypeProfilesValue: []string{transport.MediaTypeAIP2RFC0019Profile},
   311  		})
   312  		require.NoError(t, err)
   313  
   314  		msgID := randomID()
   315  
   316  		err = svc.handleInboundRequest(&callback{
   317  			msg:      generateRequestMsgPayload(t, msgID),
   318  			myDID:    MYDID,
   319  			theirDID: THEIRDID,
   320  			options:  &Options{},
   321  		})
   322  		require.NoError(t, err)
   323  	})
   324  
   325  	t.Run("test service handle request msg - kms failure", func(t *testing.T) {
   326  		expected := errors.New("test")
   327  		svc, err := New(&mockprovider.Provider{
   328  			ServiceMap: map[string]interface{}{
   329  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   330  			},
   331  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   332  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   333  			KMSValue: &mockkms.KeyManager{
   334  				CrAndExportPubKeyErr: expected,
   335  			},
   336  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{},
   337  			MediaTypeProfilesValue:  []string{"value"},
   338  		})
   339  		require.NoError(t, err)
   340  
   341  		err = svc.handleInboundRequest(&callback{
   342  			msg:      service.NewDIDCommMsgMap(&Request{ID: "test", Type: RequestMsgType}),
   343  			myDID:    MYDID,
   344  			theirDID: THEIRDID,
   345  			options:  &Options{},
   346  		})
   347  		require.Error(t, err)
   348  		require.True(t, errors.Is(err, expected))
   349  	})
   350  }
   351  
   352  //nolint:gocyclo
   353  func TestEvents(t *testing.T) {
   354  	t.Run("HandleInbound dispatches action events", func(t *testing.T) {
   355  		svc, err := New(&mockprovider.Provider{
   356  			ServiceMap: map[string]interface{}{
   357  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   358  			},
   359  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   360  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   361  			KMSValue:                          &mockkms.KeyManager{},
   362  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   363  		})
   364  		require.NoError(t, err)
   365  
   366  		events := make(chan service.DIDCommAction)
   367  
   368  		err = svc.RegisterActionEvent(events)
   369  		require.NoError(t, err)
   370  
   371  		msgID := randomID()
   372  		msg := generateRequestMsgPayload(t, msgID)
   373  
   374  		id, err := svc.HandleInbound(msg, service.EmptyDIDCommContext())
   375  		require.NoError(t, err)
   376  		require.Equal(t, msgID, id)
   377  
   378  		select {
   379  		case e := <-events:
   380  			require.Equal(t, msg, e.Message)
   381  		case <-time.After(time.Second):
   382  			require.Fail(t, "timeout")
   383  		}
   384  	})
   385  
   386  	t.Run("continuing inbound request event dispatches outbound grant", func(t *testing.T) {
   387  		dispatched := make(chan struct{})
   388  		svc, err := New(&mockprovider.Provider{
   389  			ServiceMap: map[string]interface{}{
   390  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   391  			},
   392  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   393  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   394  			KMSValue:                          &mockkms.KeyManager{},
   395  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
   396  				ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error {
   397  					dispatched <- struct{}{}
   398  					return nil
   399  				},
   400  			},
   401  			MediaTypeProfilesValue: []string{transport.MediaTypeAIP2RFC0019Profile},
   402  		})
   403  		require.NoError(t, err)
   404  
   405  		events := make(chan service.DIDCommAction)
   406  
   407  		err = svc.RegisterActionEvent(events)
   408  		require.NoError(t, err)
   409  
   410  		_, err = svc.HandleInbound(generateRequestMsgPayload(t, "123"), service.EmptyDIDCommContext())
   411  		require.NoError(t, err)
   412  
   413  		select {
   414  		case e := <-events:
   415  			e.Continue(service.Empty{})
   416  		case <-time.After(time.Second):
   417  			require.Fail(t, "timeout")
   418  		}
   419  
   420  		select {
   421  		case <-dispatched:
   422  		case <-time.After(time.Second):
   423  			require.Fail(t, "timeout")
   424  		}
   425  	})
   426  
   427  	t.Run("stopping inbound request event does not dispatch outbound grant", func(t *testing.T) {
   428  		dispatched := make(chan struct{})
   429  		svc, err := New(&mockprovider.Provider{
   430  			ServiceMap: map[string]interface{}{
   431  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   432  			},
   433  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   434  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   435  			KMSValue:                          &mockkms.KeyManager{},
   436  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
   437  				ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error {
   438  					dispatched <- struct{}{}
   439  					return nil
   440  				},
   441  			},
   442  		})
   443  		require.NoError(t, err)
   444  
   445  		events := make(chan service.DIDCommAction)
   446  
   447  		err = svc.RegisterActionEvent(events)
   448  		require.NoError(t, err)
   449  
   450  		_, err = svc.HandleInbound(generateRequestMsgPayload(t, "123"), service.EmptyDIDCommContext())
   451  		require.NoError(t, err)
   452  
   453  		select {
   454  		case e := <-events:
   455  			e.Stop(errors.New("rejected"))
   456  		case <-time.After(time.Second):
   457  			require.Fail(t, "timeout")
   458  		}
   459  
   460  		select {
   461  		case <-dispatched:
   462  			require.Fail(t, "stopping the protocol flow should not result in an outbound message dispatch")
   463  		case <-time.After(time.Second):
   464  		}
   465  	})
   466  
   467  	t.Run("fails when no listeners are registered for action events", func(t *testing.T) {
   468  		svc, err := New(&mockprovider.Provider{
   469  			ServiceMap: map[string]interface{}{
   470  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   471  			},
   472  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   473  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   474  			KMSValue:                          &mockkms.KeyManager{},
   475  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   476  		})
   477  		require.NoError(t, err)
   478  
   479  		_, err = svc.HandleInbound(generateRequestMsgPayload(t, "123"), service.EmptyDIDCommContext())
   480  		require.Error(t, err)
   481  	})
   482  
   483  	t.Run("Continue assigns keys and endpoint provided by user", func(t *testing.T) {
   484  		endpoint := "ws://agent.example.com"
   485  		routingKeys := []string{"key1", "key2"}
   486  		dispatched := make(chan struct{})
   487  		svc, err := New(&mockprovider.Provider{
   488  			ServiceMap: map[string]interface{}{
   489  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   490  			},
   491  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   492  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   493  			KMSValue:                          &mockkms.KeyManager{},
   494  			ServiceEndpointValue:              "http://other.com",
   495  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
   496  				ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error {
   497  					res, err := json.Marshal(msg)
   498  					require.NoError(t, err)
   499  
   500  					grant := &Grant{}
   501  					err = json.Unmarshal(res, grant)
   502  					require.NoError(t, err)
   503  
   504  					require.Equal(t, endpoint, grant.Endpoint)
   505  					require.Equal(t, routingKeys, grant.RoutingKeys)
   506  
   507  					dispatched <- struct{}{}
   508  
   509  					return nil
   510  				},
   511  			},
   512  			MediaTypeProfilesValue: []string{transport.MediaTypeAIP2RFC0019Profile},
   513  		})
   514  		require.NoError(t, err)
   515  
   516  		events := make(chan service.DIDCommAction)
   517  		err = svc.RegisterActionEvent(events)
   518  		require.NoError(t, err)
   519  
   520  		t.Run("with Options as a struct type", func(t *testing.T) {
   521  			_, err = svc.HandleInbound(generateRequestMsgPayload(t, randomID()), service.NewDIDCommContext(MYDID, THEIRDID, nil))
   522  			require.NoError(t, err)
   523  
   524  			select {
   525  			case event := <-events:
   526  				event.Continue(Options{
   527  					ServiceEndpoint: endpoint,
   528  					RoutingKeys:     routingKeys,
   529  				})
   530  			case <-time.After(time.Second):
   531  				require.Fail(t, "timeout")
   532  			}
   533  
   534  			select {
   535  			case <-dispatched:
   536  			case <-time.After(time.Second):
   537  				require.Fail(t, "timeout")
   538  			}
   539  		})
   540  
   541  		t.Run("with Options as a pointer type", func(t *testing.T) {
   542  			_, err = svc.HandleInbound(generateRequestMsgPayload(t, randomID()), service.NewDIDCommContext(MYDID, THEIRDID, nil))
   543  			require.NoError(t, err)
   544  
   545  			select {
   546  			case event := <-events:
   547  				event.Continue(&Options{
   548  					ServiceEndpoint: endpoint,
   549  					RoutingKeys:     routingKeys,
   550  				})
   551  			case <-time.After(time.Second):
   552  				require.Fail(t, "timeout")
   553  			}
   554  
   555  			select {
   556  			case <-dispatched:
   557  			case <-time.After(time.Second):
   558  				require.Fail(t, "timeout")
   559  			}
   560  		})
   561  	})
   562  }
   563  
   564  func TestServiceGrantMsg(t *testing.T) {
   565  	t.Run("test service handle inbound grant msg - success", func(t *testing.T) {
   566  		svc, err := New(&mockprovider.Provider{
   567  			ServiceMap: map[string]interface{}{
   568  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   569  			},
   570  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   571  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   572  			KMSValue:                          &mockkms.KeyManager{},
   573  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   574  		})
   575  		require.NoError(t, err)
   576  
   577  		msgID := randomID()
   578  
   579  		id, err := svc.HandleInbound(generateGrantMsgPayload(t, msgID), service.EmptyDIDCommContext())
   580  		require.NoError(t, err)
   581  		require.Equal(t, msgID, id)
   582  	})
   583  
   584  	t.Run("service handle grant msg - marshal error", func(t *testing.T) {
   585  		svc, err := New(&mockprovider.Provider{
   586  			ServiceMap: map[string]interface{}{
   587  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   588  			},
   589  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   590  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   591  			KMSValue:                          &mockkms.KeyManager{},
   592  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   593  		})
   594  		require.NoError(t, err)
   595  
   596  		msg := &service.DIDCommMsgMap{"@id": make(chan int64)}
   597  
   598  		err = svc.saveGrant(msg)
   599  		require.Error(t, err)
   600  		require.Contains(t, err.Error(), "marshal grant: json")
   601  	})
   602  }
   603  
   604  func TestServiceUpdateKeyListMsg(t *testing.T) {
   605  	t.Run("test service handle inbound key list update msg - success", func(t *testing.T) {
   606  		svc, err := New(&mockprovider.Provider{
   607  			ServiceMap: map[string]interface{}{
   608  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   609  			},
   610  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   611  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   612  			KMSValue:                          &mockkms.KeyManager{},
   613  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   614  		})
   615  		require.NoError(t, err)
   616  
   617  		msgID := randomID()
   618  
   619  		id, err := svc.HandleInbound(generateKeyUpdateListMsgPayload(t, msgID, []Update{{
   620  			RecipientKey: "ABC",
   621  			Action:       "add",
   622  		}}), service.EmptyDIDCommContext())
   623  		require.NoError(t, err)
   624  		require.Equal(t, msgID, id)
   625  	})
   626  
   627  	t.Run("test service handle key list update msg - success", func(t *testing.T) {
   628  		svc, err := New(&mockprovider.Provider{
   629  			ServiceMap: map[string]interface{}{
   630  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   631  			},
   632  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   633  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   634  			KMSValue:                          &mockkms.KeyManager{},
   635  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   636  		})
   637  		require.NoError(t, err)
   638  
   639  		msg := &service.DIDCommMsgMap{"@id": map[int]int{}}
   640  
   641  		err = svc.handleKeylistUpdate(msg, MYDID, THEIRDID)
   642  		require.Error(t, err)
   643  		require.Contains(t, err.Error(), "route key list update message unmarshal")
   644  	})
   645  
   646  	t.Run("test service handle request msg - verify outbound message", func(t *testing.T) {
   647  		update := make(map[string]updateResult)
   648  		update["ABC"] = updateResult{action: add, result: success}
   649  		update["XYZ"] = updateResult{action: remove, result: serverError}
   650  		update[""] = updateResult{action: add, result: success}
   651  
   652  		svc, err := New(&mockprovider.Provider{
   653  			ServiceMap: map[string]interface{}{
   654  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   655  			},
   656  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   657  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   658  			KMSValue:                          &mockkms.KeyManager{},
   659  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
   660  				ValidateSend: func(msg interface{}, senderVerKey string, des *service.Destination) error {
   661  					res, err := json.Marshal(msg)
   662  					require.NoError(t, err)
   663  
   664  					updateRes := &KeylistUpdateResponse{}
   665  					err = json.Unmarshal(res, updateRes)
   666  					require.NoError(t, err)
   667  
   668  					require.Equal(t, len(update), len(updateRes.Updated))
   669  
   670  					for _, v := range updateRes.Updated {
   671  						require.Equal(t, update[v.RecipientKey].action, v.Action)
   672  						require.Equal(t, update[v.RecipientKey].result, v.Result)
   673  					}
   674  
   675  					return nil
   676  				},
   677  			},
   678  		})
   679  		require.NoError(t, err)
   680  
   681  		msgID := randomID()
   682  
   683  		var updates []Update
   684  		for k, v := range update {
   685  			updates = append(updates, Update{
   686  				RecipientKey: k,
   687  				Action:       v.action,
   688  			})
   689  		}
   690  
   691  		err = svc.handleKeylistUpdate(generateKeyUpdateListMsgPayload(t, msgID, updates), MYDID, THEIRDID)
   692  		require.NoError(t, err)
   693  	})
   694  }
   695  
   696  func TestServiceKeylistUpdateResponseMsg(t *testing.T) {
   697  	t.Run("test service handle inbound key list update response msg - success", func(t *testing.T) {
   698  		svc, err := New(&mockprovider.Provider{
   699  			ServiceMap: map[string]interface{}{
   700  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   701  			},
   702  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   703  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   704  			KMSValue:                          &mockkms.KeyManager{},
   705  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   706  		})
   707  		require.NoError(t, err)
   708  
   709  		msgID := randomID()
   710  
   711  		id, err := svc.HandleInbound(generateKeylistUpdateResponseMsgPayload(t, msgID, []UpdateResponse{{
   712  			RecipientKey: "ABC",
   713  			Action:       "add",
   714  			Result:       success,
   715  		}}), service.EmptyDIDCommContext())
   716  		require.NoError(t, err)
   717  		require.Equal(t, msgID, id)
   718  	})
   719  
   720  	t.Run("test service handle key list update response msg - success", func(t *testing.T) {
   721  		svc, err := New(&mockprovider.Provider{
   722  			ServiceMap: map[string]interface{}{
   723  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   724  			},
   725  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   726  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   727  			KMSValue:                          &mockkms.KeyManager{},
   728  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   729  		})
   730  		require.NoError(t, err)
   731  
   732  		msg := &service.DIDCommMsgMap{"@id": map[int]int{}}
   733  
   734  		err = svc.handleKeylistUpdateResponse(msg)
   735  		require.Error(t, err)
   736  		require.Contains(t, err.Error(), "route keylist update response message unmarshal")
   737  	})
   738  }
   739  
   740  func TestServiceForwardMsg(t *testing.T) {
   741  	t.Run("test service handle inbound forward msg - success", func(t *testing.T) {
   742  		to := randomID()
   743  		svc, err := New(&mockprovider.Provider{
   744  			ServiceMap: map[string]interface{}{
   745  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   746  			},
   747  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   748  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   749  			KMSValue:                          &mockkms.KeyManager{},
   750  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   751  		})
   752  		require.NoError(t, err)
   753  
   754  		err = svc.routeStore.Put(to, []byte("did:example:123"))
   755  		require.NoError(t, err)
   756  
   757  		msgID := randomID()
   758  
   759  		id, err := svc.HandleInbound(generateForwardMsgPayload(t, msgID, to, nil), service.EmptyDIDCommContext())
   760  		require.NoError(t, err)
   761  		require.Equal(t, msgID, id)
   762  	})
   763  
   764  	t.Run("test service handle forward msg - success", func(t *testing.T) {
   765  		svc, err := New(&mockprovider.Provider{
   766  			ServiceMap: map[string]interface{}{
   767  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   768  			},
   769  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   770  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   771  			KMSValue:                          &mockkms.KeyManager{},
   772  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   773  		})
   774  		require.NoError(t, err)
   775  
   776  		msg := &service.DIDCommMsgMap{"@id": map[int]int{}}
   777  
   778  		err = svc.handleForward(msg)
   779  		require.Error(t, err)
   780  		require.Contains(t, err.Error(), "forward message unmarshal")
   781  	})
   782  
   783  	t.Run("test service handle forward msg - route key fetch fail", func(t *testing.T) {
   784  		to := randomID()
   785  		msgID := randomID()
   786  
   787  		svc, err := New(&mockprovider.Provider{
   788  			ServiceMap: map[string]interface{}{
   789  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   790  			},
   791  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   792  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   793  			KMSValue:                          &mockkms.KeyManager{},
   794  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
   795  		})
   796  		require.NoError(t, err)
   797  
   798  		err = svc.handleForward(generateForwardMsgPayload(t, msgID, to, nil))
   799  		require.Error(t, err)
   800  		require.Contains(t, err.Error(), "route key fetch")
   801  	})
   802  
   803  	t.Run("test service handle forward msg - validate forward message content", func(t *testing.T) {
   804  		to := randomID()
   805  		msgID := randomID()
   806  		invalidDID := "did:error:123"
   807  
   808  		content := []byte(`{
   809  			Protected: "eyJ0eXAiOiJwcnMuaHlwZXJsZWRnZXIuYXJpZXMtYXV0aC1t" +
   810  				"ZXNzYWdlIiwiYWxnIjoiRUNESC1TUytYQzIwUEtXIiwiZW5jIjoiWEMyMFAifQ",
   811  			IV:         "JS2FxjEKdndnt-J7QX5pEnVwyBTu0_3d",
   812  			CipherText: "qQyzvajdvCDJbwxM",
   813  			Tag:        "2FqZMMQuNPYfL0JsSkj8LQ",
   814  		}`)
   815  
   816  		msg := generateForwardMsgPayload(t, msgID, to, content)
   817  
   818  		svc, err := New(&mockprovider.Provider{
   819  			ServiceMap: map[string]interface{}{
   820  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   821  			},
   822  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   823  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   824  			KMSValue:                          &mockkms.KeyManager{},
   825  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
   826  				ValidateForward: func(msg interface{}, des *service.Destination) error {
   827  					require.Equal(t, content, msg)
   828  
   829  					return nil
   830  				},
   831  			},
   832  			VDRegistryValue: &mockvdr.MockVDRegistry{
   833  				ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (doc *did.DocResolution, e error) {
   834  					if didID == invalidDID {
   835  						return nil, errors.New("invalid")
   836  					}
   837  					return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t, false)}, nil
   838  				},
   839  			},
   840  		})
   841  		require.NoError(t, err)
   842  
   843  		err = svc.routeStore.Put(dataKey(to), []byte("did:example:123"))
   844  		require.NoError(t, err)
   845  
   846  		err = svc.handleForward(msg)
   847  		require.NoError(t, err)
   848  
   849  		err = svc.routeStore.Put(dataKey(to), []byte(invalidDID))
   850  		require.NoError(t, err)
   851  
   852  		err = svc.handleForward(msg)
   853  		require.Error(t, err)
   854  		require.Contains(t, err.Error(), "get destination")
   855  	})
   856  }
   857  
   858  func TestMessagePickup(t *testing.T) {
   859  	t.Run("test service handle inbound message pick up - success", func(t *testing.T) {
   860  		to := randomID()
   861  
   862  		content := []byte(`{
   863  			Protected: "eyJ0eXAiOiJwcnMuaHlwZXJsZWRnZXIuYXJpZXMtYXV0aC1t" +
   864  				"ZXNzYWdlIiwiYWxnIjoiRUNESC1TUytYQzIwUEtXIiwiZW5jIjoiWEMyMFAifQ",
   865  			IV:         "JS2FxjEKdndnt-J7QX5pEnVwyBTu0_3d",
   866  			CipherText: "qQyzvajdvCDJbwxM",
   867  			Tag:        "2FqZMMQuNPYfL0JsSkj8LQ",
   868  		}`)
   869  
   870  		svc, err := New(
   871  			&mockprovider.Provider{
   872  				ServiceMap: map[string]interface{}{
   873  					messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{
   874  						AddMessageFunc: func(message []byte, theirDID string) error {
   875  							require.Equal(t, content, message)
   876  							return nil
   877  						},
   878  					},
   879  				},
   880  				StorageProviderValue:              mockstore.NewMockStoreProvider(),
   881  				ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   882  				KMSValue:                          &mockkms.KeyManager{},
   883  				OutboundDispatcherValue: &mockdispatcher.MockOutbound{
   884  					ValidateForward: func(_ interface{}, _ *service.Destination) error {
   885  						return errors.New("websocket connection failed")
   886  					},
   887  				},
   888  				VDRegistryValue: &mockvdr.MockVDRegistry{
   889  					ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
   890  						return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t, false)}, nil
   891  					},
   892  				},
   893  			})
   894  		require.NoError(t, err)
   895  
   896  		err = svc.routeStore.Put(dataKey(to), []byte("did:example:123"))
   897  		require.NoError(t, err)
   898  
   899  		msgID := randomID()
   900  		msg := generateForwardMsgPayload(t, msgID, to, content)
   901  
   902  		err = svc.handleForward(msg)
   903  		require.NoError(t, err)
   904  	})
   905  
   906  	t.Run("test service handle inbound message pick up - add message error", func(t *testing.T) {
   907  		to := randomID()
   908  
   909  		content := []byte(`{
   910  			Protected: "eyJ0eXAiOiJwcnMuaHlwZXJsZWRnZXIuYXJpZXMtYXV0aC1t" +
   911  				"ZXNzYWdlIiwiYWxnIjoiRUNESC1TUytYQzIwUEtXIiwiZW5jIjoiWEMyMFAifQ",
   912  			IV:         "JS2FxjEKdndnt-J7QX5pEnVwyBTu0_3d",
   913  			CipherText: "qQyzvajdvCDJbwxM",
   914  			Tag:        "2FqZMMQuNPYfL0JsSkj8LQ",
   915  		}`)
   916  
   917  		svc, err := New(&mockprovider.Provider{
   918  			ServiceMap: map[string]interface{}{
   919  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{
   920  					AddMessageErr: errors.New("add error"),
   921  				},
   922  			},
   923  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
   924  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   925  			KMSValue:                          &mockkms.KeyManager{},
   926  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
   927  				ValidateForward: func(_ interface{}, _ *service.Destination) error {
   928  					return errors.New("websocket connection failed")
   929  				},
   930  			},
   931  			VDRegistryValue: &mockvdr.MockVDRegistry{
   932  				ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (doc *did.DocResolution, e error) {
   933  					return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t, false)}, nil
   934  				},
   935  			},
   936  		})
   937  		require.NoError(t, err)
   938  
   939  		err = svc.routeStore.Put(dataKey(to), []byte("did:example:123"))
   940  		require.NoError(t, err)
   941  
   942  		msgID := randomID()
   943  		msg := generateForwardMsgPayload(t, msgID, to, content)
   944  
   945  		err = svc.handleForward(msg)
   946  		require.Error(t, err)
   947  		require.Contains(t, err.Error(), "add error")
   948  	})
   949  }
   950  
   951  func TestRegister(t *testing.T) {
   952  	t.Run("test register route - success", func(t *testing.T) {
   953  		msgID := make(chan string)
   954  
   955  		s := make(map[string]mockstore.DBEntry)
   956  		svc, err := New(&mockprovider.Provider{
   957  			ServiceMap: map[string]interface{}{
   958  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
   959  			},
   960  			StorageProviderValue:              &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: s}},
   961  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
   962  			KMSValue:                          &mockkms.KeyManager{},
   963  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
   964  				ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error {
   965  					require.Equal(t, myDID, MYDID)
   966  					require.Equal(t, theirDID, THEIRDID)
   967  
   968  					reqMsgMap, ok := msg.(service.DIDCommMsgMap)
   969  					require.True(t, ok)
   970  
   971  					request := &Request{}
   972  
   973  					err := reqMsgMap.Decode(request)
   974  					require.NoError(t, err)
   975  
   976  					msgID <- request.ID
   977  					return nil
   978  				},
   979  			},
   980  		})
   981  		require.NoError(t, err)
   982  
   983  		connRec := &connection.Record{
   984  			ConnectionID: "conn", MyDID: MYDID, TheirDID: THEIRDID, State: "complete",
   985  		}
   986  		connBytes, err := json.Marshal(connRec)
   987  		require.NoError(t, err)
   988  		s["conn_conn"] = mockstore.DBEntry{Value: connBytes}
   989  
   990  		go func() {
   991  			id := <-msgID
   992  			require.NoError(t, svc.saveGrant(generateGrantMsgPayload(t, id)))
   993  		}()
   994  
   995  		err = svc.Register("conn")
   996  		require.NoError(t, err)
   997  
   998  		err = svc.Register("conn")
   999  		require.Error(t, err)
  1000  		require.Contains(t, err.Error(), "router is already registered")
  1001  	})
  1002  
  1003  	t.Run("test register route - with client timeout error", func(t *testing.T) {
  1004  		s := make(map[string]mockstore.DBEntry)
  1005  		svc, err := New(&mockprovider.Provider{
  1006  			ServiceMap: map[string]interface{}{
  1007  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1008  			},
  1009  			StorageProviderValue:              &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: s}},
  1010  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1011  			KMSValue:                          &mockkms.KeyManager{},
  1012  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
  1013  		})
  1014  		require.NoError(t, err)
  1015  
  1016  		connRec := &connection.Record{
  1017  			ConnectionID: "conn2", MyDID: MYDID, TheirDID: THEIRDID, State: "complete",
  1018  		}
  1019  		connBytes, err := json.Marshal(connRec)
  1020  		require.NoError(t, err)
  1021  		s["conn_conn2"] = mockstore.DBEntry{Value: connBytes}
  1022  
  1023  		err = svc.Register("conn2", func(opts *ClientOptions) {
  1024  			opts.Timeout = 1 * time.Millisecond
  1025  		})
  1026  
  1027  		require.Error(t, err)
  1028  		require.Contains(t, err.Error(), "get grant for request ID '")
  1029  		require.Contains(t, err.Error(), "': store: data not found")
  1030  	})
  1031  
  1032  	t.Run("test register route - router connection not found", func(t *testing.T) {
  1033  		svc, err := New(&mockprovider.Provider{
  1034  			ServiceMap: map[string]interface{}{
  1035  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1036  			},
  1037  			StorageProviderValue:              mockstore.NewMockStoreProvider(),
  1038  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1039  			KMSValue:                          &mockkms.KeyManager{},
  1040  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
  1041  				ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error {
  1042  					return fmt.Errorf("error send")
  1043  				},
  1044  			},
  1045  		})
  1046  		require.NoError(t, err)
  1047  
  1048  		err = svc.Register("conn")
  1049  		require.Error(t, err)
  1050  		require.Contains(t, err.Error(), ErrConnectionNotFound.Error())
  1051  	})
  1052  
  1053  	t.Run("test register route - router connection fetch error", func(t *testing.T) {
  1054  		svc, err := New(&mockprovider.Provider{
  1055  			ServiceMap: map[string]interface{}{
  1056  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1057  			},
  1058  			StorageProviderValue: &mockstore.MockStoreProvider{
  1059  				Store: &mockstore.MockStore{ErrGet: fmt.Errorf("get error")},
  1060  			},
  1061  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1062  			KMSValue:                          &mockkms.KeyManager{},
  1063  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
  1064  				ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error {
  1065  					return fmt.Errorf("error send")
  1066  				},
  1067  			},
  1068  		})
  1069  		require.NoError(t, err)
  1070  
  1071  		err = svc.Register("conn")
  1072  		require.Error(t, err)
  1073  		require.Contains(t, err.Error(), "fetch connection record from store")
  1074  	})
  1075  }
  1076  
  1077  func TestUnregister(t *testing.T) {
  1078  	const connID = "conn-id"
  1079  
  1080  	t.Run("test unregister route - success", func(t *testing.T) {
  1081  		s := make(map[string]mockstore.DBEntry)
  1082  		svc, err := New(
  1083  			&mockprovider.Provider{
  1084  				ServiceMap: map[string]interface{}{
  1085  					messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1086  				},
  1087  				StorageProviderValue:              &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: s}},
  1088  				ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1089  			},
  1090  		)
  1091  		require.NoError(t, err)
  1092  
  1093  		s[fmt.Sprintf(routeConnIDDataKey, connID)] = mockstore.DBEntry{Value: []byte("{\"connectionID\":\"conn-abc-xyz\"}")}
  1094  
  1095  		err = svc.Unregister(connID)
  1096  		require.NoError(t, err)
  1097  	})
  1098  
  1099  	t.Run("test unregister route - router not registered", func(t *testing.T) {
  1100  		s := make(map[string]mockstore.DBEntry)
  1101  		svc, err := New(
  1102  			&mockprovider.Provider{
  1103  				ServiceMap: map[string]interface{}{
  1104  					messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1105  				},
  1106  				StorageProviderValue: &mockstore.MockStoreProvider{
  1107  					Store: &mockstore.MockStore{Store: s},
  1108  				},
  1109  				ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1110  			},
  1111  		)
  1112  		require.NoError(t, err)
  1113  
  1114  		err = svc.Unregister(connID)
  1115  		require.Error(t, err)
  1116  		require.Contains(t, err.Error(), "router not registered")
  1117  	})
  1118  
  1119  	t.Run("test unregister route - db error", func(t *testing.T) {
  1120  		s := make(map[string]mockstore.DBEntry)
  1121  		svc, err := New(
  1122  			&mockprovider.Provider{
  1123  				ServiceMap: map[string]interface{}{
  1124  					messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1125  				},
  1126  				StorageProviderValue: &mockstore.MockStoreProvider{
  1127  					Store: &mockstore.MockStore{Store: s, ErrGet: errors.New("get error")},
  1128  				},
  1129  				ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1130  			},
  1131  		)
  1132  		require.NoError(t, err)
  1133  
  1134  		err = svc.Unregister(connID)
  1135  		require.Error(t, err)
  1136  		require.EqualError(t, err, "ensure connection exists: get error")
  1137  	})
  1138  }
  1139  
  1140  func TestKeylistUpdate(t *testing.T) {
  1141  	const connID = "conn-id"
  1142  
  1143  	t.Run("test keylist update - success", func(t *testing.T) {
  1144  		keyUpdateMsg := make(chan KeylistUpdate)
  1145  		recKey := "ojaosdjoajs123jkas"
  1146  
  1147  		s := make(map[string]mockstore.DBEntry)
  1148  		svc, err := New(&mockprovider.Provider{
  1149  			ServiceMap: map[string]interface{}{
  1150  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1151  			},
  1152  			StorageProviderValue:              &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: s}},
  1153  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1154  			KMSValue:                          &mockkms.KeyManager{},
  1155  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
  1156  				ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error {
  1157  					require.Equal(t, myDID, MYDID)
  1158  					require.Equal(t, theirDID, THEIRDID)
  1159  
  1160  					reqMsgMap, ok := msg.(service.DIDCommMsgMap)
  1161  					require.True(t, ok)
  1162  
  1163  					request := &KeylistUpdate{}
  1164  
  1165  					err := reqMsgMap.Decode(request)
  1166  					require.NoError(t, err)
  1167  
  1168  					keyUpdateMsg <- *request
  1169  					return nil
  1170  				},
  1171  			},
  1172  		})
  1173  		require.NoError(t, err)
  1174  
  1175  		// save router connID
  1176  		require.NoError(t, svc.saveRouterConnectionID("conn", ""))
  1177  
  1178  		// save connections
  1179  		connRec := &connection.Record{
  1180  			ConnectionID: "conn", MyDID: MYDID, TheirDID: THEIRDID, State: "complete",
  1181  		}
  1182  		connBytes, err := json.Marshal(connRec)
  1183  		require.NoError(t, err)
  1184  		s["conn_conn"] = mockstore.DBEntry{Value: connBytes}
  1185  
  1186  		go func() {
  1187  			updateMsg := <-keyUpdateMsg
  1188  
  1189  			updates := []UpdateResponse{
  1190  				{
  1191  					RecipientKey: updateMsg.Updates[0].RecipientKey,
  1192  					Action:       updateMsg.Updates[0].Action,
  1193  					Result:       success,
  1194  				},
  1195  			}
  1196  			require.NoError(t, svc.handleKeylistUpdateResponse(generateKeylistUpdateResponseMsgPayload(
  1197  				t, updateMsg.ID, updates)))
  1198  		}()
  1199  
  1200  		err = svc.AddKey("conn", recKey)
  1201  		require.NoError(t, err)
  1202  	})
  1203  
  1204  	t.Run("test keylist update - failure", func(t *testing.T) {
  1205  		keyUpdateMsg := make(chan KeylistUpdate)
  1206  		recKey := "ojaosdjoajs123jkas"
  1207  
  1208  		s := make(map[string]mockstore.DBEntry)
  1209  		svc, err := New(&mockprovider.Provider{
  1210  			ServiceMap: map[string]interface{}{
  1211  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1212  			},
  1213  			StorageProviderValue:              &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: s}},
  1214  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1215  			KMSValue:                          &mockkms.KeyManager{},
  1216  			OutboundDispatcherValue: &mockdispatcher.MockOutbound{
  1217  				ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error {
  1218  					require.Equal(t, myDID, MYDID)
  1219  					require.Equal(t, theirDID, THEIRDID)
  1220  
  1221  					reqMsgMap, ok := msg.(service.DIDCommMsgMap)
  1222  					require.True(t, ok)
  1223  
  1224  					request := &KeylistUpdate{}
  1225  
  1226  					err := reqMsgMap.Decode(request)
  1227  					require.NoError(t, err)
  1228  
  1229  					keyUpdateMsg <- *request
  1230  					return nil
  1231  				},
  1232  			},
  1233  		})
  1234  		require.NoError(t, err)
  1235  
  1236  		// no router registered
  1237  		err = svc.AddKey(connID, recKey)
  1238  		require.Error(t, err)
  1239  		require.Contains(t, err.Error(), "router not registered")
  1240  
  1241  		// save router connID
  1242  		require.NoError(t, svc.saveRouterConnectionID("conn", ""))
  1243  
  1244  		// no connections saved
  1245  		err = svc.AddKey("conn", recKey)
  1246  		require.Error(t, err)
  1247  		require.Contains(t, err.Error(), "connection not found")
  1248  
  1249  		// save connections
  1250  		connRec := &connection.Record{
  1251  			ConnectionID: "conn", MyDID: MYDID, TheirDID: THEIRDID, State: "complete",
  1252  		}
  1253  		connBytes, err := json.Marshal(connRec)
  1254  		require.NoError(t, err)
  1255  		s["conn_conn"] = mockstore.DBEntry{Value: connBytes}
  1256  
  1257  		go func() {
  1258  			updateMsg := <-keyUpdateMsg
  1259  
  1260  			updates := []UpdateResponse{
  1261  				{
  1262  					RecipientKey: updateMsg.Updates[0].RecipientKey,
  1263  					Action:       updateMsg.Updates[0].Action,
  1264  					Result:       serverError,
  1265  				},
  1266  			}
  1267  			require.NoError(t, svc.handleKeylistUpdateResponse(generateKeylistUpdateResponseMsgPayload(
  1268  				t, updateMsg.ID, updates)))
  1269  		}()
  1270  
  1271  		err = svc.AddKey("conn", recKey)
  1272  		require.Error(t, err)
  1273  		require.Contains(t, err.Error(), "failed to update the recipient key with the router")
  1274  	})
  1275  
  1276  	t.Run("test keylist update - timeout error", func(t *testing.T) {
  1277  		s := make(map[string]mockstore.DBEntry)
  1278  		svc, err := New(&mockprovider.Provider{
  1279  			ServiceMap: map[string]interface{}{
  1280  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1281  			},
  1282  			StorageProviderValue:              &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: s}},
  1283  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1284  			KMSValue:                          &mockkms.KeyManager{},
  1285  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
  1286  		})
  1287  		require.NoError(t, err)
  1288  
  1289  		connRec := &connection.Record{
  1290  			ConnectionID: "conn2", MyDID: MYDID, TheirDID: THEIRDID, State: "complete",
  1291  		}
  1292  		connBytes, err := json.Marshal(connRec)
  1293  		require.NoError(t, err)
  1294  		s["conn_conn2"] = mockstore.DBEntry{Value: connBytes}
  1295  		require.NoError(t, svc.saveRouterConnectionID("conn2", ""))
  1296  
  1297  		err = svc.AddKey("conn2", "recKey")
  1298  		require.Error(t, err)
  1299  		require.Contains(t, err.Error(), "timeout waiting for keylist update response from the router")
  1300  	})
  1301  
  1302  	t.Run("test keylist update - router connectionID fetch error", func(t *testing.T) {
  1303  		s := make(map[string]mockstore.DBEntry)
  1304  		svc, err := New(&mockprovider.Provider{
  1305  			ServiceMap: map[string]interface{}{
  1306  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1307  			},
  1308  			StorageProviderValue: &mockstore.MockStoreProvider{
  1309  				Store: &mockstore.MockStore{Store: s, ErrGet: errors.New("get error")},
  1310  			},
  1311  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1312  			KMSValue:                          &mockkms.KeyManager{},
  1313  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
  1314  		})
  1315  		require.NoError(t, err)
  1316  
  1317  		err = svc.AddKey("conn", "recKey")
  1318  		require.Error(t, err)
  1319  		require.EqualError(t, err, "ensure connection exists: get error")
  1320  	})
  1321  }
  1322  
  1323  func TestConfig(t *testing.T) {
  1324  	routingKeys := []string{"abc", "xyz"}
  1325  
  1326  	t.Run("test config - success", func(t *testing.T) {
  1327  		s := make(map[string]mockstore.DBEntry)
  1328  		svc, err := New(&mockprovider.Provider{
  1329  			ServiceMap: map[string]interface{}{
  1330  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1331  			},
  1332  			StorageProviderValue:              &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: s}},
  1333  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1334  			KMSValue:                          &mockkms.KeyManager{},
  1335  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
  1336  		})
  1337  		require.NoError(t, err)
  1338  
  1339  		require.NoError(t, svc.saveRouterConnectionID("connID-123", ""))
  1340  		require.NoError(t, svc.saveRouterConfig("connID-123", &config{
  1341  			RouterEndpoint: ENDPOINT,
  1342  			RoutingKeys:    routingKeys,
  1343  		}))
  1344  
  1345  		conf, err := svc.Config("connID-123")
  1346  		require.NoError(t, err)
  1347  		require.Equal(t, ENDPOINT, conf.Endpoint())
  1348  		require.Equal(t, routingKeys, conf.Keys())
  1349  	})
  1350  
  1351  	t.Run("test config - no router registered", func(t *testing.T) {
  1352  		s := make(map[string]mockstore.DBEntry)
  1353  		svc, err := New(&mockprovider.Provider{
  1354  			ServiceMap: map[string]interface{}{
  1355  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1356  			},
  1357  			StorageProviderValue:              &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: s}},
  1358  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1359  			KMSValue:                          &mockkms.KeyManager{},
  1360  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
  1361  		})
  1362  		require.NoError(t, err)
  1363  
  1364  		conf, err := svc.Config("conn")
  1365  		require.Error(t, err)
  1366  		require.True(t, errors.Is(err, ErrRouterNotRegistered))
  1367  		require.Nil(t, conf)
  1368  	})
  1369  
  1370  	t.Run("test config - missing configs", func(t *testing.T) {
  1371  		s := make(map[string]mockstore.DBEntry)
  1372  		svc, err := New(&mockprovider.Provider{
  1373  			ServiceMap: map[string]interface{}{
  1374  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1375  			},
  1376  			StorageProviderValue:              &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: s}},
  1377  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1378  			KMSValue:                          &mockkms.KeyManager{},
  1379  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
  1380  		})
  1381  		require.NoError(t, err)
  1382  
  1383  		require.NoError(t, svc.saveRouterConnectionID("connID-123", ""))
  1384  
  1385  		conf, err := svc.Config("connID-123")
  1386  		require.Error(t, err)
  1387  		require.Contains(t, err.Error(), "get router config data")
  1388  		require.Nil(t, conf)
  1389  	})
  1390  
  1391  	t.Run("test config - invalid config data in db", func(t *testing.T) {
  1392  		s := make(map[string]mockstore.DBEntry)
  1393  		svc, err := New(&mockprovider.Provider{
  1394  			ServiceMap: map[string]interface{}{
  1395  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1396  			},
  1397  			StorageProviderValue:              &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: s}},
  1398  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1399  			KMSValue:                          &mockkms.KeyManager{},
  1400  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
  1401  		})
  1402  		require.NoError(t, err)
  1403  
  1404  		const conn = "connID-123"
  1405  
  1406  		require.NoError(t, svc.saveRouterConnectionID(conn, ""))
  1407  		require.NoError(t, svc.routeStore.Put(fmt.Sprintf(routeConfigDataKey, conn), []byte("invalid data")))
  1408  
  1409  		conf, err := svc.Config(conn)
  1410  		require.Error(t, err)
  1411  		require.Contains(t, err.Error(), "unmarshal router config data")
  1412  		require.Nil(t, conf)
  1413  	})
  1414  
  1415  	t.Run("test config - router connectionID fetch error", func(t *testing.T) {
  1416  		s := make(map[string]mockstore.DBEntry)
  1417  		svc, err := New(&mockprovider.Provider{
  1418  			ServiceMap: map[string]interface{}{
  1419  				messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1420  			},
  1421  			StorageProviderValue: &mockstore.MockStoreProvider{
  1422  				Store: &mockstore.MockStore{Store: s, ErrGet: errors.New("get error")},
  1423  			},
  1424  			ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(),
  1425  			KMSValue:                          &mockkms.KeyManager{},
  1426  			OutboundDispatcherValue:           &mockdispatcher.MockOutbound{},
  1427  		})
  1428  		require.NoError(t, err)
  1429  
  1430  		require.NoError(t, svc.saveRouterConnectionID("connID-123", ""))
  1431  		require.NoError(t, svc.routeStore.Put(routeConfigDataKey, []byte("invalid data")))
  1432  
  1433  		conf, err := svc.Config("connID-123")
  1434  		require.Error(t, err)
  1435  		require.EqualError(t, err, "ensure connection exists: get error")
  1436  		require.Nil(t, conf)
  1437  	})
  1438  }
  1439  
  1440  func TestGetConnections(t *testing.T) {
  1441  	routerConnectionID := "conn-abc-xyz"
  1442  
  1443  	t.Run("test get connection - success", func(t *testing.T) {
  1444  		svc, err := New(
  1445  			&mockprovider.Provider{
  1446  				ServiceMap: map[string]interface{}{
  1447  					messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1448  				},
  1449  				StorageProviderValue:              mem.NewProvider(),
  1450  				ProtocolStateStorageProviderValue: mem.NewProvider(),
  1451  			},
  1452  		)
  1453  		require.NoError(t, err)
  1454  
  1455  		err = svc.saveRouterConnectionID(routerConnectionID, "")
  1456  		require.NoError(t, err)
  1457  
  1458  		connID, err := svc.GetConnections()
  1459  		require.NoError(t, err)
  1460  		require.Equal(t, routerConnectionID, connID[0])
  1461  	})
  1462  
  1463  	t.Run("test get connection - no data found", func(t *testing.T) {
  1464  		svc, err := New(
  1465  			&mockprovider.Provider{
  1466  				ServiceMap: map[string]interface{}{
  1467  					messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1468  				},
  1469  				StorageProviderValue:              mem.NewProvider(),
  1470  				ProtocolStateStorageProviderValue: mem.NewProvider(),
  1471  			},
  1472  		)
  1473  		require.NoError(t, err)
  1474  
  1475  		connID, err := svc.GetConnections()
  1476  		require.NoError(t, err)
  1477  		require.Empty(t, connID)
  1478  	})
  1479  
  1480  	t.Run("test get connection - filter by didcomm version", func(t *testing.T) {
  1481  		svc, err := New(
  1482  			&mockprovider.Provider{
  1483  				ServiceMap: map[string]interface{}{
  1484  					messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1485  				},
  1486  				StorageProviderValue:              mem.NewProvider(),
  1487  				ProtocolStateStorageProviderValue: mem.NewProvider(),
  1488  			},
  1489  		)
  1490  		require.NoError(t, err)
  1491  
  1492  		const (
  1493  			connID1 = "conn-id-1"
  1494  			connID2 = "conn-id-2"
  1495  		)
  1496  
  1497  		err = svc.saveRouterConnectionID(connID1, service.V1)
  1498  		require.NoError(t, err)
  1499  
  1500  		err = svc.saveRouterConnectionID(connID2, service.V2)
  1501  		require.NoError(t, err)
  1502  
  1503  		connIDs, err := svc.GetConnections()
  1504  		require.NoError(t, err)
  1505  		require.Len(t, connIDs, 2)
  1506  
  1507  		connIDs, err = svc.GetConnections(ConnectionByVersion(service.V1))
  1508  		require.NoError(t, err)
  1509  		require.Len(t, connIDs, 1)
  1510  		require.Equal(t, connID1, connIDs[0])
  1511  
  1512  		connIDs, err = svc.GetConnections(ConnectionByVersion(service.V2))
  1513  		require.NoError(t, err)
  1514  		require.Len(t, connIDs, 1)
  1515  		require.Equal(t, connID2, connIDs[0])
  1516  	})
  1517  
  1518  	t.Run("test get connection - fail to parse connection entry", func(t *testing.T) {
  1519  		svc, err := New(
  1520  			&mockprovider.Provider{
  1521  				ServiceMap: map[string]interface{}{
  1522  					messagepickup.MessagePickup: &mockmessagep.MockMessagePickupSvc{},
  1523  				},
  1524  				StorageProviderValue:              mem.NewProvider(),
  1525  				ProtocolStateStorageProviderValue: mem.NewProvider(),
  1526  			},
  1527  		)
  1528  		require.NoError(t, err)
  1529  
  1530  		err = svc.routeStore.Put(
  1531  			fmt.Sprintf(routeConnIDDataKey, routerConnectionID),
  1532  			[]byte("foo"),
  1533  			storage.Tag{Name: routeConnIDDataKey},
  1534  		)
  1535  		require.NoError(t, err)
  1536  
  1537  		_, err = svc.GetConnections()
  1538  		require.Error(t, err)
  1539  		require.Contains(t, err.Error(), "failed to unmarshal router connection entry")
  1540  	})
  1541  }
  1542  
  1543  func generateRequestMsgPayload(t *testing.T, id string) service.DIDCommMsg {
  1544  	requestBytes, err := json.Marshal(&Request{
  1545  		Type: RequestMsgType,
  1546  		ID:   id,
  1547  	})
  1548  	require.NoError(t, err)
  1549  
  1550  	didMsg, err := service.ParseDIDCommMsgMap(requestBytes)
  1551  	require.NoError(t, err)
  1552  
  1553  	return didMsg
  1554  }
  1555  
  1556  func generateGrantMsgPayload(t *testing.T, id string) service.DIDCommMsg {
  1557  	grantBytes, err := json.Marshal(&Grant{
  1558  		Type: GrantMsgType,
  1559  		ID:   id,
  1560  	})
  1561  	require.NoError(t, err)
  1562  
  1563  	didMsg, err := service.ParseDIDCommMsgMap(grantBytes)
  1564  	require.NoError(t, err)
  1565  
  1566  	return didMsg
  1567  }
  1568  
  1569  func generateKeyUpdateListMsgPayload(t *testing.T, id string, updates []Update) service.DIDCommMsg {
  1570  	requestBytes, err := json.Marshal(&KeylistUpdate{
  1571  		Type:    KeylistUpdateMsgType,
  1572  		ID:      id,
  1573  		Updates: updates,
  1574  	})
  1575  	require.NoError(t, err)
  1576  
  1577  	didMsg, err := service.ParseDIDCommMsgMap(requestBytes)
  1578  	require.NoError(t, err)
  1579  
  1580  	return didMsg
  1581  }
  1582  
  1583  func generateKeylistUpdateResponseMsgPayload(t *testing.T, id string, updates []UpdateResponse) service.DIDCommMsg {
  1584  	respBytes, err := json.Marshal(&KeylistUpdateResponse{
  1585  		Type:    KeylistUpdateResponseMsgType,
  1586  		ID:      id,
  1587  		Updated: updates,
  1588  	})
  1589  	require.NoError(t, err)
  1590  
  1591  	didMsg, err := service.ParseDIDCommMsgMap(respBytes)
  1592  	require.NoError(t, err)
  1593  
  1594  	return didMsg
  1595  }
  1596  
  1597  func generateForwardMsgPayload(t *testing.T, id, to string, msg []byte) service.DIDCommMsg {
  1598  	requestBytes, err := json.Marshal(&model.Forward{
  1599  		Type: service.ForwardMsgType,
  1600  		ID:   id,
  1601  		To:   to,
  1602  		Msg:  msg,
  1603  	})
  1604  	require.NoError(t, err)
  1605  
  1606  	didMsg, err := service.ParseDIDCommMsgMap(requestBytes)
  1607  	require.NoError(t, err)
  1608  
  1609  	return didMsg
  1610  }
  1611  
  1612  func randomID() string {
  1613  	return uuid.New().String()
  1614  }
  1615  
  1616  type connectionsStub struct {
  1617  	getConnIDByDIDs func(string, string) (string, error)
  1618  	getConnRecord   func(string) (*connection.Record, error)
  1619  }
  1620  
  1621  func (c *connectionsStub) GetConnectionRecordByDIDs(myDID, theirDID string) (*connection.Record, error) {
  1622  	connID, err := c.GetConnectionIDByDIDs(myDID, theirDID)
  1623  	if err != nil {
  1624  		return nil, err
  1625  	}
  1626  
  1627  	return c.GetConnectionRecord(connID)
  1628  }
  1629  
  1630  func (c *connectionsStub) GetConnectionIDByDIDs(myDID, theirDID string) (string, error) {
  1631  	if c.getConnIDByDIDs != nil {
  1632  		return c.getConnIDByDIDs(myDID, theirDID)
  1633  	}
  1634  
  1635  	return "", nil
  1636  }
  1637  
  1638  func (c *connectionsStub) GetConnectionRecord(id string) (*connection.Record, error) {
  1639  	if c.getConnRecord != nil {
  1640  		return c.getConnRecord(id)
  1641  	}
  1642  
  1643  	return nil, nil
  1644  }