github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/protocol/didexchange/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 didexchange
     8  
     9  import (
    10  	"crypto/ed25519"
    11  	"encoding/base64"
    12  	"encoding/json"
    13  	"errors"
    14  	"fmt"
    15  	"strings"
    16  	"testing"
    17  	"time"
    18  
    19  	"github.com/btcsuite/btcutil/base58"
    20  	"github.com/google/uuid"
    21  	"github.com/stretchr/testify/require"
    22  
    23  	commonmodel "github.com/hyperledger/aries-framework-go/pkg/common/model"
    24  	"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
    25  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
    26  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
    27  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
    28  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator"
    29  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
    30  	"github.com/hyperledger/aries-framework-go/pkg/doc/did"
    31  	"github.com/hyperledger/aries-framework-go/pkg/doc/util/kmsdidkey"
    32  	vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
    33  	"github.com/hyperledger/aries-framework-go/pkg/kms"
    34  	"github.com/hyperledger/aries-framework-go/pkg/kms/localkms"
    35  	"github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol"
    36  	mockroute "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/mediator"
    37  	mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/mock/diddoc"
    38  	mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
    39  	mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider"
    40  	mockstorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage"
    41  	mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr"
    42  	"github.com/hyperledger/aries-framework-go/pkg/secretlock"
    43  	"github.com/hyperledger/aries-framework-go/pkg/secretlock/noop"
    44  	"github.com/hyperledger/aries-framework-go/pkg/store/connection"
    45  	didstore "github.com/hyperledger/aries-framework-go/pkg/store/did"
    46  	"github.com/hyperledger/aries-framework-go/pkg/vdr/peer"
    47  	"github.com/hyperledger/aries-framework-go/spi/storage"
    48  )
    49  
    50  const (
    51  	testMethod    = "peer"
    52  	threadIDValue = "xyz"
    53  )
    54  
    55  type event interface {
    56  	// connection ID
    57  	ConnectionID() string
    58  
    59  	// invitation ID
    60  	InvitationID() string
    61  }
    62  
    63  func TestService_Name(t *testing.T) {
    64  	t.Run("test success", func(t *testing.T) {
    65  		prov, err := New(&protocol.MockProvider{
    66  			ServiceMap: map[string]interface{}{
    67  				mediator.Coordination: &mockroute.MockMediatorSvc{},
    68  			},
    69  		})
    70  		require.NoError(t, err)
    71  		require.Equal(t, DIDExchange, prov.Name())
    72  	})
    73  }
    74  
    75  func TestServiceNew(t *testing.T) {
    76  	t.Run("test error from open store", func(t *testing.T) {
    77  		_, err := New(
    78  			&protocol.MockProvider{StoreProvider: &mockstorage.MockStoreProvider{
    79  				ErrOpenStoreHandle: fmt.Errorf("failed to open store"),
    80  			}})
    81  		require.Error(t, err)
    82  		require.Contains(t, err.Error(), "failed to open store")
    83  	})
    84  
    85  	t.Run("test error from open protocol state store", func(t *testing.T) {
    86  		_, err := New(
    87  			&protocol.MockProvider{ProtocolStateStoreProvider: &mockstorage.MockStoreProvider{
    88  				ErrOpenStoreHandle: fmt.Errorf("failed to open protocol state store"),
    89  			}})
    90  		require.Error(t, err)
    91  		require.Contains(t, err.Error(), "failed to open protocol state store")
    92  	})
    93  
    94  	t.Run("test service new error - no route service found", func(t *testing.T) {
    95  		_, err := New(&protocol.MockProvider{ServiceErr: errors.New("service not found")})
    96  		require.Error(t, err)
    97  		require.Contains(t, err.Error(), "service not found")
    98  	})
    99  
   100  	t.Run("test service new error - casting to route service failed", func(t *testing.T) {
   101  		_, err := New(&protocol.MockProvider{})
   102  		require.Error(t, err)
   103  		require.Contains(t, err.Error(), "cast service to Route Service failed")
   104  	})
   105  }
   106  
   107  func TestService_Initialize(t *testing.T) {
   108  	t.Run("success: already initialized", func(t *testing.T) {
   109  		prov := &protocol.MockProvider{
   110  			ServiceMap: map[string]interface{}{
   111  				mediator.Coordination: &mockroute.MockMediatorSvc{},
   112  			},
   113  		}
   114  
   115  		svc, err := New(prov)
   116  		require.NoError(t, err)
   117  
   118  		require.NoError(t, svc.Initialize(prov))
   119  	})
   120  
   121  	t.Run("fail: provider of wrong type", func(t *testing.T) {
   122  		prov := "this is not a provider"
   123  
   124  		svc := Service{}
   125  
   126  		err := svc.Initialize(prov)
   127  
   128  		require.Error(t, err)
   129  		require.Contains(t, err.Error(), "expected provider of type")
   130  	})
   131  }
   132  
   133  // did-exchange flow with role Inviter.
   134  func TestService_Handle_Inviter(t *testing.T) {
   135  	mockStore := &mockstorage.MockStore{Store: make(map[string]mockstorage.DBEntry)}
   136  	storeProv := mockstorage.NewCustomMockStoreProvider(mockStore)
   137  	k := newKMS(t, storeProv)
   138  	prov := &protocol.MockProvider{
   139  		StoreProvider: storeProv,
   140  		ServiceMap: map[string]interface{}{
   141  			mediator.Coordination: &mockroute.MockMediatorSvc{},
   142  		},
   143  		CustomKMS:             k,
   144  		KeyTypeValue:          kms.ED25519Type,
   145  		KeyAgreementTypeValue: kms.X25519ECDHKWType,
   146  	}
   147  
   148  	ctx := &context{
   149  		outboundDispatcher: prov.OutboundDispatcher(),
   150  		crypto:             &tinkcrypto.Crypto{},
   151  		kms:                k,
   152  		keyType:            kms.ED25519Type,
   153  		keyAgreementType:   kms.X25519ECDHKWType,
   154  	}
   155  
   156  	verPubKey, encPubKey := newSigningAndEncryptionDIDKeys(t, ctx)
   157  	mtp := transport.MediaTypeRFC0019EncryptedEnvelope
   158  
   159  	ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: createDIDDocWithKey(verPubKey, encPubKey, mtp)}
   160  
   161  	connRec, err := connection.NewRecorder(prov)
   162  	require.NoError(t, err)
   163  	require.NotNil(t, connRec)
   164  
   165  	ctx.connectionRecorder = connRec
   166  
   167  	doc, err := ctx.vdRegistry.Create(testMethod, nil)
   168  	require.NoError(t, err)
   169  
   170  	s, err := New(prov)
   171  	require.NoError(t, err)
   172  
   173  	actionCh := make(chan service.DIDCommAction, 10)
   174  	err = s.RegisterActionEvent(actionCh)
   175  	require.NoError(t, err)
   176  
   177  	statusCh := make(chan service.StateMsg, 10)
   178  	err = s.RegisterMsgEvent(statusCh)
   179  	require.NoError(t, err)
   180  
   181  	completedFlag := make(chan struct{})
   182  	respondedFlag := make(chan struct{})
   183  
   184  	go msgEventListener(t, statusCh, respondedFlag, completedFlag)
   185  
   186  	go func() { service.AutoExecuteActionEvent(actionCh) }()
   187  
   188  	invitation := &Invitation{
   189  		Type:            InvitationMsgType,
   190  		ID:              randomString(),
   191  		Label:           "Bob",
   192  		RecipientKeys:   []string{verPubKey},
   193  		ServiceEndpoint: "http://alice.agent.example.com:8081",
   194  	}
   195  
   196  	err = ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
   197  	require.NoError(t, err)
   198  
   199  	thid := randomString()
   200  
   201  	// Invitation was previously sent by Alice to Bob.
   202  	// Bob now sends a did-exchange Invitation
   203  	payloadBytes, err := json.Marshal(
   204  		&Request{
   205  			Type:  RequestMsgType,
   206  			ID:    thid,
   207  			Label: "Bob",
   208  			Thread: &decorator.Thread{
   209  				PID: invitation.ID,
   210  			},
   211  			DID:       doc.DIDDocument.ID,
   212  			DocAttach: unsignedDocAttach(t, doc.DIDDocument),
   213  		})
   214  	require.NoError(t, err)
   215  	msg, err := service.ParseDIDCommMsgMap(payloadBytes)
   216  	require.NoError(t, err)
   217  	_, err = s.HandleInbound(msg, service.NewDIDCommContext(doc.DIDDocument.ID, "", nil))
   218  	require.NoError(t, err)
   219  
   220  	select {
   221  	case <-respondedFlag:
   222  	case <-time.After(2 * time.Second):
   223  		require.Fail(t, "didn't receive post event responded")
   224  	}
   225  	// Alice automatically sends exchange Response to Bob
   226  	// Bob replies with an ACK
   227  	payloadBytes, err = json.Marshal(
   228  		&model.Ack{
   229  			Type:   AckMsgType,
   230  			ID:     randomString(),
   231  			Status: "OK",
   232  			Thread: &decorator.Thread{ID: thid},
   233  		})
   234  	require.NoError(t, err)
   235  
   236  	didMsg, err := service.ParseDIDCommMsgMap(payloadBytes)
   237  	require.NoError(t, err)
   238  
   239  	_, err = s.HandleInbound(didMsg, service.NewDIDCommContext(doc.DIDDocument.ID, "", nil))
   240  	require.NoError(t, err)
   241  
   242  	select {
   243  	case <-completedFlag:
   244  	case <-time.After(2 * time.Second):
   245  		require.Fail(t, "didn't receive post event complete")
   246  	}
   247  
   248  	validateState(t, s, thid, findNamespace(AckMsgType), (&completed{}).Name())
   249  }
   250  
   251  func msgEventListener(t *testing.T, statusCh chan service.StateMsg, respondedFlag, completedFlag chan struct{}) {
   252  	for e := range statusCh {
   253  		require.Equal(t, DIDExchange, e.ProtocolName)
   254  
   255  		prop, ok := e.Properties.(event)
   256  		if !ok {
   257  			require.Fail(t, "Failed to cast the event properties to service.Event")
   258  		}
   259  		// Get the connectionID when it's created
   260  		if e.Type == service.PreState {
   261  			if e.StateID == "requested" {
   262  				require.NotNil(t, prop.ConnectionID())
   263  				require.NotNil(t, prop.InvitationID())
   264  			}
   265  		}
   266  
   267  		if e.Type == service.PostState {
   268  			// receive the events
   269  			if e.StateID == "completed" {
   270  				// validate connectionID received during state transition with original connectionID
   271  				require.NotNil(t, prop.ConnectionID())
   272  				require.NotNil(t, prop.InvitationID())
   273  				close(completedFlag)
   274  			}
   275  
   276  			if e.StateID == "responded" {
   277  				// validate connectionID received during state transition with original connectionID
   278  				require.NotNil(t, prop.ConnectionID())
   279  				require.NotNil(t, prop.InvitationID())
   280  				close(respondedFlag)
   281  			}
   282  		}
   283  	}
   284  }
   285  
   286  type kmsProvider struct {
   287  	store             kms.Store
   288  	secretLockService secretlock.Service
   289  }
   290  
   291  func (k *kmsProvider) StorageProvider() kms.Store {
   292  	return k.store
   293  }
   294  
   295  func (k *kmsProvider) SecretLock() secretlock.Service {
   296  	return k.secretLockService
   297  }
   298  
   299  func newKMS(t *testing.T, store storage.Provider) kms.KeyManager {
   300  	t.Helper()
   301  
   302  	kmsStore, err := kms.NewAriesProviderWrapper(store)
   303  	require.NoError(t, err)
   304  
   305  	kmsProv := &kmsProvider{
   306  		store:             kmsStore,
   307  		secretLockService: &noop.NoLock{},
   308  	}
   309  
   310  	customKMS, err := localkms.New("local-lock://primary/test/", kmsProv)
   311  	require.NoError(t, err)
   312  
   313  	return customKMS
   314  }
   315  
   316  func newSigningAndEncryptionDIDKeys(t *testing.T, ctx *context) (string, string) {
   317  	t.Helper()
   318  
   319  	_, pubKey, err := ctx.kms.CreateAndExportPubKeyBytes(ctx.keyType)
   320  	require.NoError(t, err)
   321  
   322  	didKey, err := kmsdidkey.BuildDIDKeyByKeyType(pubKey, ctx.keyType)
   323  	require.NoError(t, err)
   324  
   325  	_, encPubKey, err := ctx.kms.CreateAndExportPubKeyBytes(ctx.keyAgreementType)
   326  	require.NoError(t, err)
   327  
   328  	encDIDKey, err := kmsdidkey.BuildDIDKeyByKeyType(encPubKey, ctx.keyAgreementType)
   329  	require.NoError(t, err)
   330  
   331  	return didKey, encDIDKey
   332  }
   333  
   334  // did-exchange flow with role Invitee.
   335  func TestService_Handle_Invitee(t *testing.T) {
   336  	protocolStateStore := mockstorage.NewMockStoreProvider()
   337  	store := mockstorage.NewMockStoreProvider()
   338  	k := newKMS(t, store)
   339  	prov := &protocol.MockProvider{
   340  		StoreProvider:              store,
   341  		ProtocolStateStoreProvider: protocolStateStore,
   342  		ServiceMap: map[string]interface{}{
   343  			mediator.Coordination: &mockroute.MockMediatorSvc{},
   344  		},
   345  		CustomKMS:             k,
   346  		KeyTypeValue:          kms.ED25519Type,
   347  		KeyAgreementTypeValue: kms.X25519ECDHKWType,
   348  	}
   349  
   350  	mtp := transport.MediaTypeRFC0019EncryptedEnvelope
   351  
   352  	ctx := &context{
   353  		outboundDispatcher: prov.OutboundDispatcher(),
   354  		crypto:             &tinkcrypto.Crypto{},
   355  		kms:                k,
   356  		keyType:            kms.ED25519Type,
   357  		keyAgreementType:   kms.X25519ECDHKWType,
   358  		mediaTypeProfiles:  []string{mtp},
   359  	}
   360  
   361  	verPubKey, encPubKey := newSigningAndEncryptionDIDKeys(t, ctx)
   362  
   363  	ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: createDIDDocWithKey(verPubKey, encPubKey, mtp)}
   364  
   365  	connRec, err := connection.NewRecorder(prov)
   366  	require.NoError(t, err)
   367  	require.NotNil(t, connRec)
   368  
   369  	ctx.connectionRecorder = connRec
   370  
   371  	doc, err := ctx.vdRegistry.Create(testMethod, nil)
   372  	require.NoError(t, err)
   373  
   374  	s, err := New(prov)
   375  	require.NoError(t, err)
   376  
   377  	s.ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: doc.DIDDocument}
   378  	actionCh := make(chan service.DIDCommAction, 10)
   379  	err = s.RegisterActionEvent(actionCh)
   380  	require.NoError(t, err)
   381  
   382  	statusCh := make(chan service.StateMsg, 10)
   383  	err = s.RegisterMsgEvent(statusCh)
   384  	require.NoError(t, err)
   385  
   386  	requestedCh := make(chan string)
   387  	completedCh := make(chan struct{})
   388  
   389  	go handleMessagesInvitee(statusCh, requestedCh, completedCh)
   390  
   391  	go func() { service.AutoExecuteActionEvent(actionCh) }()
   392  
   393  	invitation := &Invitation{
   394  		Type:            InvitationMsgType,
   395  		ID:              randomString(),
   396  		Label:           "Bob",
   397  		RecipientKeys:   []string{verPubKey},
   398  		ServiceEndpoint: "http://alice.agent.example.com:8081",
   399  	}
   400  
   401  	err = ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
   402  	require.NoError(t, err)
   403  	// Alice receives an invitation from Bob
   404  	payloadBytes, err := json.Marshal(invitation)
   405  	require.NoError(t, err)
   406  
   407  	didMsg, err := service.ParseDIDCommMsgMap(payloadBytes)
   408  	require.NoError(t, err)
   409  
   410  	_, err = s.HandleInbound(didMsg, service.EmptyDIDCommContext())
   411  	require.NoError(t, err)
   412  
   413  	var connID string
   414  	select {
   415  	case connID = <-requestedCh:
   416  	case <-time.After(2 * time.Second):
   417  		require.Fail(t, "didn't receive post event requested")
   418  	}
   419  
   420  	// Alice automatically sends a Request to Bob and is now in REQUESTED state.
   421  	connRecord, err := s.connectionRecorder.GetConnectionRecord(connID)
   422  	require.NoError(t, err)
   423  	require.Equal(t, (&requested{}).Name(), connRecord.State)
   424  	require.Equal(t, invitation.ID, connRecord.InvitationID)
   425  	require.Equal(t, invitation.RecipientKeys, connRecord.RecipientKeys)
   426  	uri, err := connRecord.ServiceEndPoint.URI()
   427  	require.NoError(t, err)
   428  	require.Equal(t, invitation.ServiceEndpoint, uri)
   429  
   430  	didKey, err := ctx.getVerKey(invitation.ID)
   431  	require.NoError(t, err)
   432  
   433  	docAttach, err := ctx.didDocAttachment(doc.DIDDocument, didKey)
   434  	require.NoError(t, err)
   435  
   436  	// Bob replies with a Response
   437  	payloadBytes, err = json.Marshal(
   438  		&Response{
   439  			Type:      ResponseMsgType,
   440  			ID:        randomString(),
   441  			DID:       doc.DIDDocument.ID,
   442  			DocAttach: docAttach,
   443  			Thread: &decorator.Thread{
   444  				ID: connRecord.ThreadID,
   445  			},
   446  		},
   447  	)
   448  	require.NoError(t, err)
   449  
   450  	didMsg, err = service.ParseDIDCommMsgMap(payloadBytes)
   451  	require.NoError(t, err)
   452  
   453  	_, err = s.HandleInbound(didMsg, service.EmptyDIDCommContext())
   454  	require.NoError(t, err)
   455  
   456  	// Alice automatically sends an ACK to Bob
   457  	// Alice must now be in COMPLETED state
   458  	select {
   459  	case <-completedCh:
   460  	case <-time.After(2 * time.Second):
   461  		require.Fail(t, "didn't receive post event complete")
   462  	}
   463  
   464  	validateState(t, s, connRecord.ThreadID, findNamespace(ResponseMsgType), (&completed{}).Name())
   465  }
   466  
   467  func handleMessagesInvitee(statusCh chan service.StateMsg, requestedCh chan string, completedCh chan struct{}) {
   468  	for e := range statusCh {
   469  		if e.Type == service.PostState {
   470  			// receive the events
   471  			if e.StateID == StateIDCompleted {
   472  				close(completedCh)
   473  			} else if e.StateID == StateIDRequested {
   474  				prop, ok := e.Properties.(event)
   475  				if !ok {
   476  					panic("Failed to cast the event properties to service.Event")
   477  				}
   478  
   479  				requestedCh <- prop.ConnectionID()
   480  			}
   481  		}
   482  	}
   483  }
   484  
   485  func TestService_Handle_EdgeCases(t *testing.T) {
   486  	t.Run("handleInbound - must not transition to same state", func(t *testing.T) {
   487  		s, err := New(&protocol.MockProvider{
   488  			ServiceMap: map[string]interface{}{
   489  				mediator.Coordination: &mockroute.MockMediatorSvc{},
   490  			},
   491  		})
   492  		require.NoError(t, err)
   493  
   494  		err = s.RegisterActionEvent(make(chan service.DIDCommAction))
   495  		require.NoError(t, err)
   496  
   497  		response, err := json.Marshal(
   498  			&Response{
   499  				Type:   ResponseMsgType,
   500  				ID:     randomString(),
   501  				Thread: &decorator.Thread{ID: randomString()},
   502  			},
   503  		)
   504  		require.NoError(t, err)
   505  
   506  		didMsg, err := service.ParseDIDCommMsgMap(response)
   507  		require.NoError(t, err)
   508  
   509  		_, err = s.HandleInbound(didMsg, service.EmptyDIDCommContext())
   510  		require.Error(t, err)
   511  		require.Contains(t, err.Error(), "handle inbound - next state : invalid state transition: "+
   512  			"null -> responded")
   513  	})
   514  
   515  	t.Run("handleInbound - connection record error", func(t *testing.T) {
   516  		protocolStateStore := &mockstorage.MockStore{
   517  			Store:  make(map[string]mockstorage.DBEntry),
   518  			ErrPut: errors.New("db error"),
   519  		}
   520  		prov := &protocol.MockProvider{
   521  			ProtocolStateStoreProvider: mockstorage.NewCustomMockStoreProvider(protocolStateStore),
   522  			ServiceMap: map[string]interface{}{
   523  				mediator.Coordination: &mockroute.MockMediatorSvc{},
   524  			},
   525  		}
   526  		svc, err := New(prov)
   527  		require.NoError(t, err)
   528  
   529  		err = svc.RegisterActionEvent(make(chan service.DIDCommAction))
   530  		require.NoError(t, err)
   531  
   532  		svc.connectionRecorder, err = connection.NewRecorder(prov)
   533  		require.NotNil(t, svc.connectionRecorder)
   534  		require.NoError(t, err)
   535  
   536  		_, err = svc.HandleInbound(
   537  			generateRequestMsgPayload(t, &protocol.MockProvider{}, randomString(), randomString()),
   538  			service.EmptyDIDCommContext())
   539  		require.Error(t, err)
   540  		require.Contains(t, err.Error(), "save connection record")
   541  	})
   542  
   543  	t.Run("handleInbound - no error", func(t *testing.T) {
   544  		svc, err := New(&protocol.MockProvider{
   545  			ServiceMap: map[string]interface{}{
   546  				mediator.Coordination: &mockroute.MockMediatorSvc{},
   547  			},
   548  		})
   549  		require.NoError(t, err)
   550  
   551  		err = svc.RegisterActionEvent(make(chan service.DIDCommAction))
   552  		require.NoError(t, err)
   553  
   554  		protocolStateStore := &mockStore{
   555  			get: func(s string) (bytes []byte, e error) {
   556  				return nil, storage.ErrDataNotFound
   557  			},
   558  			put: func(s string, bytes []byte, tags ...storage.Tag) error {
   559  				if strings.Contains(s, "didex-event-") {
   560  					return errors.New("db error")
   561  				}
   562  
   563  				return nil
   564  			},
   565  		}
   566  
   567  		svc.connectionRecorder, err = connection.NewRecorder(&protocol.MockProvider{
   568  			ProtocolStateStoreProvider: mockstorage.NewCustomMockStoreProvider(protocolStateStore),
   569  		})
   570  		require.NotNil(t, svc.connectionRecorder)
   571  		require.NoError(t, err)
   572  
   573  		requestBytes, err := json.Marshal(&Request{
   574  			Type: RequestMsgType,
   575  			ID:   generateRandomID(),
   576  			Connection: &Connection{
   577  				DID: "xyz",
   578  			},
   579  			Thread: &decorator.Thread{
   580  				PID: randomString(),
   581  			},
   582  		})
   583  		require.NoError(t, err)
   584  
   585  		// send invite
   586  		didMsg, err := service.ParseDIDCommMsgMap(requestBytes)
   587  		require.NoError(t, err)
   588  
   589  		_, err = svc.HandleInbound(didMsg, service.EmptyDIDCommContext())
   590  		require.NoError(t, err)
   591  	})
   592  }
   593  
   594  func TestService_Accept(t *testing.T) {
   595  	s := &Service{}
   596  
   597  	require.Equal(t, true, s.Accept("https://didcomm.org/didexchange/1.0/invitation"))
   598  	require.Equal(t, true, s.Accept("https://didcomm.org/didexchange/1.0/request"))
   599  	require.Equal(t, true, s.Accept("https://didcomm.org/didexchange/1.0/response"))
   600  	require.Equal(t, true, s.Accept("https://didcomm.org/didexchange/1.0/ack"))
   601  	require.Equal(t, true, s.Accept("https://didcomm.org/didexchange/1.0/complete"))
   602  	require.Equal(t, false, s.Accept("unsupported msg type"))
   603  }
   604  
   605  func TestService_CurrentState(t *testing.T) {
   606  	t.Run("null state if not found in store", func(t *testing.T) {
   607  		connRec, err := connection.NewRecorder(&protocol.MockProvider{
   608  			StoreProvider: mockstorage.NewCustomMockStoreProvider(&mockStore{
   609  				get: func(string) ([]byte, error) { return nil, storage.ErrDataNotFound },
   610  			}),
   611  		})
   612  		require.NotNil(t, connRec)
   613  		require.NoError(t, err)
   614  
   615  		svc := &Service{
   616  			connectionRecorder: connRec,
   617  		}
   618  		thid, err := connection.CreateNamespaceKey(theirNSPrefix, "ignored")
   619  		require.NoError(t, err)
   620  		s, err := svc.currentState(thid)
   621  		require.NoError(t, err)
   622  		require.Equal(t, (&null{}).Name(), s.Name())
   623  	})
   624  
   625  	t.Run("returns state from store", func(t *testing.T) {
   626  		expected := &requested{}
   627  		connRecord, err := json.Marshal(&connection.Record{State: expected.Name()})
   628  		require.NoError(t, err)
   629  
   630  		connRec, err := connection.NewRecorder(&protocol.MockProvider{
   631  			ProtocolStateStoreProvider: mockstorage.NewCustomMockStoreProvider(&mockStore{
   632  				get: func(string) ([]byte, error) { return connRecord, nil },
   633  			}),
   634  		})
   635  		require.NotNil(t, connRec)
   636  		require.NoError(t, err)
   637  
   638  		svc := &Service{
   639  			connectionRecorder: connRec,
   640  		}
   641  		thid, err := connection.CreateNamespaceKey(theirNSPrefix, "ignored")
   642  		require.NoError(t, err)
   643  		actual, err := svc.currentState(thid)
   644  		require.NoError(t, err)
   645  		require.Equal(t, expected.Name(), actual.Name())
   646  	})
   647  
   648  	t.Run("forwards generic error from store", func(t *testing.T) {
   649  		connRec, err := connection.NewRecorder(&protocol.MockProvider{
   650  			ProtocolStateStoreProvider: mockstorage.NewCustomMockStoreProvider(&mockStore{
   651  				get: func(string) ([]byte, error) {
   652  					return nil, errors.New("test")
   653  				},
   654  			}),
   655  		})
   656  		require.NotNil(t, connRec)
   657  		require.NoError(t, err)
   658  
   659  		svc := &Service{connectionRecorder: connRec}
   660  		thid, err := connection.CreateNamespaceKey(theirNSPrefix, "ignored")
   661  		require.NoError(t, err)
   662  		_, err = svc.currentState(thid)
   663  		require.Error(t, err)
   664  		require.Contains(t, err.Error(), "cannot fetch state from store")
   665  	})
   666  }
   667  
   668  func TestService_Update(t *testing.T) {
   669  	s := &requested{}
   670  	data := make(map[string][]byte)
   671  	connRecord := &connection.Record{
   672  		ThreadID: "123", ConnectionID: "123456", State: s.Name(),
   673  		Namespace: findNamespace(RequestMsgType),
   674  	}
   675  	bytes, err := json.Marshal(connRecord)
   676  	require.NoError(t, err)
   677  
   678  	connRec, err := connection.NewRecorder(&protocol.MockProvider{
   679  		StoreProvider: mockstorage.NewCustomMockStoreProvider(&mockStore{
   680  			put: func(k string, v []byte, tags ...storage.Tag) error {
   681  				data[k] = bytes
   682  				return nil
   683  			},
   684  			get: func(k string) ([]byte, error) {
   685  				return bytes, nil
   686  			},
   687  		}),
   688  	})
   689  	require.NotNil(t, connRec)
   690  	require.NoError(t, err)
   691  
   692  	svc := &Service{connectionRecorder: connRec}
   693  
   694  	require.NoError(t, svc.update(RequestMsgType, connRecord))
   695  
   696  	cr := &connection.Record{}
   697  	err = json.Unmarshal(bytes, cr)
   698  	require.NoError(t, err)
   699  	require.Equal(t, cr, connRecord)
   700  }
   701  
   702  func TestCreateConnection(t *testing.T) {
   703  	store := mockstorage.NewMockStoreProvider()
   704  	k := newKMS(t, store)
   705  
   706  	t.Run("create connection", func(t *testing.T) {
   707  		theirDID := newPeerDID(t, k)
   708  		record := &connection.Record{
   709  			ConnectionID:    uuid.New().String(),
   710  			State:           StateIDCompleted,
   711  			ThreadID:        uuid.New().String(),
   712  			ParentThreadID:  uuid.New().String(),
   713  			TheirLabel:      uuid.New().String(),
   714  			TheirDID:        theirDID.ID,
   715  			MyDID:           newPeerDID(t, k).ID,
   716  			ServiceEndPoint: commonmodel.NewDIDCommV1Endpoint("http://example.com"),
   717  			RecipientKeys:   []string{"testkeys"},
   718  			InvitationID:    uuid.New().String(),
   719  			Namespace:       myNSPrefix,
   720  		}
   721  		storedInVDR := false
   722  		storageProvider := &mockprovider.Provider{
   723  			StorageProviderValue:              mockstorage.NewMockStoreProvider(),
   724  			ProtocolStateStorageProviderValue: mockstorage.NewMockStoreProvider(),
   725  		}
   726  		provider := &mockprovider.Provider{
   727  			KMSValue:                          &mockkms.KeyManager{},
   728  			StorageProviderValue:              storageProvider.StorageProvider(),
   729  			ProtocolStateStorageProviderValue: storageProvider.ProtocolStateStorageProvider(),
   730  			VDRegistryValue: &mockvdr.MockVDRegistry{
   731  				CreateFunc: func(method string, result *did.Doc, _ ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
   732  					storedInVDR = true
   733  					require.Equal(t, theirDID, result)
   734  
   735  					return nil, nil
   736  				},
   737  			},
   738  			ServiceMap: map[string]interface{}{
   739  				mediator.Coordination: &mockroute.MockMediatorSvc{},
   740  			},
   741  			DIDConnectionStoreValue: &mockConnectionStore{},
   742  		}
   743  		s, err := New(provider)
   744  		require.NoError(t, err)
   745  
   746  		err = s.CreateConnection(record, theirDID)
   747  		require.True(t, storedInVDR)
   748  		require.NoError(t, err)
   749  
   750  		connRec, err := connection.NewRecorder(provider)
   751  		require.NoError(t, err)
   752  		result, err := connRec.GetConnectionRecord(record.ConnectionID)
   753  		require.NoError(t, err)
   754  		require.Equal(t, record, result)
   755  	})
   756  
   757  	t.Run("wraps vdr registry error", func(t *testing.T) {
   758  		expected := errors.New("test")
   759  		s, err := New(&mockprovider.Provider{
   760  			KMSValue:                          &mockkms.KeyManager{},
   761  			StorageProviderValue:              mockstorage.NewMockStoreProvider(),
   762  			ProtocolStateStorageProviderValue: mockstorage.NewMockStoreProvider(),
   763  			VDRegistryValue: &mockvdr.MockVDRegistry{
   764  				CreateFunc: func(s string, doc *did.Doc, option ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
   765  					return nil, expected
   766  				},
   767  			},
   768  			ServiceMap: map[string]interface{}{
   769  				mediator.Coordination: &mockroute.MockMediatorSvc{},
   770  			},
   771  		})
   772  		require.NoError(t, err)
   773  
   774  		err = s.CreateConnection(&connection.Record{}, newPeerDID(t, k))
   775  		require.Error(t, err)
   776  		require.True(t, errors.Is(err, expected))
   777  	})
   778  
   779  	t.Run("wraps connection store error", func(t *testing.T) {
   780  		expected := errors.New("test")
   781  		s, err := New(&mockprovider.Provider{
   782  			KMSValue: &mockkms.KeyManager{},
   783  			StorageProviderValue: &mockstorage.MockStoreProvider{
   784  				Store: &mockstorage.MockStore{ErrPut: expected},
   785  			},
   786  			ProtocolStateStorageProviderValue: mockstorage.NewMockStoreProvider(),
   787  			VDRegistryValue:                   &mockvdr.MockVDRegistry{},
   788  			ServiceMap: map[string]interface{}{
   789  				mediator.Coordination: &mockroute.MockMediatorSvc{},
   790  			},
   791  			DIDConnectionStoreValue: &mockConnectionStore{},
   792  		})
   793  		require.NoError(t, err)
   794  
   795  		err = s.CreateConnection(&connection.Record{
   796  			State: StateIDCompleted,
   797  		}, newPeerDID(t, k))
   798  		require.Error(t, err)
   799  		require.True(t, errors.Is(err, expected))
   800  	})
   801  
   802  	t.Run("wraps did.ConnectionStore.SaveDIDFromDoc error", func(t *testing.T) {
   803  		expected := errors.New("test")
   804  		s, err := New(&mockprovider.Provider{
   805  			KMSValue:                          &mockkms.KeyManager{},
   806  			KeyTypeValue:                      kms.ECDSAP384TypeIEEEP1363,
   807  			KeyAgreementTypeValue:             kms.X25519ECDHKWType,
   808  			StorageProviderValue:              mockstorage.NewMockStoreProvider(),
   809  			ProtocolStateStorageProviderValue: mockstorage.NewMockStoreProvider(),
   810  			VDRegistryValue:                   &mockvdr.MockVDRegistry{},
   811  			ServiceMap: map[string]interface{}{
   812  				mediator.Coordination: &mockroute.MockMediatorSvc{},
   813  			},
   814  			DIDConnectionStoreValue: &mockConnectionStore{
   815  				saveDIDFromDocErr: expected,
   816  			},
   817  		})
   818  		require.NoError(t, err)
   819  
   820  		err = s.CreateConnection(&connection.Record{
   821  			State: StateIDCompleted,
   822  		}, newPeerDID(t, k))
   823  		require.Error(t, err)
   824  		require.True(t, errors.Is(err, expected))
   825  	})
   826  
   827  	t.Run("wraps did.ConnectionStore.SaveDIDByResolving error", func(t *testing.T) {
   828  		expected := errors.New("test")
   829  		s, err := New(&mockprovider.Provider{
   830  			KMSValue:                          &mockkms.KeyManager{},
   831  			KeyTypeValue:                      kms.ED25519Type,
   832  			KeyAgreementTypeValue:             kms.X25519ECDHKWType,
   833  			StorageProviderValue:              mockstorage.NewMockStoreProvider(),
   834  			ProtocolStateStorageProviderValue: mockstorage.NewMockStoreProvider(),
   835  			VDRegistryValue:                   &mockvdr.MockVDRegistry{},
   836  			ServiceMap: map[string]interface{}{
   837  				mediator.Coordination: &mockroute.MockMediatorSvc{},
   838  			},
   839  			DIDConnectionStoreValue: &mockConnectionStore{
   840  				saveDIDByResolvingErr: expected,
   841  			},
   842  		})
   843  		require.NoError(t, err)
   844  
   845  		err = s.CreateConnection(&connection.Record{
   846  			State: StateIDCompleted,
   847  		}, newPeerDID(t, k))
   848  		require.Error(t, err)
   849  		require.True(t, errors.Is(err, expected))
   850  	})
   851  }
   852  
   853  type mockStore struct {
   854  	put    func(string, []byte, ...storage.Tag) error
   855  	get    func(string) ([]byte, error)
   856  	delete func(string) error
   857  }
   858  
   859  // Put stores the key and the record.
   860  func (m *mockStore) Put(k string, v []byte, tags ...storage.Tag) error {
   861  	return m.put(k, v, tags...)
   862  }
   863  
   864  // Get fetches the record based on key.
   865  func (m *mockStore) Get(k string) ([]byte, error) {
   866  	return m.get(k)
   867  }
   868  
   869  func (m *mockStore) GetTags(key string) ([]storage.Tag, error) {
   870  	panic("implement me")
   871  }
   872  
   873  func (m *mockStore) GetBulk(keys ...string) ([][]byte, error) {
   874  	panic("implement me")
   875  }
   876  
   877  func (m *mockStore) Query(expression string, options ...storage.QueryOption) (storage.Iterator, error) {
   878  	panic("implement me")
   879  }
   880  
   881  // Delete the record based on key.
   882  func (m *mockStore) Delete(k string) error {
   883  	return m.delete(k)
   884  }
   885  
   886  func (m *mockStore) Batch(operations []storage.Operation) error {
   887  	panic("implement me")
   888  }
   889  
   890  func (m *mockStore) Flush() error {
   891  	panic("implement me")
   892  }
   893  
   894  func (m *mockStore) Close() error {
   895  	panic("implement me")
   896  }
   897  
   898  func randomString() string {
   899  	u := uuid.New()
   900  	return u.String()
   901  }
   902  
   903  func TestEventsSuccess(t *testing.T) {
   904  	sp := mockstorage.NewMockStoreProvider()
   905  	k := newKMS(t, sp)
   906  	ctx := &context{
   907  		kms:              k,
   908  		keyType:          kms.ED25519Type,
   909  		keyAgreementType: kms.X25519ECDHKWType,
   910  	}
   911  
   912  	svc, err := New(&protocol.MockProvider{
   913  		ServiceMap: map[string]interface{}{
   914  			mediator.Coordination: &mockroute.MockMediatorSvc{},
   915  		},
   916  		CustomKMS:             k,
   917  		KeyTypeValue:          ctx.keyType,
   918  		KeyAgreementTypeValue: ctx.keyAgreementType,
   919  	})
   920  	require.NoError(t, err)
   921  
   922  	actionCh := make(chan service.DIDCommAction, 10)
   923  	err = svc.RegisterActionEvent(actionCh)
   924  	require.NoError(t, err)
   925  
   926  	go func() { service.AutoExecuteActionEvent(actionCh) }()
   927  
   928  	statusCh := make(chan service.StateMsg, 10)
   929  	err = svc.RegisterMsgEvent(statusCh)
   930  	require.NoError(t, err)
   931  
   932  	done := make(chan struct{})
   933  
   934  	go func() {
   935  		for e := range statusCh {
   936  			if e.Type == service.PostState && e.StateID == StateIDRequested {
   937  				done <- struct{}{}
   938  			}
   939  		}
   940  	}()
   941  
   942  	pubKey, _ := newSigningAndEncryptionDIDKeys(t, ctx)
   943  	id := randomString()
   944  	invite, err := json.Marshal(
   945  		&Invitation{
   946  			Type:          InvitationMsgType,
   947  			ID:            id,
   948  			Label:         "test",
   949  			RecipientKeys: []string{pubKey},
   950  		},
   951  	)
   952  	require.NoError(t, err)
   953  
   954  	// send invite
   955  	didMsg, err := service.ParseDIDCommMsgMap(invite)
   956  	require.NoError(t, err)
   957  
   958  	_, err = svc.HandleInbound(didMsg, service.EmptyDIDCommContext())
   959  	require.NoError(t, err)
   960  
   961  	select {
   962  	case <-done:
   963  	case <-time.After(5 * time.Second):
   964  		require.Fail(t, "tests are not validated")
   965  	}
   966  }
   967  
   968  func TestContinueWithPublicDID(t *testing.T) {
   969  	sp := mockstorage.NewMockStoreProvider()
   970  	k := newKMS(t, sp)
   971  	ctx := &context{
   972  		kms:              k,
   973  		keyType:          kms.ED25519Type,
   974  		keyAgreementType: kms.X25519ECDHKWType,
   975  	}
   976  	didDoc := mockdiddoc.GetMockDIDDoc(t, false)
   977  	svc, err := New(&protocol.MockProvider{
   978  		ServiceMap: map[string]interface{}{
   979  			mediator.Coordination: &mockroute.MockMediatorSvc{},
   980  		},
   981  		KeyTypeValue:          ctx.keyType,
   982  		KeyAgreementTypeValue: ctx.keyAgreementType,
   983  	})
   984  	require.NoError(t, err)
   985  
   986  	actionCh := make(chan service.DIDCommAction, 10)
   987  	err = svc.RegisterActionEvent(actionCh)
   988  	require.NoError(t, err)
   989  
   990  	go func() { continueWithPublicDID(actionCh, didDoc.ID) }()
   991  
   992  	pubKey, _ := newSigningAndEncryptionDIDKeys(t, ctx)
   993  	id := randomString()
   994  	invite, err := json.Marshal(
   995  		&Invitation{
   996  			Type:          InvitationMsgType,
   997  			ID:            id,
   998  			Label:         "test",
   999  			RecipientKeys: []string{pubKey},
  1000  		},
  1001  	)
  1002  	require.NoError(t, err)
  1003  
  1004  	// send invite
  1005  	didMsg, err := service.ParseDIDCommMsgMap(invite)
  1006  	require.NoError(t, err)
  1007  
  1008  	_, err = svc.HandleInbound(didMsg, service.EmptyDIDCommContext())
  1009  	require.NoError(t, err)
  1010  }
  1011  
  1012  func continueWithPublicDID(ch chan service.DIDCommAction, pubDID string) {
  1013  	for msg := range ch {
  1014  		msg.Continue(&testOptions{publicDID: pubDID})
  1015  	}
  1016  }
  1017  
  1018  type testOptions struct {
  1019  	publicDID         string
  1020  	label             string
  1021  	routerConnections []string
  1022  }
  1023  
  1024  func (to *testOptions) PublicDID() string {
  1025  	return to.publicDID
  1026  }
  1027  
  1028  func (to *testOptions) Label() string {
  1029  	return to.label
  1030  }
  1031  
  1032  func (to *testOptions) RouterConnections() []string {
  1033  	return to.routerConnections
  1034  }
  1035  
  1036  func TestEventsUserError(t *testing.T) {
  1037  	svc, err := New(&protocol.MockProvider{
  1038  		ServiceMap: map[string]interface{}{
  1039  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1040  		},
  1041  	})
  1042  	require.NoError(t, err)
  1043  
  1044  	actionCh := make(chan service.DIDCommAction, 10)
  1045  	err = svc.RegisterActionEvent(actionCh)
  1046  	require.NoError(t, err)
  1047  
  1048  	statusCh := make(chan service.StateMsg, 10)
  1049  	err = svc.RegisterMsgEvent(statusCh)
  1050  	require.NoError(t, err)
  1051  
  1052  	done := make(chan struct{})
  1053  
  1054  	go func() {
  1055  		for {
  1056  			select {
  1057  			case e := <-actionCh:
  1058  				e.Stop(errors.New("invalid id"))
  1059  			case e := <-statusCh:
  1060  				if e.Type == service.PostState && e.StateID == StateIDAbandoned {
  1061  					done <- struct{}{}
  1062  				}
  1063  			}
  1064  		}
  1065  	}()
  1066  
  1067  	id := randomString()
  1068  	connRec := &connection.Record{
  1069  		ConnectionID: randomString(), ThreadID: id,
  1070  		Namespace: findNamespace(RequestMsgType), State: (&null{}).Name(),
  1071  	}
  1072  
  1073  	err = svc.connectionRecorder.SaveConnectionRecordWithMappings(connRec)
  1074  	require.NoError(t, err)
  1075  
  1076  	_, err = svc.HandleInbound(
  1077  		generateRequestMsgPayload(t, &protocol.MockProvider{}, id, randomString()),
  1078  		service.EmptyDIDCommContext())
  1079  	require.NoError(t, err)
  1080  
  1081  	select {
  1082  	case <-done:
  1083  	case <-time.After(5 * time.Second):
  1084  		require.Fail(t, "tests are not validated")
  1085  	}
  1086  }
  1087  
  1088  func TestEventStoreError(t *testing.T) {
  1089  	svc, err := New(&protocol.MockProvider{
  1090  		ServiceMap: map[string]interface{}{
  1091  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1092  		},
  1093  	})
  1094  	require.NoError(t, err)
  1095  
  1096  	actionCh := make(chan service.DIDCommAction, 10)
  1097  	err = svc.RegisterActionEvent(actionCh)
  1098  	require.NoError(t, err)
  1099  
  1100  	go func() {
  1101  		for e := range actionCh {
  1102  			e.Continue = func(args interface{}) {
  1103  				svc.processCallback(&message{Msg: service.NewDIDCommMsgMap(struct{}{})})
  1104  			}
  1105  			e.Continue(&service.Empty{})
  1106  		}
  1107  	}()
  1108  
  1109  	_, err = svc.HandleInbound(
  1110  		generateRequestMsgPayload(t, &protocol.MockProvider{}, randomString(), randomString()),
  1111  		service.EmptyDIDCommContext())
  1112  	require.NoError(t, err)
  1113  }
  1114  
  1115  func TestEventProcessCallback(t *testing.T) {
  1116  	svc, err := New(&protocol.MockProvider{
  1117  		ServiceMap: map[string]interface{}{
  1118  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1119  		},
  1120  	})
  1121  	require.NoError(t, err)
  1122  
  1123  	msg := &message{
  1124  		ThreadID: threadIDValue,
  1125  		Msg:      service.NewDIDCommMsgMap(model.Ack{Type: AckMsgType}),
  1126  	}
  1127  
  1128  	err = svc.handleWithoutAction(msg)
  1129  	require.Error(t, err)
  1130  	require.Contains(t, err.Error(), "invalid state name: invalid state name ")
  1131  
  1132  	err = svc.abandon(msg.ThreadID, msg.Msg, nil)
  1133  	require.Error(t, err)
  1134  	require.Contains(t, err.Error(), "unable to update the state to abandoned")
  1135  }
  1136  
  1137  func validateState(t *testing.T, svc *Service, id, namespace, expected string) {
  1138  	nsThid, err := connection.CreateNamespaceKey(namespace, id)
  1139  	require.NoError(t, err)
  1140  	s, err := svc.currentState(nsThid)
  1141  	require.NoError(t, err)
  1142  	require.Equal(t, expected, s.Name())
  1143  }
  1144  
  1145  func TestServiceErrors(t *testing.T) {
  1146  	requestBytes, err := json.Marshal(
  1147  		&Request{
  1148  			Type:  ResponseMsgType,
  1149  			ID:    randomString(),
  1150  			Label: "test",
  1151  		},
  1152  	)
  1153  	require.NoError(t, err)
  1154  
  1155  	msg, err := service.ParseDIDCommMsgMap(requestBytes)
  1156  	require.NoError(t, err)
  1157  
  1158  	svc, err := New(&protocol.MockProvider{
  1159  		ServiceMap: map[string]interface{}{
  1160  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1161  		},
  1162  	})
  1163  	require.NoError(t, err)
  1164  
  1165  	actionCh := make(chan service.DIDCommAction, 10)
  1166  	err = svc.RegisterActionEvent(actionCh)
  1167  	require.NoError(t, err)
  1168  
  1169  	// fetch current state error
  1170  	mockStore := &mockStore{get: func(s string) (bytes []byte, e error) {
  1171  		return nil, errors.New("error")
  1172  	}}
  1173  
  1174  	prov := &protocol.MockProvider{
  1175  		ProtocolStateStoreProvider: mockstorage.NewCustomMockStoreProvider(
  1176  			mockStore,
  1177  		),
  1178  		ServiceMap: map[string]interface{}{
  1179  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1180  		},
  1181  	}
  1182  	svc, err = New(prov)
  1183  	require.NoError(t, err)
  1184  
  1185  	payload := generateRequestMsgPayload(t, prov, randomString(), "")
  1186  	_, err = svc.HandleInbound(payload, service.EmptyDIDCommContext())
  1187  	require.Error(t, err)
  1188  	require.Contains(t, err.Error(), "cannot fetch state from store")
  1189  
  1190  	svc, err = New(&protocol.MockProvider{
  1191  		ServiceMap: map[string]interface{}{
  1192  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1193  		},
  1194  	})
  1195  	require.NoError(t, err)
  1196  
  1197  	// invalid message type
  1198  	msg["@type"] = "invalid"
  1199  	svc.connectionRecorder, err = connection.NewRecorder(&protocol.MockProvider{})
  1200  	require.NoError(t, err)
  1201  
  1202  	_, err = svc.HandleInbound(msg, service.EmptyDIDCommContext())
  1203  	require.Error(t, err)
  1204  	require.Contains(t, err.Error(), "unrecognized msgType: invalid")
  1205  
  1206  	// test handle - invalid state name
  1207  	msg["@type"] = ResponseMsgType
  1208  	m := &message{Msg: msg, ThreadID: randomString()}
  1209  	err = svc.handleWithoutAction(m)
  1210  	require.Error(t, err)
  1211  	require.Contains(t, err.Error(), "invalid state name:")
  1212  
  1213  	// invalid state name
  1214  	m.NextStateName = StateIDInvited
  1215  	m.ConnRecord = &connection.Record{ConnectionID: "abc"}
  1216  	err = svc.handleWithoutAction(m)
  1217  	require.Error(t, err)
  1218  	require.Contains(t, err.Error(), "failed to execute state 'invited':")
  1219  }
  1220  
  1221  func TestHandleOutbound(t *testing.T) {
  1222  	svc, err := New(&protocol.MockProvider{
  1223  		ServiceMap: map[string]interface{}{
  1224  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1225  		},
  1226  	})
  1227  	require.NoError(t, err)
  1228  
  1229  	_, err = svc.HandleOutbound(service.DIDCommMsgMap{}, "", "")
  1230  	require.Error(t, err)
  1231  	require.Contains(t, err.Error(), "not implemented")
  1232  }
  1233  
  1234  func TestConnectionRecord(t *testing.T) {
  1235  	svc, err := New(&protocol.MockProvider{
  1236  		ServiceMap: map[string]interface{}{
  1237  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1238  		},
  1239  	})
  1240  	require.NoError(t, err)
  1241  
  1242  	conn, err := svc.connectionRecord(generateRequestMsgPayload(t, &protocol.MockProvider{},
  1243  		randomString(), randomString()))
  1244  	require.NoError(t, err)
  1245  	require.NotNil(t, conn)
  1246  
  1247  	// invalid type
  1248  	requestBytes, err := json.Marshal(&Request{
  1249  		Type: "invalid-type",
  1250  	})
  1251  	require.NoError(t, err)
  1252  	msg, err := service.ParseDIDCommMsgMap(requestBytes)
  1253  	require.NoError(t, err)
  1254  
  1255  	_, err = svc.connectionRecord(msg)
  1256  	require.Error(t, err)
  1257  	require.Contains(t, err.Error(), "invalid message type")
  1258  }
  1259  
  1260  func TestInvitationRecord(t *testing.T) {
  1261  	sp := mockstorage.NewMockStoreProvider()
  1262  	k := newKMS(t, sp)
  1263  	ctx := &context{
  1264  		kms:              k,
  1265  		keyType:          kms.ED25519Type,
  1266  		keyAgreementType: kms.X25519ECDHKWType,
  1267  	}
  1268  	svc, err := New(&protocol.MockProvider{
  1269  		ServiceMap: map[string]interface{}{
  1270  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1271  		},
  1272  		KeyTypeValue:          ctx.keyType,
  1273  		KeyAgreementTypeValue: ctx.keyAgreementType,
  1274  	})
  1275  	require.NoError(t, err)
  1276  
  1277  	verPubKey, _ := newSigningAndEncryptionDIDKeys(t, ctx)
  1278  	invitationBytes, err := json.Marshal(&Invitation{
  1279  		Type:          InvitationMsgType,
  1280  		ID:            "id",
  1281  		RecipientKeys: []string{verPubKey},
  1282  	})
  1283  	require.NoError(t, err)
  1284  
  1285  	msg, err := service.ParseDIDCommMsgMap(invitationBytes)
  1286  	require.NoError(t, err)
  1287  
  1288  	conn, err := svc.invitationMsgRecord(msg)
  1289  	require.NoError(t, err)
  1290  	require.NotNil(t, conn)
  1291  
  1292  	// invalid thread id
  1293  	invitationBytes, err = json.Marshal(&Invitation{
  1294  		Type: "invalid-type",
  1295  	})
  1296  	require.NoError(t, err)
  1297  	msg, err = service.ParseDIDCommMsgMap(invitationBytes)
  1298  	require.NoError(t, err)
  1299  
  1300  	_, err = svc.invitationMsgRecord(msg)
  1301  	require.Error(t, err)
  1302  	require.Contains(t, err.Error(), "threadID not found")
  1303  
  1304  	// db error
  1305  	svc, err = New(&protocol.MockProvider{
  1306  		ProtocolStateStoreProvider: mockstorage.NewCustomMockStoreProvider(&mockstorage.MockStore{
  1307  			Store: make(map[string]mockstorage.DBEntry), ErrPut: errors.New("db error"),
  1308  		}),
  1309  		ServiceMap: map[string]interface{}{
  1310  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1311  		},
  1312  	})
  1313  	require.NotNil(t, svc.connectionRecorder)
  1314  	require.NoError(t, err)
  1315  
  1316  	invitationBytes, err = json.Marshal(&Invitation{
  1317  		Type:          InvitationMsgType,
  1318  		ID:            "id",
  1319  		RecipientKeys: []string{verPubKey},
  1320  	})
  1321  	require.NoError(t, err)
  1322  
  1323  	msg, err = service.ParseDIDCommMsgMap(invitationBytes)
  1324  	require.NoError(t, err)
  1325  
  1326  	_, err = svc.invitationMsgRecord(msg)
  1327  	require.Error(t, err)
  1328  	require.Contains(t, err.Error(), "save connection record")
  1329  }
  1330  
  1331  func Test_getRequestConnection(t *testing.T) {
  1332  	store := mockstorage.NewMockStoreProvider()
  1333  	k := newKMS(t, store)
  1334  
  1335  	t.Run("success - did_doc~attach present", func(t *testing.T) {
  1336  		testDoc := newPeerDID(t, k)
  1337  		docBytes, err := testDoc.MarshalJSON()
  1338  		require.NoError(t, err)
  1339  
  1340  		attachment := decorator.Attachment{
  1341  			Data: decorator.AttachmentData{
  1342  				Base64: base64.StdEncoding.EncodeToString(docBytes),
  1343  			},
  1344  		}
  1345  
  1346  		r := Request{DID: "test", DocAttach: &attachment}
  1347  
  1348  		conn, err := getRequestConnection(&r)
  1349  		require.NoError(t, err)
  1350  		require.Equal(t, "test", conn.DID)
  1351  	})
  1352  
  1353  	t.Run("failure - no connection or did_doc~attach", func(t *testing.T) {
  1354  		_, err := getRequestConnection(&Request{DID: "test"})
  1355  		require.Error(t, err)
  1356  		require.Contains(t, err.Error(), "missing did_doc~attach")
  1357  	})
  1358  
  1359  	t.Run("failure - did_doc~attach not valid base64", func(t *testing.T) {
  1360  		_, err := getRequestConnection(&Request{DID: "test", DocAttach: &decorator.Attachment{
  1361  			Data: decorator.AttachmentData{
  1362  				Base64: "abc %$#@abc test test bad data ^",
  1363  			},
  1364  		}})
  1365  		require.Error(t, err)
  1366  		require.Contains(t, err.Error(), "failed to parse base64 attachment data")
  1367  	})
  1368  
  1369  	t.Run("failure - did_doc~attach not valid did doc", func(t *testing.T) {
  1370  		_, err := getRequestConnection(&Request{DID: "test", DocAttach: &decorator.Attachment{
  1371  			Data: decorator.AttachmentData{
  1372  				Base64: base64.StdEncoding.EncodeToString([]byte("this is not a valid did doc")),
  1373  			},
  1374  		}})
  1375  		require.Error(t, err)
  1376  		require.Contains(t, err.Error(), "failed to parse did document")
  1377  	})
  1378  
  1379  	t.Run("test pad", func(t *testing.T) {
  1380  		in := []string{
  1381  			"abcdabcdabcdabcda",
  1382  			"abcdabcdabcdabcdab",
  1383  			"abcdabcdabcdabcdabc",
  1384  			"abcdabcdabcdabcdabcd",
  1385  			"abcdabcdabcdabcdabcda",
  1386  			"abcdabcdabcdabcdabcdab",
  1387  		}
  1388  
  1389  		out := []string{
  1390  			"abcdabcdabcdabcda",
  1391  			"abcdabcdabcdabcdab==",
  1392  			"abcdabcdabcdabcdabc=",
  1393  			"abcdabcdabcdabcdabcd",
  1394  			"abcdabcdabcdabcdabcda",
  1395  			"abcdabcdabcdabcdabcdab==",
  1396  		}
  1397  
  1398  		for i, input := range in {
  1399  			require.Equal(t, out[i], pad(input))
  1400  		}
  1401  	})
  1402  }
  1403  
  1404  func TestRequestRecord(t *testing.T) {
  1405  	t.Run("returns connection record", func(t *testing.T) {
  1406  		svc, err := New(&protocol.MockProvider{
  1407  			ServiceMap: map[string]interface{}{
  1408  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1409  			},
  1410  		})
  1411  		require.NoError(t, err)
  1412  
  1413  		didcommMsg := generateRequestMsgPayload(t, &protocol.MockProvider{}, randomString(), uuid.New().String())
  1414  		require.NotEmpty(t, didcommMsg.ParentThreadID())
  1415  		conn, err := svc.requestMsgRecord(didcommMsg)
  1416  		require.NoError(t, err)
  1417  		require.NotNil(t, conn)
  1418  		require.Equal(t, didcommMsg.ParentThreadID(), conn.InvitationID)
  1419  	})
  1420  
  1421  	t.Run("returns connection record from request without connection", func(t *testing.T) {
  1422  		svc, err := New(&protocol.MockProvider{
  1423  			ServiceMap: map[string]interface{}{
  1424  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1425  			},
  1426  		})
  1427  		require.NoError(t, err)
  1428  
  1429  		didcommMsg := generateRequestMsgPayload(t, &protocol.MockProvider{}, randomString(), uuid.New().String())
  1430  		require.NotEmpty(t, didcommMsg.ParentThreadID())
  1431  		delete(didcommMsg, "connection")
  1432  		didcommMsg["did"] = "did:test:abc"
  1433  
  1434  		conn, err := svc.requestMsgRecord(didcommMsg)
  1435  		require.NoError(t, err)
  1436  		require.NotNil(t, conn)
  1437  		require.Equal(t, didcommMsg.ParentThreadID(), conn.InvitationID)
  1438  		require.Equal(t, "did:test:abc", conn.TheirDID)
  1439  	})
  1440  
  1441  	t.Run("fails on db error", func(t *testing.T) {
  1442  		svc, err := New(&protocol.MockProvider{
  1443  			ProtocolStateStoreProvider: mockstorage.NewCustomMockStoreProvider(
  1444  				&mockstorage.MockStore{Store: make(map[string]mockstorage.DBEntry), ErrPut: errors.New("db error")},
  1445  			),
  1446  			ServiceMap: map[string]interface{}{
  1447  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1448  			},
  1449  		})
  1450  		require.NotNil(t, svc.connectionRecorder)
  1451  		require.NoError(t, err)
  1452  
  1453  		_, err = svc.requestMsgRecord(generateRequestMsgPayload(t, &protocol.MockProvider{},
  1454  			randomString(), uuid.New().String()))
  1455  		require.Error(t, err)
  1456  		require.Contains(t, err.Error(), "save connection record")
  1457  	})
  1458  
  1459  	t.Run("fails if parent thread ID is missing", func(t *testing.T) {
  1460  		svc, err := New(&protocol.MockProvider{
  1461  			ServiceMap: map[string]interface{}{
  1462  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1463  			},
  1464  		})
  1465  		require.NoError(t, err)
  1466  
  1467  		parentThreadID := ""
  1468  		didcommMsg := generateRequestMsgPayload(t, &protocol.MockProvider{}, randomString(), parentThreadID)
  1469  		require.Empty(t, didcommMsg.ParentThreadID())
  1470  		_, err = svc.requestMsgRecord(didcommMsg)
  1471  		require.Error(t, err)
  1472  	})
  1473  }
  1474  
  1475  func TestAcceptExchangeRequest(t *testing.T) {
  1476  	sp := mockstorage.NewMockStoreProvider()
  1477  	k := newKMS(t, sp)
  1478  	ctx := &context{
  1479  		kms:              k,
  1480  		keyType:          kms.ED25519Type,
  1481  		keyAgreementType: kms.X25519ECDHKWType,
  1482  	}
  1483  
  1484  	svc, err := New(&protocol.MockProvider{
  1485  		StoreProvider: sp,
  1486  		ServiceMap: map[string]interface{}{
  1487  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1488  		},
  1489  		CustomKMS:             k,
  1490  		KeyTypeValue:          ctx.keyType,
  1491  		KeyAgreementTypeValue: ctx.keyAgreementType,
  1492  	})
  1493  	require.NoError(t, err)
  1494  
  1495  	actionCh := make(chan service.DIDCommAction, 10)
  1496  	err = svc.RegisterActionEvent(actionCh)
  1497  	require.NoError(t, err)
  1498  
  1499  	verPubKey, _ := newSigningAndEncryptionDIDKeys(t, ctx)
  1500  	invitation := &Invitation{
  1501  		Type:            InvitationMsgType,
  1502  		ID:              randomString(),
  1503  		Label:           "Bob",
  1504  		RecipientKeys:   []string{verPubKey},
  1505  		ServiceEndpoint: "http://alice.agent.example.com:8081",
  1506  	}
  1507  
  1508  	err = svc.connectionRecorder.SaveInvitation(invitation.ID, invitation)
  1509  	require.NoError(t, err)
  1510  
  1511  	go func() {
  1512  		for e := range actionCh {
  1513  			prop, ok := e.Properties.(event)
  1514  			require.True(t, ok, "Failed to cast the event properties to service.Event")
  1515  			require.NoError(t, svc.AcceptExchangeRequest(prop.ConnectionID(), "", "", nil))
  1516  		}
  1517  	}()
  1518  
  1519  	statusCh := make(chan service.StateMsg, 10)
  1520  	err = svc.RegisterMsgEvent(statusCh)
  1521  	require.NoError(t, err)
  1522  
  1523  	done := make(chan struct{})
  1524  
  1525  	go func() {
  1526  		for e := range statusCh {
  1527  			if e.Type == service.PostState && e.StateID == StateIDResponded {
  1528  				done <- struct{}{}
  1529  			}
  1530  		}
  1531  	}()
  1532  
  1533  	_, err = svc.HandleInbound(generateRequestMsgPayload(t, &protocol.MockProvider{
  1534  		StoreProvider: mockstorage.NewMockStoreProvider(),
  1535  	}, randomString(), invitation.ID), service.EmptyDIDCommContext())
  1536  	require.NoError(t, err)
  1537  
  1538  	select {
  1539  	case <-done:
  1540  	case <-time.After(5 * time.Second):
  1541  		require.Fail(t, "tests are not validated")
  1542  	}
  1543  }
  1544  
  1545  func TestAcceptExchangeRequestWithPublicDID(t *testing.T) {
  1546  	sp := mockstorage.NewMockStoreProvider()
  1547  	k := newKMS(t, sp)
  1548  	ctx := &context{
  1549  		kms:              k,
  1550  		keyType:          kms.ED25519Type,
  1551  		keyAgreementType: kms.X25519ECDHKWType,
  1552  	}
  1553  	svc, err := New(&protocol.MockProvider{
  1554  		StoreProvider: sp,
  1555  		ServiceMap: map[string]interface{}{
  1556  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  1557  		},
  1558  		KeyTypeValue:          ctx.keyType,
  1559  		KeyAgreementTypeValue: ctx.keyAgreementType,
  1560  	})
  1561  	require.NoError(t, err)
  1562  
  1563  	const publicDIDMethod = "sidetree"
  1564  	publicDID := fmt.Sprintf("did:%s:123456", publicDIDMethod)
  1565  	doc, err := svc.ctx.vdRegistry.Create(publicDIDMethod, nil)
  1566  	require.NoError(t, err)
  1567  
  1568  	svc.ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: doc.DIDDocument}
  1569  
  1570  	actionCh := make(chan service.DIDCommAction, 10)
  1571  	err = svc.RegisterActionEvent(actionCh)
  1572  	require.NoError(t, err)
  1573  
  1574  	verPubKey, _ := newSigningAndEncryptionDIDKeys(t, ctx)
  1575  	invitation := &Invitation{
  1576  		Type:            InvitationMsgType,
  1577  		ID:              randomString(),
  1578  		Label:           "Bob",
  1579  		RecipientKeys:   []string{verPubKey},
  1580  		ServiceEndpoint: "http://alice.agent.example.com:8081",
  1581  	}
  1582  
  1583  	err = svc.connectionRecorder.SaveInvitation(invitation.ID, invitation)
  1584  	require.NoError(t, err)
  1585  
  1586  	go func() {
  1587  		for e := range actionCh {
  1588  			prop, ok := e.Properties.(event)
  1589  			require.True(t, ok, "Failed to cast the event properties to service.Event")
  1590  			require.NoError(t, svc.AcceptExchangeRequest(prop.ConnectionID(), publicDID, "sample-label", nil))
  1591  		}
  1592  	}()
  1593  
  1594  	statusCh := make(chan service.StateMsg, 10)
  1595  	err = svc.RegisterMsgEvent(statusCh)
  1596  	require.NoError(t, err)
  1597  
  1598  	done := make(chan struct{})
  1599  
  1600  	go func() {
  1601  		for e := range statusCh {
  1602  			if e.Type == service.PostState && e.StateID == StateIDResponded {
  1603  				done <- struct{}{}
  1604  			}
  1605  		}
  1606  	}()
  1607  
  1608  	_, err = svc.HandleInbound(generateRequestMsgPayload(t, &protocol.MockProvider{
  1609  		StoreProvider: mockstorage.NewMockStoreProvider(),
  1610  	}, randomString(), invitation.ID), service.EmptyDIDCommContext())
  1611  	require.NoError(t, err)
  1612  
  1613  	select {
  1614  	case <-done:
  1615  	case <-time.After(5 * time.Second):
  1616  		require.Fail(t, "tests are not validated")
  1617  	}
  1618  }
  1619  
  1620  func TestAcceptInvitation(t *testing.T) {
  1621  	t.Run("accept invitation - success", func(t *testing.T) {
  1622  		sp := mockstorage.NewMockStoreProvider()
  1623  		k := newKMS(t, sp)
  1624  		ctx := &context{
  1625  			kms:              k,
  1626  			keyType:          kms.ED25519Type,
  1627  			keyAgreementType: kms.X25519ECDHKWType,
  1628  		}
  1629  		svc, err := New(&protocol.MockProvider{
  1630  			StoreProvider: sp,
  1631  			ServiceMap: map[string]interface{}{
  1632  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1633  			},
  1634  			CustomKMS:             k,
  1635  			KeyTypeValue:          ctx.keyType,
  1636  			KeyAgreementTypeValue: ctx.keyAgreementType,
  1637  		})
  1638  		require.NoError(t, err)
  1639  
  1640  		actionCh := make(chan service.DIDCommAction, 10)
  1641  		err = svc.RegisterActionEvent(actionCh)
  1642  		require.NoError(t, err)
  1643  
  1644  		go func() {
  1645  			for e := range actionCh {
  1646  				_, ok := e.Properties.(event)
  1647  				require.True(t, ok, "Failed to cast the event properties to service.Event")
  1648  
  1649  				// ignore action event
  1650  			}
  1651  		}()
  1652  
  1653  		statusCh := make(chan service.StateMsg, 10)
  1654  		err = svc.RegisterMsgEvent(statusCh)
  1655  		require.NoError(t, err)
  1656  
  1657  		done := make(chan struct{})
  1658  
  1659  		go func() {
  1660  			for e := range statusCh {
  1661  				prop, ok := e.Properties.(event)
  1662  				if !ok {
  1663  					require.Fail(t, "Failed to cast the event properties to service.Event")
  1664  				}
  1665  
  1666  				if e.Type == service.PostState && e.StateID == StateIDInvited {
  1667  					require.NoError(t, svc.AcceptInvitation(prop.ConnectionID(), "", "", nil))
  1668  				}
  1669  
  1670  				if e.Type == service.PostState && e.StateID == StateIDRequested {
  1671  					done <- struct{}{}
  1672  				}
  1673  			}
  1674  		}()
  1675  		verPubKey, _ := newSigningAndEncryptionDIDKeys(t, ctx)
  1676  		invitationBytes, err := json.Marshal(&Invitation{
  1677  			Type:          InvitationMsgType,
  1678  			ID:            generateRandomID(),
  1679  			RecipientKeys: []string{verPubKey},
  1680  		})
  1681  		require.NoError(t, err)
  1682  
  1683  		didMsg, err := service.ParseDIDCommMsgMap(invitationBytes)
  1684  		require.NoError(t, err)
  1685  
  1686  		_, err = svc.HandleInbound(didMsg, service.EmptyDIDCommContext())
  1687  		require.NoError(t, err)
  1688  
  1689  		select {
  1690  		case <-done:
  1691  		case <-time.After(5 * time.Second):
  1692  			require.Fail(t, "tests are not validated")
  1693  		}
  1694  	})
  1695  
  1696  	t.Run("accept invitation - error", func(t *testing.T) {
  1697  		svc, err := New(&protocol.MockProvider{
  1698  			ServiceMap: map[string]interface{}{
  1699  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1700  			},
  1701  		})
  1702  		require.NoError(t, err)
  1703  
  1704  		err = svc.AcceptInvitation(generateRandomID(), "", "", nil)
  1705  		require.Error(t, err)
  1706  		require.Contains(t, err.Error(), "accept exchange invitation : get protocol state data : data not found")
  1707  	})
  1708  
  1709  	t.Run("accept invitation - state error", func(t *testing.T) {
  1710  		svc, err := New(&protocol.MockProvider{
  1711  			ServiceMap: map[string]interface{}{
  1712  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1713  			},
  1714  		})
  1715  		require.NoError(t, err)
  1716  
  1717  		id := generateRandomID()
  1718  		connRecord := &connection.Record{
  1719  			ConnectionID: id,
  1720  			State:        StateIDRequested,
  1721  		}
  1722  		err = svc.connectionRecorder.SaveConnectionRecord(connRecord)
  1723  		require.NoError(t, err)
  1724  
  1725  		err = svc.storeEventProtocolStateData(&message{ConnRecord: connRecord})
  1726  		require.NoError(t, err)
  1727  
  1728  		err = svc.AcceptInvitation(id, "", "", nil)
  1729  		require.Error(t, err)
  1730  		require.Contains(t, err.Error(), "current state (requested) is different from expected state (invited)")
  1731  	})
  1732  
  1733  	t.Run("accept invitation - no connection record error", func(t *testing.T) {
  1734  		svc, err := New(&protocol.MockProvider{
  1735  			ServiceMap: map[string]interface{}{
  1736  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1737  			},
  1738  		})
  1739  		require.NoError(t, err)
  1740  
  1741  		id := generateRandomID()
  1742  		connRecord := &connection.Record{
  1743  			ConnectionID: id,
  1744  			State:        StateIDRequested,
  1745  		}
  1746  
  1747  		err = svc.storeEventProtocolStateData(&message{ConnRecord: connRecord})
  1748  		require.NoError(t, err)
  1749  
  1750  		err = svc.AcceptInvitation(id, "", "", nil)
  1751  		require.Error(t, err)
  1752  		require.Contains(t, err.Error(), "accept exchange invitation : data not found")
  1753  	})
  1754  }
  1755  
  1756  func TestAcceptInvitationWithPublicDID(t *testing.T) {
  1757  	t.Run("accept invitation with public DID - success", func(t *testing.T) {
  1758  		sp := mockstorage.NewMockStoreProvider()
  1759  		k := newKMS(t, sp)
  1760  		ctx := &context{
  1761  			kms:              k,
  1762  			keyType:          kms.ED25519Type,
  1763  			keyAgreementType: kms.X25519ECDHKWType,
  1764  		}
  1765  		svc, err := New(&protocol.MockProvider{
  1766  			StoreProvider: sp,
  1767  			ServiceMap: map[string]interface{}{
  1768  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1769  			},
  1770  			KeyTypeValue:          ctx.keyType,
  1771  			KeyAgreementTypeValue: ctx.keyAgreementType,
  1772  		})
  1773  		require.NoError(t, err)
  1774  
  1775  		const publicDIDMethod = "sidetree"
  1776  		publicDID := fmt.Sprintf("did:%s:123456", publicDIDMethod)
  1777  		doc, err := svc.ctx.vdRegistry.Create(publicDIDMethod, nil)
  1778  		require.NoError(t, err)
  1779  		svc.ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: doc.DIDDocument}
  1780  
  1781  		actionCh := make(chan service.DIDCommAction, 10)
  1782  		err = svc.RegisterActionEvent(actionCh)
  1783  		require.NoError(t, err)
  1784  
  1785  		go func() {
  1786  			for e := range actionCh {
  1787  				_, ok := e.Properties.(event)
  1788  				require.True(t, ok, "Failed to cast the event properties to service.Event")
  1789  
  1790  				// ignore action event
  1791  			}
  1792  		}()
  1793  
  1794  		statusCh := make(chan service.StateMsg, 10)
  1795  		err = svc.RegisterMsgEvent(statusCh)
  1796  		require.NoError(t, err)
  1797  
  1798  		done := make(chan struct{})
  1799  
  1800  		go func() {
  1801  			for e := range statusCh {
  1802  				prop, ok := e.Properties.(event)
  1803  				if !ok {
  1804  					require.Fail(t, "Failed to cast the event properties to service.Event")
  1805  				}
  1806  
  1807  				if e.Type == service.PostState && e.StateID == StateIDInvited {
  1808  					require.NoError(t, svc.AcceptInvitation(prop.ConnectionID(), publicDID, "sample-label", nil))
  1809  				}
  1810  
  1811  				if e.Type == service.PostState && e.StateID == StateIDRequested {
  1812  					done <- struct{}{}
  1813  				}
  1814  			}
  1815  		}()
  1816  
  1817  		verPubKey, _ := newSigningAndEncryptionDIDKeys(t, ctx)
  1818  		invitationBytes, err := json.Marshal(&Invitation{
  1819  			Type:          InvitationMsgType,
  1820  			ID:            generateRandomID(),
  1821  			RecipientKeys: []string{verPubKey},
  1822  		})
  1823  		require.NoError(t, err)
  1824  
  1825  		didMsg, err := service.ParseDIDCommMsgMap(invitationBytes)
  1826  		require.NoError(t, err)
  1827  
  1828  		_, err = svc.HandleInbound(didMsg, service.EmptyDIDCommContext())
  1829  		require.NoError(t, err)
  1830  
  1831  		select {
  1832  		case <-done:
  1833  		case <-time.After(5 * time.Second):
  1834  			require.Fail(t, "tests are not validated")
  1835  		}
  1836  	})
  1837  
  1838  	t.Run("accept invitation - error", func(t *testing.T) {
  1839  		svc, err := New(&protocol.MockProvider{
  1840  			ServiceMap: map[string]interface{}{
  1841  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1842  			},
  1843  		})
  1844  		require.NoError(t, err)
  1845  
  1846  		err = svc.AcceptInvitation(generateRandomID(), "sample-public-did", "sample-label", nil)
  1847  		require.Error(t, err)
  1848  		require.Contains(t, err.Error(), "accept exchange invitation : get protocol state data : data not found")
  1849  	})
  1850  
  1851  	t.Run("accept invitation - state error", func(t *testing.T) {
  1852  		svc, err := New(&protocol.MockProvider{
  1853  			ServiceMap: map[string]interface{}{
  1854  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1855  			},
  1856  		})
  1857  		require.NoError(t, err)
  1858  
  1859  		id := generateRandomID()
  1860  		connRecord := &connection.Record{
  1861  			ConnectionID: id,
  1862  			State:        StateIDRequested,
  1863  		}
  1864  		err = svc.connectionRecorder.SaveConnectionRecord(connRecord)
  1865  		require.NoError(t, err)
  1866  
  1867  		err = svc.storeEventProtocolStateData(&message{ConnRecord: connRecord})
  1868  		require.NoError(t, err)
  1869  
  1870  		err = svc.AcceptInvitation(id, "sample-public-did", "sample-label", nil)
  1871  		require.Error(t, err)
  1872  		require.Contains(t, err.Error(), "current state (requested) is different from expected state (invited)")
  1873  	})
  1874  
  1875  	t.Run("accept invitation - no connection record error", func(t *testing.T) {
  1876  		svc, err := New(&protocol.MockProvider{
  1877  			ServiceMap: map[string]interface{}{
  1878  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1879  			},
  1880  		})
  1881  		require.NoError(t, err)
  1882  
  1883  		id := generateRandomID()
  1884  		connRecord := &connection.Record{
  1885  			ConnectionID: id,
  1886  			State:        StateIDRequested,
  1887  		}
  1888  
  1889  		err = svc.storeEventProtocolStateData(&message{ConnRecord: connRecord})
  1890  		require.NoError(t, err)
  1891  
  1892  		err = svc.AcceptInvitation(id, "sample-public-did", "sample-label", nil)
  1893  		require.Error(t, err)
  1894  		require.Contains(t, err.Error(), "accept exchange invitation : data not found")
  1895  	})
  1896  }
  1897  
  1898  func TestEventProtocolStateData(t *testing.T) {
  1899  	t.Run("event protocol state data - success", func(t *testing.T) {
  1900  		svc, err := New(&protocol.MockProvider{
  1901  			ServiceMap: map[string]interface{}{
  1902  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1903  			},
  1904  		})
  1905  		require.NoError(t, err)
  1906  
  1907  		connID := generateRandomID()
  1908  
  1909  		msg := &message{
  1910  			ConnRecord: &connection.Record{ConnectionID: connID},
  1911  		}
  1912  		err = svc.storeEventProtocolStateData(msg)
  1913  		require.NoError(t, err)
  1914  
  1915  		retrievedMsg, err := svc.getEventProtocolStateData(connID)
  1916  		require.NoError(t, err)
  1917  		require.Equal(t, msg, retrievedMsg)
  1918  	})
  1919  
  1920  	t.Run("event protocol state data - data not found", func(t *testing.T) {
  1921  		svc, err := New(&protocol.MockProvider{
  1922  			ServiceMap: map[string]interface{}{
  1923  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1924  			},
  1925  		})
  1926  		require.NoError(t, err)
  1927  
  1928  		err = svc.AcceptExchangeRequest(generateRandomID(), "", "", nil)
  1929  		require.Error(t, err)
  1930  		require.Contains(t, err.Error(), "accept exchange request : get protocol state data : data not found")
  1931  
  1932  		err = svc.AcceptExchangeRequest(generateRandomID(), "sample-public-did", "sample-label", nil)
  1933  		require.Error(t, err)
  1934  		require.Contains(t, err.Error(), "accept exchange request : get protocol state data : data not found")
  1935  	})
  1936  
  1937  	t.Run("event protocol state data - invalid data", func(t *testing.T) {
  1938  		svc, err := New(&protocol.MockProvider{
  1939  			ServiceMap: map[string]interface{}{
  1940  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1941  			},
  1942  		})
  1943  		require.NoError(t, err)
  1944  
  1945  		connID := generateRandomID()
  1946  
  1947  		err = svc.connectionRecorder.SaveEvent(connID, []byte("invalid data"))
  1948  		require.NoError(t, err)
  1949  
  1950  		_, err = svc.getEventProtocolStateData(connID)
  1951  		require.Error(t, err)
  1952  		require.Contains(t, err.Error(), "get protocol state data : invalid character")
  1953  	})
  1954  }
  1955  
  1956  func TestNextState(t *testing.T) {
  1957  	t.Run("empty thread ID", func(t *testing.T) {
  1958  		svc, err := New(&protocol.MockProvider{
  1959  			ServiceMap: map[string]interface{}{
  1960  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1961  			},
  1962  		})
  1963  		require.NoError(t, err)
  1964  
  1965  		_, err = svc.nextState(RequestMsgType, "")
  1966  		require.EqualError(t, err, "unable to compute hash, empty bytes")
  1967  	})
  1968  
  1969  	t.Run("valid inputs", func(t *testing.T) {
  1970  		svc, err := New(&protocol.MockProvider{
  1971  			ServiceMap: map[string]interface{}{
  1972  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1973  			},
  1974  		})
  1975  		require.NoError(t, err)
  1976  
  1977  		s, errState := svc.nextState(RequestMsgType, generateRandomID())
  1978  		require.NoError(t, errState)
  1979  		require.Equal(t, StateIDRequested, s.Name())
  1980  	})
  1981  }
  1982  
  1983  func TestFetchConnectionRecord(t *testing.T) {
  1984  	t.Run("fetch connection record - invalid payload", func(t *testing.T) {
  1985  		svc, err := New(&protocol.MockProvider{
  1986  			ServiceMap: map[string]interface{}{
  1987  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  1988  			},
  1989  		})
  1990  		require.NoError(t, err)
  1991  
  1992  		_, err = svc.fetchConnectionRecord("", service.DIDCommMsgMap{"~thread": map[int]int{1: 1}})
  1993  		require.Contains(t, fmt.Sprintf("%v", err), `'~thread' needs a map with string keys`)
  1994  	})
  1995  
  1996  	t.Run("fetch connection record - no thread id", func(t *testing.T) {
  1997  		svc, err := New(&protocol.MockProvider{
  1998  			ServiceMap: map[string]interface{}{
  1999  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  2000  			},
  2001  		})
  2002  		require.NoError(t, err)
  2003  
  2004  		_, err = svc.fetchConnectionRecord(theirNSPrefix, toDIDCommMsg(t, &Request{
  2005  			Type: ResponseMsgType,
  2006  			ID:   generateRandomID(),
  2007  		}))
  2008  		require.Error(t, err)
  2009  		require.Contains(t, err.Error(), "unable to compute hash, empty bytes")
  2010  	})
  2011  
  2012  	t.Run("fetch connection record - valid input", func(t *testing.T) {
  2013  		svc, err := New(&protocol.MockProvider{
  2014  			ServiceMap: map[string]interface{}{
  2015  				mediator.Coordination: &mockroute.MockMediatorSvc{},
  2016  			},
  2017  		})
  2018  		require.NoError(t, err)
  2019  
  2020  		_, err = svc.fetchConnectionRecord(theirNSPrefix, toDIDCommMsg(t, &Response{
  2021  			Type:   ResponseMsgType,
  2022  			ID:     generateRandomID(),
  2023  			Thread: &decorator.Thread{ID: generateRandomID()},
  2024  		}))
  2025  		require.Error(t, err)
  2026  		require.Contains(t, err.Error(), "get connectionID by namespaced threadID: data not found")
  2027  	})
  2028  }
  2029  
  2030  func generateRequestMsgPayload(t *testing.T, prov provider, id, invitationID string) service.DIDCommMsgMap {
  2031  	connRec, err := connection.NewRecorder(prov)
  2032  	require.NoError(t, err)
  2033  	require.NotNil(t, connRec)
  2034  
  2035  	ctx := context{
  2036  		outboundDispatcher: prov.OutboundDispatcher(),
  2037  		vdRegistry:         &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
  2038  		connectionRecorder: connRec,
  2039  	}
  2040  	doc, err := ctx.vdRegistry.Create(testMethod, nil)
  2041  	require.NoError(t, err)
  2042  
  2043  	requestBytes, err := json.Marshal(&Request{
  2044  		Type: RequestMsgType,
  2045  		ID:   id,
  2046  		Thread: &decorator.Thread{
  2047  			PID: invitationID,
  2048  		},
  2049  		DID:       doc.DIDDocument.ID,
  2050  		DocAttach: signedDocAttach(t, doc.DIDDocument),
  2051  	})
  2052  	require.NoError(t, err)
  2053  
  2054  	didMsg, err := service.ParseDIDCommMsgMap(requestBytes)
  2055  	require.NoError(t, err)
  2056  
  2057  	return didMsg
  2058  }
  2059  
  2060  func TestService_CreateImplicitInvitation(t *testing.T) {
  2061  	t.Run("success", func(t *testing.T) {
  2062  		routeSvc := &mockroute.MockMediatorSvc{}
  2063  		prov := &protocol.MockProvider{
  2064  			ServiceMap: map[string]interface{}{
  2065  				mediator.Coordination: routeSvc,
  2066  			},
  2067  		}
  2068  		sp := mockstorage.NewMockStoreProvider()
  2069  		k := newKMS(t, sp)
  2070  		ctx := &context{
  2071  			kms:                k,
  2072  			outboundDispatcher: prov.OutboundDispatcher(),
  2073  			routeSvc:           routeSvc,
  2074  			keyType:            kms.ED25519Type,
  2075  			keyAgreementType:   kms.X25519ECDHKWType,
  2076  			mediaTypeProfiles:  []string{transport.MediaTypeRFC0019EncryptedEnvelope},
  2077  		}
  2078  
  2079  		verPubKey, encPubKey := newSigningAndEncryptionDIDKeys(t, ctx)
  2080  		newDIDDoc := createDIDDocWithKey(verPubKey, encPubKey, ctx.mediaTypeProfiles[0])
  2081  
  2082  		connRec, err := connection.NewRecorder(prov)
  2083  		require.NoError(t, err)
  2084  		require.NotNil(t, connRec)
  2085  
  2086  		didConnStore, err := didstore.NewConnectionStore(prov)
  2087  		require.NoError(t, err)
  2088  		require.NotNil(t, didConnStore)
  2089  
  2090  		ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: newDIDDoc}
  2091  		ctx.connectionRecorder = connRec
  2092  		ctx.connectionStore = didConnStore
  2093  
  2094  		s, err := New(prov)
  2095  		require.NoError(t, err)
  2096  
  2097  		s.ctx = ctx
  2098  		connID, err := s.CreateImplicitInvitation("label", newDIDDoc.ID, "", "", nil)
  2099  		require.NoError(t, err)
  2100  		require.NotEmpty(t, connID)
  2101  	})
  2102  
  2103  	t.Run("error during did resolution", func(t *testing.T) {
  2104  		routeSvc := &mockroute.MockMediatorSvc{}
  2105  		prov := &protocol.MockProvider{
  2106  			ServiceMap: map[string]interface{}{
  2107  				mediator.Coordination: routeSvc,
  2108  			},
  2109  		}
  2110  		sp := mockstorage.NewMockStoreProvider()
  2111  		k := newKMS(t, sp)
  2112  		ctx := &context{
  2113  			kms:                k,
  2114  			outboundDispatcher: prov.OutboundDispatcher(),
  2115  			routeSvc:           routeSvc,
  2116  			keyType:            kms.ED25519Type,
  2117  			keyAgreementType:   kms.X25519ECDHKWType,
  2118  			mediaTypeProfiles:  []string{transport.MediaTypeRFC0019EncryptedEnvelope},
  2119  		}
  2120  		verPubKey, encPubKey := newSigningAndEncryptionDIDKeys(t, ctx)
  2121  		newDIDDoc := createDIDDocWithKey(verPubKey, encPubKey, ctx.mediaTypeProfiles[0])
  2122  
  2123  		connRec, err := connection.NewRecorder(prov)
  2124  		require.NoError(t, err)
  2125  		require.NotNil(t, connRec)
  2126  
  2127  		didConnStore, err := didstore.NewConnectionStore(prov)
  2128  		require.NoError(t, err)
  2129  		require.NotNil(t, didConnStore)
  2130  
  2131  		ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveErr: errors.New("resolve error")}
  2132  		ctx.connectionRecorder = connRec
  2133  		ctx.connectionStore = didConnStore
  2134  
  2135  		s, err := New(prov)
  2136  		require.NoError(t, err)
  2137  		s.ctx = ctx
  2138  
  2139  		connID, err := s.CreateImplicitInvitation("label", newDIDDoc.ID, "", "", nil)
  2140  		require.Error(t, err)
  2141  		require.Contains(t, err.Error(), "resolve error")
  2142  		require.Empty(t, connID)
  2143  	})
  2144  
  2145  	t.Run("error during saving connection", func(t *testing.T) {
  2146  		sp := mockstorage.NewMockStoreProvider()
  2147  		k := newKMS(t, sp)
  2148  		ctx := &context{
  2149  			kms:               k,
  2150  			keyType:           kms.ED25519Type,
  2151  			keyAgreementType:  kms.X25519ECDHKWType,
  2152  			mediaTypeProfiles: []string{transport.MediaTypeRFC0019EncryptedEnvelope},
  2153  		}
  2154  		routeSvc := &mockroute.MockMediatorSvc{}
  2155  		protocolStateStore := mockstorage.NewMockStoreProvider()
  2156  		protocolStateStore.Store.ErrPut = errors.New("store put error")
  2157  		prov := &protocol.MockProvider{
  2158  			ProtocolStateStoreProvider: protocolStateStore,
  2159  			ServiceMap: map[string]interface{}{
  2160  				mediator.Coordination: routeSvc,
  2161  			},
  2162  			KeyTypeValue:          ctx.keyType,
  2163  			KeyAgreementTypeValue: ctx.keyAgreementType,
  2164  		}
  2165  
  2166  		ctx.outboundDispatcher = prov.OutboundDispatcher()
  2167  		ctx.routeSvc = routeSvc
  2168  
  2169  		verPubKey, encPubKey := newSigningAndEncryptionDIDKeys(t, ctx)
  2170  		newDIDDoc := createDIDDocWithKey(verPubKey, encPubKey, ctx.mediaTypeProfiles[0])
  2171  
  2172  		connRec, err := connection.NewRecorder(prov)
  2173  		require.NoError(t, err)
  2174  		require.NotNil(t, connRec)
  2175  
  2176  		didConnStore, err := didstore.NewConnectionStore(prov)
  2177  		require.NoError(t, err)
  2178  		require.NotNil(t, didConnStore)
  2179  
  2180  		ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: newDIDDoc}
  2181  		ctx.connectionRecorder = connRec
  2182  		ctx.connectionStore = didConnStore
  2183  
  2184  		s, err := New(prov)
  2185  		require.NoError(t, err)
  2186  		s.ctx = ctx
  2187  
  2188  		connID, err := s.CreateImplicitInvitation("label", newDIDDoc.ID, "", "", nil)
  2189  		require.Error(t, err)
  2190  		require.Contains(t, err.Error(), "store put error")
  2191  		require.Empty(t, connID)
  2192  	})
  2193  }
  2194  
  2195  func TestRespondTo(t *testing.T) {
  2196  	sp := mockstorage.NewMockStoreProvider()
  2197  	k := newKMS(t, sp)
  2198  	t.Run("responds to an explicit invitation", func(t *testing.T) {
  2199  		s, err := New(testProvider())
  2200  		require.NoError(t, err)
  2201  		connID, err := s.RespondTo(newInvitation(&did.Service{
  2202  			ID:              uuid.New().String(),
  2203  			Type:            "did-communication",
  2204  			RecipientKeys:   []string{"did:key:1234567"},
  2205  			ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://example.com"),
  2206  		}), nil)
  2207  		require.NoError(t, err)
  2208  		require.NotEmpty(t, connID)
  2209  	})
  2210  	t.Run("responds to an implicit invitation", func(t *testing.T) {
  2211  		publicDID := createDIDDoc(t, &context{
  2212  			kms:               k,
  2213  			keyType:           kms.ED25519Type,
  2214  			keyAgreementType:  kms.X25519ECDHKWType,
  2215  			mediaTypeProfiles: []string{transport.MediaTypeRFC0019EncryptedEnvelope},
  2216  		})
  2217  		provider := testProvider()
  2218  		provider.CustomVDR = &mockvdr.MockVDRegistry{ResolveValue: publicDID}
  2219  		s, err := New(provider)
  2220  		require.NoError(t, err)
  2221  		connID, err := s.RespondTo(newInvitation(publicDID.ID), nil)
  2222  		require.NoError(t, err)
  2223  		require.NotEmpty(t, connID)
  2224  	})
  2225  	t.Run("fails if invitation is missing a threadID", func(t *testing.T) {
  2226  		s, err := New(testProvider())
  2227  		require.NoError(t, err)
  2228  		_, err = s.RespondTo(&OOBInvitation{
  2229  			ID:         uuid.New().String(),
  2230  			ThreadID:   "",
  2231  			TheirLabel: "test",
  2232  			Target:     "did:example:123",
  2233  		}, nil)
  2234  		require.Error(t, err)
  2235  	})
  2236  	t.Run("fails if invitation is missing a target", func(t *testing.T) {
  2237  		s, err := New(testProvider())
  2238  		require.NoError(t, err)
  2239  		_, err = s.RespondTo(&OOBInvitation{
  2240  			ID:         uuid.New().String(),
  2241  			ThreadID:   uuid.New().String(),
  2242  			TheirLabel: "test",
  2243  			Target:     nil,
  2244  		}, nil)
  2245  		require.Error(t, err)
  2246  	})
  2247  	t.Run("fails if invitation has an invalid target type", func(t *testing.T) {
  2248  		invalid := &struct{}{}
  2249  		s, err := New(testProvider())
  2250  		require.NoError(t, err)
  2251  		_, err = s.RespondTo(newInvitation(invalid), nil)
  2252  		require.Error(t, err)
  2253  	})
  2254  	t.Run("wraps error from vdr registry when resolving DID", func(t *testing.T) {
  2255  		expected := errors.New("test")
  2256  		provider := testProvider()
  2257  		provider.CustomVDR = &mockvdr.MockVDRegistry{
  2258  			ResolveErr: expected,
  2259  		}
  2260  		s, err := New(provider)
  2261  		require.NoError(t, err)
  2262  		_, err = s.RespondTo(newInvitation("did:example:123"), nil)
  2263  		require.Error(t, err)
  2264  		require.True(t, errors.Is(err, expected))
  2265  	})
  2266  }
  2267  
  2268  func TestSave(t *testing.T) {
  2269  	t.Run("saves invitation", func(t *testing.T) {
  2270  		expected := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, "did:example:public")
  2271  		provider := testProvider()
  2272  		provider.StoreProvider = &mockstorage.MockStoreProvider{
  2273  			Custom: &mockStore{
  2274  				put: func(k string, v []byte, tags ...storage.Tag) error {
  2275  					result := &OOBInvitation{}
  2276  					err := json.Unmarshal(v, result)
  2277  					require.NoError(t, err)
  2278  					require.Equal(t, expected, result)
  2279  					return nil
  2280  				},
  2281  			},
  2282  		}
  2283  		s, err := New(provider)
  2284  		require.NoError(t, err)
  2285  		err = s.SaveInvitation(expected)
  2286  		require.NoError(t, err)
  2287  	})
  2288  	t.Run("wraps error returned by store", func(t *testing.T) {
  2289  		expected := errors.New("test")
  2290  		provider := testProvider()
  2291  		provider.StoreProvider = &mockstorage.MockStoreProvider{
  2292  			Store: &mockstorage.MockStore{
  2293  				ErrPut: expected,
  2294  			},
  2295  		}
  2296  		s, err := New(provider)
  2297  		require.NoError(t, err)
  2298  		err = s.SaveInvitation(newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, "did:example:public"))
  2299  		require.Error(t, err)
  2300  		require.True(t, errors.Is(err, expected))
  2301  	})
  2302  }
  2303  
  2304  func newInvitation(target interface{}) *OOBInvitation {
  2305  	return &OOBInvitation{
  2306  		ID:         uuid.New().String(),
  2307  		ThreadID:   uuid.New().String(),
  2308  		TheirLabel: "test",
  2309  		Target:     target,
  2310  	}
  2311  }
  2312  
  2313  func testProvider() *protocol.MockProvider {
  2314  	return &protocol.MockProvider{
  2315  		StoreProvider: mockstorage.NewMockStoreProvider(),
  2316  		ServiceMap: map[string]interface{}{
  2317  			mediator.Coordination: &mockroute.MockMediatorSvc{},
  2318  		},
  2319  		KeyTypeValue:          kms.ED25519Type,
  2320  		KeyAgreementTypeValue: kms.X25519ECDHKWType,
  2321  	}
  2322  }
  2323  
  2324  func newPeerDID(t *testing.T, k kms.KeyManager) *did.Doc {
  2325  	kid, pubKey, err := k.CreateAndExportPubKeyBytes(kms.ED25519)
  2326  	require.NoError(t, err)
  2327  
  2328  	key := did.VerificationMethod{
  2329  		ID:         kid,
  2330  		Type:       "Ed25519VerificationKey2018",
  2331  		Controller: "",
  2332  		Value:      pubKey,
  2333  	}
  2334  	doc, err := peer.NewDoc(
  2335  		[]did.VerificationMethod{key},
  2336  		did.WithAuthentication([]did.Verification{{
  2337  			VerificationMethod: key,
  2338  			Relationship:       0,
  2339  			Embedded:           true,
  2340  		}}),
  2341  		did.WithService([]did.Service{{
  2342  			ID:              "didcomm",
  2343  			Type:            "did-communication",
  2344  			Priority:        0,
  2345  			RecipientKeys:   []string{base58.Encode(pubKey)},
  2346  			ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://example.com"),
  2347  		}}),
  2348  	)
  2349  	require.NoError(t, err)
  2350  
  2351  	return doc
  2352  }
  2353  
  2354  func unsignedDocAttach(t *testing.T, doc *did.Doc) *decorator.Attachment {
  2355  	t.Helper()
  2356  
  2357  	docBytes, err := doc.JSONBytes()
  2358  	require.NoError(t, err)
  2359  
  2360  	att := &decorator.Attachment{
  2361  		Data: decorator.AttachmentData{
  2362  			Base64: base64.StdEncoding.EncodeToString(docBytes),
  2363  		},
  2364  	}
  2365  
  2366  	return att
  2367  }
  2368  
  2369  func signedDocAttach(t *testing.T, doc *did.Doc) *decorator.Attachment {
  2370  	t.Helper()
  2371  
  2372  	docBytes, err := doc.JSONBytes()
  2373  	require.NoError(t, err)
  2374  
  2375  	att := &decorator.Attachment{
  2376  		Data: decorator.AttachmentData{
  2377  			Base64: base64.StdEncoding.EncodeToString(docBytes),
  2378  		},
  2379  	}
  2380  
  2381  	store := mockstorage.NewMockStoreProvider()
  2382  
  2383  	kmsInstance := newKMS(t, store)
  2384  
  2385  	kid, kh, err := kmsInstance.Create(kms.ED25519Type)
  2386  	require.NoError(t, err)
  2387  
  2388  	pub, kt, err := kmsInstance.ExportPubKeyBytes(kid)
  2389  	require.NoError(t, err)
  2390  	require.Equal(t, kms.ED25519Type, kt)
  2391  
  2392  	c := &tinkcrypto.Crypto{}
  2393  
  2394  	err = att.Data.Sign(c, kh, ed25519.PublicKey(pub), pub)
  2395  	require.NoError(t, err)
  2396  
  2397  	return att
  2398  }
  2399  
  2400  type mockConnectionStore struct {
  2401  	saveDIDByResolvingErr error
  2402  	saveDIDFromDocErr     error
  2403  }
  2404  
  2405  // GetDID returns DID associated with key.
  2406  func (m *mockConnectionStore) GetDID(string) (string, error) {
  2407  	return "", nil
  2408  }
  2409  
  2410  // SaveDID saves DID to the underlying storage.
  2411  func (m *mockConnectionStore) SaveDID(string, ...string) error {
  2412  	return nil
  2413  }
  2414  
  2415  // SaveDIDFromDoc saves DID from did.Doc to the underlying storage.
  2416  func (m *mockConnectionStore) SaveDIDFromDoc(*did.Doc) error {
  2417  	return m.saveDIDFromDocErr
  2418  }
  2419  
  2420  // SaveDIDByResolving saves DID resolved by VDR to the underlying storage.
  2421  func (m *mockConnectionStore) SaveDIDByResolving(string, ...string) error {
  2422  	return m.saveDIDByResolvingErr
  2423  }