github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/messenger/messenger_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package messenger
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"testing"
    13  
    14  	"github.com/golang/mock/gomock"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
    18  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
    19  	dispatcherMocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/didcomm/dispatcher"
    20  	messengerMocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/didcomm/messenger"
    21  	storageMocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/spi/storage"
    22  )
    23  
    24  const (
    25  	ID       = "ID"
    26  	myDID    = "myDID"
    27  	theirDID = "theirDID"
    28  	msgID    = "msgID"
    29  	errMsg   = "test error"
    30  
    31  	jsonID             = "@id"
    32  	jsonThread         = "~thread"
    33  	jsonThreadID       = "thid"
    34  	jsonParentThreadID = "pthid"
    35  )
    36  
    37  // makes sure it satisfies the interface.
    38  var _ service.MessengerHandler = (*Messenger)(nil)
    39  
    40  func TestNewMessenger(t *testing.T) {
    41  	ctrl := gomock.NewController(t)
    42  	defer ctrl.Finish()
    43  
    44  	t.Run("success", func(t *testing.T) {
    45  		storageProvider := storageMocks.NewMockProvider(ctrl)
    46  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, nil)
    47  
    48  		provider := messengerMocks.NewMockProvider(ctrl)
    49  		provider.EXPECT().StorageProvider().Return(storageProvider)
    50  		provider.EXPECT().OutboundDispatcher().Return(nil)
    51  
    52  		msgr, err := NewMessenger(provider)
    53  		require.NoError(t, err)
    54  		require.NotNil(t, msgr)
    55  	})
    56  
    57  	t.Run("open store error", func(t *testing.T) {
    58  		storageProvider := storageMocks.NewMockProvider(ctrl)
    59  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, errors.New("test error"))
    60  
    61  		provider := messengerMocks.NewMockProvider(ctrl)
    62  		provider.EXPECT().StorageProvider().Return(storageProvider)
    63  
    64  		msgr, err := NewMessenger(provider)
    65  		require.Error(t, err)
    66  		require.Nil(t, msgr)
    67  	})
    68  }
    69  
    70  func TestMessenger_HandleInbound(t *testing.T) {
    71  	ctrl := gomock.NewController(t)
    72  	defer ctrl.Finish()
    73  
    74  	t.Run("success", func(t *testing.T) {
    75  		store := storageMocks.NewMockStore(ctrl)
    76  		store.EXPECT().Put(ID, gomock.Any()).Return(nil)
    77  
    78  		storageProvider := storageMocks.NewMockProvider(ctrl)
    79  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil)
    80  
    81  		provider := messengerMocks.NewMockProvider(ctrl)
    82  		provider.EXPECT().StorageProvider().Return(storageProvider)
    83  		provider.EXPECT().OutboundDispatcher().Return(nil)
    84  
    85  		msgr, err := NewMessenger(provider)
    86  		require.NoError(t, err)
    87  		require.NotNil(t, msgr)
    88  
    89  		require.NoError(t,
    90  			msgr.HandleInbound(service.DIDCommMsgMap{jsonID: ID}, service.NewDIDCommContext(myDID, theirDID, nil)))
    91  	})
    92  
    93  	t.Run("absent ID", func(t *testing.T) {
    94  		storageProvider := storageMocks.NewMockProvider(ctrl)
    95  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, nil)
    96  
    97  		provider := messengerMocks.NewMockProvider(ctrl)
    98  		provider.EXPECT().StorageProvider().Return(storageProvider)
    99  		provider.EXPECT().OutboundDispatcher().Return(nil)
   100  
   101  		msgr, err := NewMessenger(provider)
   102  		require.NoError(t, err)
   103  		require.NotNil(t, msgr)
   104  
   105  		err = msgr.HandleInbound(service.DIDCommMsgMap{}, service.NewDIDCommContext(myDID, theirDID, nil))
   106  		require.Contains(t, fmt.Sprintf("%v", err), "message-id is absent")
   107  	})
   108  }
   109  
   110  func sendToDIDCheck(t *testing.T, checks ...string) func(msg service.DIDCommMsgMap, myDID, theirDID string) error {
   111  	return func(msg service.DIDCommMsgMap, myDID, theirDID string) error {
   112  		v := struct {
   113  			ID     string           `json:"@id"`
   114  			Thread decorator.Thread `json:"~thread"`
   115  		}{}
   116  
   117  		require.NoError(t, msg.Decode(&v))
   118  
   119  		for _, check := range checks {
   120  			switch check {
   121  			case jsonID:
   122  				// ID always should be in the message
   123  				require.NotEmpty(t, v.ID)
   124  			case jsonThreadID:
   125  				require.NotEmpty(t, v.Thread.ID)
   126  			case jsonParentThreadID:
   127  				require.NotEmpty(t, v.Thread.PID)
   128  			}
   129  		}
   130  
   131  		return nil
   132  	}
   133  }
   134  
   135  func TestMessenger_Send(t *testing.T) {
   136  	ctrl := gomock.NewController(t)
   137  	defer ctrl.Finish()
   138  
   139  	t.Run("send success", func(t *testing.T) {
   140  		storageProvider := storageMocks.NewMockProvider(ctrl)
   141  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, nil)
   142  
   143  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   144  		outbound.EXPECT().SendToDID(gomock.Any(), myDID, theirDID).
   145  			Do(sendToDIDCheck(t, jsonID))
   146  
   147  		provider := messengerMocks.NewMockProvider(ctrl)
   148  		provider.EXPECT().StorageProvider().Return(storageProvider)
   149  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   150  
   151  		msgr, err := NewMessenger(provider)
   152  		require.NoError(t, err)
   153  		require.NotNil(t, msgr)
   154  
   155  		require.NoError(t, msgr.Send(service.DIDCommMsgMap{jsonID: ID}, myDID, theirDID))
   156  	})
   157  
   158  	t.Run("send to destination success", func(t *testing.T) {
   159  		storageProvider := storageMocks.NewMockProvider(ctrl)
   160  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, nil)
   161  
   162  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   163  		outbound.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).
   164  			Return(nil)
   165  
   166  		provider := messengerMocks.NewMockProvider(ctrl)
   167  		provider.EXPECT().StorageProvider().Return(storageProvider)
   168  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   169  
   170  		msgr, err := NewMessenger(provider)
   171  		require.NoError(t, err)
   172  		require.NotNil(t, msgr)
   173  
   174  		require.NoError(t, msgr.SendToDestination(service.DIDCommMsgMap{jsonID: ID}, "", &service.Destination{}))
   175  	})
   176  
   177  	t.Run("success msg without id", func(t *testing.T) {
   178  		storageProvider := storageMocks.NewMockProvider(ctrl)
   179  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, nil)
   180  
   181  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   182  		outbound.EXPECT().SendToDID(gomock.Any(), myDID, theirDID).
   183  			Do(sendToDIDCheck(t, jsonID))
   184  
   185  		provider := messengerMocks.NewMockProvider(ctrl)
   186  		provider.EXPECT().StorageProvider().Return(storageProvider)
   187  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   188  
   189  		msgr, err := NewMessenger(provider)
   190  		require.NoError(t, err)
   191  		require.NotNil(t, msgr)
   192  
   193  		require.NoError(t, msgr.Send(service.DIDCommMsgMap{}, myDID, theirDID))
   194  	})
   195  }
   196  
   197  func TestMessenger_ReplyTo(t *testing.T) {
   198  	ctrl := gomock.NewController(t)
   199  	defer ctrl.Finish()
   200  
   201  	t.Run("success", func(t *testing.T) {
   202  		store := storageMocks.NewMockStore(ctrl)
   203  		store.EXPECT().Get(ID).Return([]byte(`{"thread_id":"thID","parent_thread_id":"pthID"}`), nil)
   204  
   205  		storageProvider := storageMocks.NewMockProvider(ctrl)
   206  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil)
   207  
   208  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   209  		outbound.EXPECT().SendToDID(gomock.Any(), gomock.Any(), gomock.Any()).
   210  			Do(sendToDIDCheck(t, jsonID, jsonThreadID, jsonParentThreadID))
   211  
   212  		provider := messengerMocks.NewMockProvider(ctrl)
   213  		provider.EXPECT().StorageProvider().Return(storageProvider)
   214  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   215  
   216  		msgr, err := NewMessenger(provider)
   217  		require.NoError(t, err)
   218  		require.NotNil(t, msgr)
   219  		require.NoError(t, msgr.ReplyTo(ID, service.DIDCommMsgMap{jsonID: ID}))
   220  	})
   221  
   222  	t.Run("the message was not received", func(t *testing.T) {
   223  		store := storageMocks.NewMockStore(ctrl)
   224  		store.EXPECT().Get(ID).Return(nil, errors.New(errMsg))
   225  
   226  		storageProvider := storageMocks.NewMockProvider(ctrl)
   227  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil)
   228  
   229  		provider := messengerMocks.NewMockProvider(ctrl)
   230  		provider.EXPECT().StorageProvider().Return(storageProvider)
   231  		provider.EXPECT().OutboundDispatcher().Return(nil)
   232  
   233  		msgr, err := NewMessenger(provider)
   234  		require.NoError(t, err)
   235  		require.NotNil(t, msgr)
   236  
   237  		err = msgr.ReplyTo(ID, service.DIDCommMsgMap{})
   238  		require.Contains(t, fmt.Sprintf("%v", err), errMsg)
   239  	})
   240  
   241  	t.Run("success msg without id", func(t *testing.T) {
   242  		store := storageMocks.NewMockStore(ctrl)
   243  		store.EXPECT().Get(ID).Return([]byte(`{"thread_id":"thID"}`), nil)
   244  
   245  		storageProvider := storageMocks.NewMockProvider(ctrl)
   246  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil)
   247  
   248  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   249  		outbound.EXPECT().SendToDID(gomock.Any(), gomock.Any(), gomock.Any()).
   250  			Do(sendToDIDCheck(t, jsonID, jsonThreadID))
   251  
   252  		provider := messengerMocks.NewMockProvider(ctrl)
   253  		provider.EXPECT().StorageProvider().Return(storageProvider)
   254  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   255  
   256  		msgr, err := NewMessenger(provider)
   257  		require.NoError(t, err)
   258  		require.NotNil(t, msgr)
   259  
   260  		require.NoError(t, msgr.ReplyTo(ID, service.DIDCommMsgMap{}))
   261  	})
   262  }
   263  
   264  func TestMessenger_ReplyToNested(t *testing.T) {
   265  	ctrl := gomock.NewController(t)
   266  	defer ctrl.Finish()
   267  
   268  	const thID = "thID"
   269  
   270  	t.Run("success", func(t *testing.T) {
   271  		storageProvider := storageMocks.NewMockProvider(ctrl)
   272  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, nil)
   273  
   274  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   275  		outbound.EXPECT().SendToDID(gomock.Any(), gomock.Any(), gomock.Any()).
   276  			Do(sendToDIDCheck(t, jsonID, jsonParentThreadID))
   277  
   278  		provider := messengerMocks.NewMockProvider(ctrl)
   279  		provider.EXPECT().StorageProvider().Return(storageProvider)
   280  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   281  
   282  		msgr, err := NewMessenger(provider)
   283  		require.NoError(t, err)
   284  		require.NotNil(t, msgr)
   285  		require.NoError(t, msgr.ReplyToNested(service.DIDCommMsgMap{jsonID: ID},
   286  			&service.NestedReplyOpts{ThreadID: thID, TheirDID: theirDID, MyDID: myDID}))
   287  	})
   288  
   289  	t.Run("success with msgID option", func(t *testing.T) {
   290  		store := storageMocks.NewMockStore(ctrl)
   291  		store.EXPECT().Get(msgID).Return([]byte(`{"my_did":"myDID","their_did":"theirDID","thread_id":"theirDID"}`), nil)
   292  
   293  		storageProvider := storageMocks.NewMockProvider(ctrl)
   294  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil)
   295  
   296  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   297  		outbound.EXPECT().SendToDID(gomock.Any(), gomock.Any(), gomock.Any()).
   298  			Do(sendToDIDCheck(t, jsonID, jsonParentThreadID))
   299  
   300  		provider := messengerMocks.NewMockProvider(ctrl)
   301  		provider.EXPECT().StorageProvider().Return(storageProvider)
   302  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   303  
   304  		msgr, err := NewMessenger(provider)
   305  		require.NoError(t, err)
   306  		require.NotNil(t, msgr)
   307  		require.NoError(t, msgr.ReplyToNested(service.DIDCommMsgMap{jsonID: ID},
   308  			&service.NestedReplyOpts{MsgID: msgID}))
   309  	})
   310  
   311  	t.Run("success msg without id", func(t *testing.T) {
   312  		storageProvider := storageMocks.NewMockProvider(ctrl)
   313  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, nil)
   314  
   315  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   316  		outbound.EXPECT().SendToDID(gomock.Any(), gomock.Any(), gomock.Any()).
   317  			Do(sendToDIDCheck(t, jsonID, jsonParentThreadID))
   318  
   319  		provider := messengerMocks.NewMockProvider(ctrl)
   320  		provider.EXPECT().StorageProvider().Return(storageProvider)
   321  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   322  
   323  		msgr, err := NewMessenger(provider)
   324  		require.NoError(t, err)
   325  		require.NotNil(t, msgr)
   326  
   327  		require.NoError(t, msgr.ReplyToNested(service.DIDCommMsgMap{},
   328  			&service.NestedReplyOpts{ThreadID: thID, TheirDID: theirDID, MyDID: myDID}))
   329  	})
   330  
   331  	t.Run("failure with message ID issues", func(t *testing.T) {
   332  		store := storageMocks.NewMockStore(ctrl)
   333  		store.EXPECT().Get(msgID).Return(nil, errors.New(errMsg))
   334  
   335  		storageProvider := storageMocks.NewMockProvider(ctrl)
   336  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil)
   337  
   338  		provider := messengerMocks.NewMockProvider(ctrl)
   339  		provider.EXPECT().StorageProvider().Return(storageProvider)
   340  		provider.EXPECT().OutboundDispatcher().Return(dispatcherMocks.NewMockOutbound(ctrl))
   341  
   342  		msgr, err := NewMessenger(provider)
   343  		require.NoError(t, err)
   344  		require.NotNil(t, msgr)
   345  
   346  		err = msgr.ReplyToNested(service.DIDCommMsgMap{jsonID: ID},
   347  			&service.NestedReplyOpts{MsgID: msgID})
   348  		require.Contains(t, err.Error(), errMsg)
   349  	})
   350  }
   351  
   352  func TestMessenger_ReplyToMsg(t *testing.T) {
   353  	ctrl := gomock.NewController(t)
   354  	defer ctrl.Finish()
   355  
   356  	t.Run("success", func(t *testing.T) {
   357  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   358  		outbound.EXPECT().SendToDID(gomock.Any(), gomock.Any(), gomock.Any()).
   359  			Do(sendToDIDCheck(t, jsonID, jsonThreadID, jsonParentThreadID))
   360  
   361  		storageProvider := storageMocks.NewMockProvider(ctrl)
   362  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, nil)
   363  
   364  		provider := messengerMocks.NewMockProvider(ctrl)
   365  		provider.EXPECT().StorageProvider().Return(storageProvider)
   366  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   367  
   368  		msgr, err := NewMessenger(provider)
   369  		require.NoError(t, err)
   370  		require.NotNil(t, msgr)
   371  		require.NoError(t, msgr.ReplyToMsg(service.DIDCommMsgMap{
   372  			jsonID:     "id",
   373  			jsonThread: map[string]interface{}{jsonThreadID: "thID", jsonParentThreadID: "pthID"},
   374  		}, service.DIDCommMsgMap{}, "", ""))
   375  	})
   376  
   377  	t.Run("success msg without id", func(t *testing.T) {
   378  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   379  		outbound.EXPECT().SendToDID(gomock.Any(), gomock.Any(), gomock.Any()).
   380  			Do(sendToDIDCheck(t, jsonID, jsonThreadID))
   381  
   382  		storageProvider := storageMocks.NewMockProvider(ctrl)
   383  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, nil)
   384  
   385  		provider := messengerMocks.NewMockProvider(ctrl)
   386  		provider.EXPECT().StorageProvider().Return(storageProvider)
   387  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   388  
   389  		msgr, err := NewMessenger(provider)
   390  		require.NoError(t, err)
   391  		require.NotNil(t, msgr)
   392  
   393  		require.NoError(t, msgr.ReplyToMsg(service.DIDCommMsgMap{
   394  			jsonID:     "id",
   395  			jsonThread: map[string]interface{}{jsonThreadID: "thID"},
   396  		}, service.DIDCommMsgMap{}, "", ""))
   397  	})
   398  
   399  	t.Run("invalid message", func(t *testing.T) {
   400  		outbound := dispatcherMocks.NewMockOutbound(ctrl)
   401  
   402  		storageProvider := storageMocks.NewMockProvider(ctrl)
   403  		storageProvider.EXPECT().OpenStore(gomock.Any()).Return(nil, nil)
   404  
   405  		provider := messengerMocks.NewMockProvider(ctrl)
   406  		provider.EXPECT().StorageProvider().Return(storageProvider)
   407  		provider.EXPECT().OutboundDispatcher().Return(outbound)
   408  
   409  		msgr, err := NewMessenger(provider)
   410  		require.NoError(t, err)
   411  		require.NotNil(t, msgr)
   412  
   413  		require.EqualError(t, msgr.ReplyToMsg(service.DIDCommMsgMap{
   414  			jsonThread: map[string]interface{}{jsonThreadID: "thID"},
   415  		}, service.DIDCommMsgMap{}, "", ""), "get threadID: invalid message")
   416  	})
   417  }