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

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package issuecredential
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"testing"
    13  
    14  	"github.com/golang/mock/gomock"
    15  	"github.com/google/uuid"
    16  	"github.com/stretchr/testify/require"
    17  
    18  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
    19  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
    20  	serviceMocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/didcomm/common/service"
    21  )
    22  
    23  func notTransition(t *testing.T, st state) {
    24  	t.Helper()
    25  
    26  	allState := [...]state{
    27  		// common states
    28  		&start{}, &abandoning{}, &done{}, &noOp{},
    29  		// states for Issuer
    30  		&proposalReceived{}, &offerSent{}, &requestReceived{}, &credentialIssued{},
    31  		// states for Holder
    32  		&proposalSent{}, &offerReceived{}, &requestSent{}, &credentialReceived{},
    33  	}
    34  
    35  	for _, s := range allState {
    36  		require.False(t, st.CanTransitionTo(s))
    37  	}
    38  }
    39  
    40  func TestStart_CanTransitionTo(t *testing.T) {
    41  	st := &start{}
    42  	require.Equal(t, stateNameStart, st.Name())
    43  	// common states
    44  	require.False(t, st.CanTransitionTo(&start{}))
    45  	require.False(t, st.CanTransitionTo(&abandoning{}))
    46  	require.False(t, st.CanTransitionTo(&done{}))
    47  	require.False(t, st.CanTransitionTo(&noOp{}))
    48  	// states for Issuer
    49  	require.True(t, st.CanTransitionTo(&proposalReceived{}))
    50  	require.True(t, st.CanTransitionTo(&offerSent{}))
    51  	require.True(t, st.CanTransitionTo(&requestReceived{}))
    52  	require.False(t, st.CanTransitionTo(&credentialIssued{}))
    53  	// states for Holder
    54  	require.True(t, st.CanTransitionTo(&proposalSent{}))
    55  	require.True(t, st.CanTransitionTo(&offerReceived{}))
    56  	require.True(t, st.CanTransitionTo(&requestSent{}))
    57  	require.False(t, st.CanTransitionTo(&credentialReceived{}))
    58  }
    59  
    60  func TestStart_ExecuteInbound(t *testing.T) {
    61  	followup, action, err := (&start{}).ExecuteInbound(&MetaData{})
    62  	require.Contains(t, fmt.Sprintf("%v", err), "is not implemented yet")
    63  	require.Nil(t, followup)
    64  	require.Nil(t, action)
    65  }
    66  
    67  func TestStart_ExecuteOutbound(t *testing.T) {
    68  	followup, action, err := (&start{}).ExecuteOutbound(&MetaData{})
    69  	require.Contains(t, fmt.Sprintf("%v", err), "is not implemented yet")
    70  	require.Nil(t, followup)
    71  	require.Nil(t, action)
    72  }
    73  
    74  func TestAbandoning_CanTransitionTo(t *testing.T) {
    75  	st := &abandoning{}
    76  	require.Equal(t, stateNameAbandoning, st.Name())
    77  	// common states
    78  	require.False(t, st.CanTransitionTo(&start{}))
    79  	require.False(t, st.CanTransitionTo(&abandoning{}))
    80  	require.True(t, st.CanTransitionTo(&done{}))
    81  	require.False(t, st.CanTransitionTo(&noOp{}))
    82  	// states for Issuer
    83  	require.False(t, st.CanTransitionTo(&proposalReceived{}))
    84  	require.False(t, st.CanTransitionTo(&offerSent{}))
    85  	require.False(t, st.CanTransitionTo(&requestReceived{}))
    86  	require.False(t, st.CanTransitionTo(&credentialIssued{}))
    87  	// states for Holder
    88  	require.False(t, st.CanTransitionTo(&proposalSent{}))
    89  	require.False(t, st.CanTransitionTo(&offerReceived{}))
    90  	require.False(t, st.CanTransitionTo(&requestSent{}))
    91  	require.False(t, st.CanTransitionTo(&credentialReceived{}))
    92  }
    93  
    94  func TestAbandoning_ExecuteInbound(t *testing.T) {
    95  	t.Run("With code", func(t *testing.T) {
    96  		md := &MetaData{}
    97  		md.Msg = service.NewDIDCommMsgMap(struct{}{})
    98  
    99  		thID := uuid.New().String()
   100  		md.Msg.SetID(thID)
   101  
   102  		followup, action, err := (&abandoning{Code: codeInternalError}).ExecuteInbound(md)
   103  		require.NoError(t, err)
   104  		require.Equal(t, &done{}, followup)
   105  		require.NotNil(t, action)
   106  
   107  		ctrl := gomock.NewController(t)
   108  		defer ctrl.Finish()
   109  
   110  		messenger := serviceMocks.NewMockMessenger(ctrl)
   111  		messenger.EXPECT().
   112  			ReplyToNested(gomock.Any(), gomock.Any()).
   113  			Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error {
   114  				r := &model.ProblemReport{}
   115  				require.NoError(t, msg.Decode(r))
   116  				require.Equal(t, codeInternalError, r.Description.Code)
   117  				require.Equal(t, ProblemReportMsgTypeV2, r.Type)
   118  
   119  				return nil
   120  			})
   121  
   122  		require.NoError(t, action(messenger))
   123  	})
   124  
   125  	t.Run("With invalid message", func(t *testing.T) {
   126  		followup, action, err := (&abandoning{Code: codeInternalError}).ExecuteInbound(&MetaData{})
   127  		require.EqualError(t, errors.Unwrap(err), service.ErrInvalidMessage.Error())
   128  		require.Nil(t, followup)
   129  		require.Nil(t, action)
   130  	})
   131  
   132  	t.Run("With custom error", func(t *testing.T) {
   133  		md := &MetaData{err: customError{error: errors.New("error")}}
   134  		md.Msg = service.NewDIDCommMsgMap(struct{}{})
   135  
   136  		thID := uuid.New().String()
   137  		md.Msg.SetID(thID)
   138  
   139  		followup, action, err := (&abandoning{Code: codeInternalError}).ExecuteInbound(md)
   140  		require.NoError(t, err)
   141  		require.Equal(t, &done{}, followup)
   142  		require.NotNil(t, action)
   143  
   144  		ctrl := gomock.NewController(t)
   145  		defer ctrl.Finish()
   146  
   147  		messenger := serviceMocks.NewMockMessenger(ctrl)
   148  		messenger.EXPECT().
   149  			ReplyToNested(gomock.Any(), gomock.Any()).
   150  			Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error {
   151  				r := &model.ProblemReport{}
   152  				require.NoError(t, msg.Decode(r))
   153  				require.Equal(t, codeRejectedError, r.Description.Code)
   154  				require.Equal(t, ProblemReportMsgTypeV2, r.Type)
   155  
   156  				return nil
   157  			})
   158  
   159  		require.NoError(t, action(messenger))
   160  	})
   161  
   162  	t.Run("Without code", func(t *testing.T) {
   163  		md := &MetaData{}
   164  		md.Msg = service.NewDIDCommMsgMap(struct{}{})
   165  		md.Msg.SetID(uuid.New().String())
   166  
   167  		followup, action, err := (&abandoning{}).ExecuteInbound(md)
   168  		require.NoError(t, err)
   169  		require.Equal(t, &done{}, followup)
   170  		require.NotNil(t, action)
   171  
   172  		require.NoError(t, action(nil))
   173  	})
   174  }
   175  
   176  func TestAbandoning_ExecuteOutbound(t *testing.T) {
   177  	followup, action, err := (&abandoning{}).ExecuteOutbound(&MetaData{})
   178  	require.Contains(t, fmt.Sprintf("%v", err), "is not implemented yet")
   179  	require.Nil(t, followup)
   180  	require.Nil(t, action)
   181  }
   182  
   183  func TestDone_CanTransitionTo(t *testing.T) {
   184  	st := &done{}
   185  	require.Equal(t, stateNameDone, st.Name())
   186  	notTransition(t, st)
   187  }
   188  
   189  func TestDone_ExecuteInbound(t *testing.T) {
   190  	followup, action, err := (&done{}).ExecuteInbound(&MetaData{})
   191  	require.NoError(t, err)
   192  	require.Equal(t, &noOp{}, followup)
   193  	require.NoError(t, action(nil))
   194  }
   195  
   196  func TestDone_ExecuteOutbound(t *testing.T) {
   197  	followup, action, err := (&done{}).ExecuteOutbound(&MetaData{})
   198  	require.Contains(t, fmt.Sprintf("%v", err), "is not implemented yet")
   199  	require.Nil(t, followup)
   200  	require.Nil(t, action)
   201  }
   202  
   203  func TestNoOp_CanTransitionTo(t *testing.T) {
   204  	st := &noOp{}
   205  	require.Equal(t, stateNameNoop, st.Name())
   206  	notTransition(t, st)
   207  }
   208  
   209  func TestNoOp_ExecuteInbound(t *testing.T) {
   210  	followup, action, err := (&noOp{}).ExecuteInbound(&MetaData{})
   211  	require.Contains(t, fmt.Sprintf("%v", err), "cannot execute no-op")
   212  	require.Nil(t, followup)
   213  	require.Nil(t, action)
   214  }
   215  
   216  func TestNoOp_ExecuteOutbound(t *testing.T) {
   217  	followup, action, err := (&noOp{}).ExecuteOutbound(&MetaData{})
   218  	require.Contains(t, fmt.Sprintf("%v", err), "cannot execute no-op")
   219  	require.Nil(t, followup)
   220  	require.Nil(t, action)
   221  }
   222  
   223  func TestProposalReceived_CanTransitionTo(t *testing.T) {
   224  	st := &proposalReceived{}
   225  	require.Equal(t, stateNameProposalReceived, st.Name())
   226  	// common states
   227  	require.False(t, st.CanTransitionTo(&start{}))
   228  	require.True(t, st.CanTransitionTo(&abandoning{}))
   229  	require.False(t, st.CanTransitionTo(&done{}))
   230  	require.False(t, st.CanTransitionTo(&noOp{}))
   231  	// states for Issuer
   232  	require.False(t, st.CanTransitionTo(&proposalReceived{}))
   233  	require.True(t, st.CanTransitionTo(&offerSent{}))
   234  	require.False(t, st.CanTransitionTo(&requestReceived{}))
   235  	require.False(t, st.CanTransitionTo(&credentialIssued{}))
   236  	// states for Holder
   237  	require.False(t, st.CanTransitionTo(&proposalSent{}))
   238  	require.False(t, st.CanTransitionTo(&offerReceived{}))
   239  	require.False(t, st.CanTransitionTo(&requestSent{}))
   240  	require.False(t, st.CanTransitionTo(&credentialReceived{}))
   241  }
   242  
   243  func TestProposalReceived_ExecuteInbound(t *testing.T) {
   244  	followup, action, err := (&proposalReceived{}).ExecuteInbound(&MetaData{})
   245  	require.NoError(t, err)
   246  	require.Equal(t, &offerSent{}, followup)
   247  	require.NotNil(t, action)
   248  }
   249  
   250  func TestProposalReceived_ExecuteOutbound(t *testing.T) {
   251  	followup, action, err := (&proposalReceived{}).ExecuteOutbound(&MetaData{})
   252  	require.Contains(t, fmt.Sprintf("%v", err), "is not implemented yet")
   253  	require.Nil(t, followup)
   254  	require.Nil(t, action)
   255  }
   256  
   257  func TestOfferSent_CanTransitionTo(t *testing.T) {
   258  	st := &offerSent{}
   259  	require.Equal(t, stateNameOfferSent, st.Name())
   260  	// common states
   261  	require.False(t, st.CanTransitionTo(&start{}))
   262  	require.True(t, st.CanTransitionTo(&abandoning{}))
   263  	require.False(t, st.CanTransitionTo(&done{}))
   264  	require.False(t, st.CanTransitionTo(&noOp{}))
   265  	// states for Issuer
   266  	require.True(t, st.CanTransitionTo(&proposalReceived{}))
   267  	require.False(t, st.CanTransitionTo(&offerSent{}))
   268  	require.True(t, st.CanTransitionTo(&requestReceived{}))
   269  	require.False(t, st.CanTransitionTo(&credentialIssued{}))
   270  	// states for Holder
   271  	require.False(t, st.CanTransitionTo(&proposalSent{}))
   272  	require.False(t, st.CanTransitionTo(&offerReceived{}))
   273  	require.False(t, st.CanTransitionTo(&requestSent{}))
   274  	require.False(t, st.CanTransitionTo(&credentialReceived{}))
   275  }
   276  
   277  func TestOfferSent_ExecuteInbound(t *testing.T) {
   278  	t.Run("Success", func(t *testing.T) {
   279  		followup, action, err := (&offerSent{}).ExecuteInbound(&MetaData{offerCredentialV2: &OfferCredentialV2{}})
   280  		require.NoError(t, err)
   281  		require.Equal(t, &noOp{}, followup)
   282  		require.NotNil(t, action)
   283  
   284  		ctrl := gomock.NewController(t)
   285  		defer ctrl.Finish()
   286  
   287  		messenger := serviceMocks.NewMockMessenger(ctrl)
   288  		messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   289  
   290  		require.NoError(t, action(messenger))
   291  	})
   292  
   293  	t.Run("OfferCredential is absent", func(t *testing.T) {
   294  		followup, action, err := (&offerSent{}).ExecuteInbound(&MetaData{})
   295  		require.Contains(t, fmt.Sprintf("%v", err), "offer credential was not provided")
   296  		require.Nil(t, followup)
   297  		require.Nil(t, action)
   298  	})
   299  }
   300  
   301  func TestOfferSent_ExecuteOutbound(t *testing.T) {
   302  	followup, action, err := (&offerSent{}).ExecuteOutbound(&MetaData{})
   303  	require.NoError(t, err)
   304  	require.Equal(t, &noOp{}, followup)
   305  	require.NotNil(t, action)
   306  
   307  	ctrl := gomock.NewController(t)
   308  	defer ctrl.Finish()
   309  
   310  	messenger := serviceMocks.NewMockMessenger(ctrl)
   311  	messenger.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   312  
   313  	require.NoError(t, action(messenger))
   314  }
   315  
   316  func TestRequestReceived_CanTransitionTo(t *testing.T) {
   317  	st := &requestReceived{}
   318  	require.Equal(t, stateNameRequestReceived, st.Name())
   319  	// common states
   320  	require.False(t, st.CanTransitionTo(&start{}))
   321  	require.True(t, st.CanTransitionTo(&abandoning{}))
   322  	require.False(t, st.CanTransitionTo(&done{}))
   323  	require.False(t, st.CanTransitionTo(&noOp{}))
   324  	// states for Issuer
   325  	require.False(t, st.CanTransitionTo(&proposalReceived{}))
   326  	require.False(t, st.CanTransitionTo(&offerSent{}))
   327  	require.False(t, st.CanTransitionTo(&requestReceived{}))
   328  	require.True(t, st.CanTransitionTo(&credentialIssued{}))
   329  	// states for Holder
   330  	require.False(t, st.CanTransitionTo(&proposalSent{}))
   331  	require.False(t, st.CanTransitionTo(&offerReceived{}))
   332  	require.False(t, st.CanTransitionTo(&requestSent{}))
   333  	require.False(t, st.CanTransitionTo(&credentialReceived{}))
   334  }
   335  
   336  func TestRequestReceived_ExecuteInbound(t *testing.T) {
   337  	t.Run("Successes", func(t *testing.T) {
   338  		followup, action, err := (&requestReceived{}).ExecuteInbound(&MetaData{issueCredentialV2: &IssueCredentialV2{}})
   339  		require.NoError(t, err)
   340  		require.Equal(t, &credentialIssued{}, followup)
   341  		require.NotNil(t, action)
   342  
   343  		ctrl := gomock.NewController(t)
   344  		defer ctrl.Finish()
   345  
   346  		messenger := serviceMocks.NewMockMessenger(ctrl)
   347  		messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   348  
   349  		require.NoError(t, action(messenger))
   350  	})
   351  
   352  	t.Run("IssueCredential is absent", func(t *testing.T) {
   353  		followup, action, err := (&requestReceived{}).ExecuteInbound(&MetaData{})
   354  		require.Contains(t, fmt.Sprintf("%v", err), "issue credential was not provided")
   355  		require.Nil(t, followup)
   356  		require.Nil(t, action)
   357  	})
   358  }
   359  
   360  func TestRequestReceived_ExecuteOutbound(t *testing.T) {
   361  	followup, action, err := (&requestReceived{}).ExecuteOutbound(&MetaData{})
   362  	require.Contains(t, fmt.Sprintf("%v", err), "is not implemented yet")
   363  	require.Nil(t, followup)
   364  	require.Nil(t, action)
   365  }
   366  
   367  func TestCredentialIssued_CanTransitionTo(t *testing.T) {
   368  	st := &credentialIssued{}
   369  	require.Equal(t, stateNameCredentialIssued, st.Name())
   370  	// common states
   371  	require.False(t, st.CanTransitionTo(&start{}))
   372  	require.True(t, st.CanTransitionTo(&abandoning{}))
   373  	require.True(t, st.CanTransitionTo(&done{}))
   374  	require.False(t, st.CanTransitionTo(&noOp{}))
   375  	// states for Issuer
   376  	require.False(t, st.CanTransitionTo(&proposalReceived{}))
   377  	require.False(t, st.CanTransitionTo(&offerSent{}))
   378  	require.False(t, st.CanTransitionTo(&requestReceived{}))
   379  	require.False(t, st.CanTransitionTo(&credentialIssued{}))
   380  	// states for Holder
   381  	require.False(t, st.CanTransitionTo(&proposalSent{}))
   382  	require.False(t, st.CanTransitionTo(&offerReceived{}))
   383  	require.False(t, st.CanTransitionTo(&requestSent{}))
   384  	require.False(t, st.CanTransitionTo(&credentialReceived{}))
   385  }
   386  
   387  func TestCredentialIssued_ExecuteInbound(t *testing.T) {
   388  	followup, action, err := (&credentialIssued{}).ExecuteInbound(&MetaData{})
   389  	require.NoError(t, err)
   390  	require.Equal(t, &noOp{}, followup)
   391  	require.NoError(t, action(nil))
   392  }
   393  
   394  func TestCredentialIssued_ExecuteOutbound(t *testing.T) {
   395  	followup, action, err := (&credentialIssued{}).ExecuteOutbound(&MetaData{})
   396  	require.Contains(t, fmt.Sprintf("%v", err), "is not implemented yet")
   397  	require.Nil(t, followup)
   398  	require.Nil(t, action)
   399  }
   400  
   401  func TestProposalSent_CanTransitionTo(t *testing.T) {
   402  	st := &proposalSent{}
   403  	require.Equal(t, stateNameProposalSent, st.Name())
   404  	// common states
   405  	require.False(t, st.CanTransitionTo(&start{}))
   406  	require.True(t, st.CanTransitionTo(&abandoning{}))
   407  	require.False(t, st.CanTransitionTo(&done{}))
   408  	require.False(t, st.CanTransitionTo(&noOp{}))
   409  	// states for Issuer
   410  	require.False(t, st.CanTransitionTo(&proposalReceived{}))
   411  	require.False(t, st.CanTransitionTo(&offerSent{}))
   412  	require.False(t, st.CanTransitionTo(&requestReceived{}))
   413  	require.False(t, st.CanTransitionTo(&credentialIssued{}))
   414  	// states for Holder
   415  	require.False(t, st.CanTransitionTo(&proposalSent{}))
   416  	require.True(t, st.CanTransitionTo(&offerReceived{}))
   417  	require.False(t, st.CanTransitionTo(&requestSent{}))
   418  	require.False(t, st.CanTransitionTo(&credentialReceived{}))
   419  }
   420  
   421  func TestProposalSent_ExecuteInbound(t *testing.T) {
   422  	t.Run("Successes", func(t *testing.T) {
   423  		followup, action, err := (&proposalSent{}).ExecuteInbound(&MetaData{proposeCredentialV2: &ProposeCredentialV2{}})
   424  		require.NoError(t, err)
   425  		require.Equal(t, &noOp{}, followup)
   426  		require.NotNil(t, action)
   427  
   428  		ctrl := gomock.NewController(t)
   429  		defer ctrl.Finish()
   430  
   431  		messenger := serviceMocks.NewMockMessenger(ctrl)
   432  		messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   433  
   434  		require.NoError(t, action(messenger))
   435  	})
   436  
   437  	t.Run("ProposeCredential is absent", func(t *testing.T) {
   438  		followup, action, err := (&proposalSent{}).ExecuteInbound(&MetaData{})
   439  		require.Contains(t, fmt.Sprintf("%v", err), "propose credential was not provided")
   440  		require.Nil(t, followup)
   441  		require.Nil(t, action)
   442  	})
   443  }
   444  
   445  func TestProposalSent_ExecuteOutbound(t *testing.T) {
   446  	followup, action, err := (&proposalSent{}).ExecuteOutbound(&MetaData{})
   447  	require.NoError(t, err)
   448  	require.Equal(t, &noOp{}, followup)
   449  	require.NotNil(t, action)
   450  
   451  	ctrl := gomock.NewController(t)
   452  	defer ctrl.Finish()
   453  
   454  	messenger := serviceMocks.NewMockMessenger(ctrl)
   455  	messenger.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   456  
   457  	require.NoError(t, action(messenger))
   458  }
   459  
   460  func TestOfferReceived_CanTransitionTo(t *testing.T) {
   461  	st := &offerReceived{}
   462  	require.Equal(t, stateNameOfferReceived, st.Name())
   463  	// common states
   464  	require.False(t, st.CanTransitionTo(&start{}))
   465  	require.True(t, st.CanTransitionTo(&abandoning{}))
   466  	require.False(t, st.CanTransitionTo(&done{}))
   467  	require.False(t, st.CanTransitionTo(&noOp{}))
   468  	// states for Issuer
   469  	require.False(t, st.CanTransitionTo(&proposalReceived{}))
   470  	require.False(t, st.CanTransitionTo(&offerSent{}))
   471  	require.False(t, st.CanTransitionTo(&requestReceived{}))
   472  	require.False(t, st.CanTransitionTo(&credentialIssued{}))
   473  	// states for Holder
   474  	require.True(t, st.CanTransitionTo(&proposalSent{}))
   475  	require.False(t, st.CanTransitionTo(&offerReceived{}))
   476  	require.True(t, st.CanTransitionTo(&requestSent{}))
   477  	require.False(t, st.CanTransitionTo(&credentialReceived{}))
   478  }
   479  
   480  func TestOfferReceived_ExecuteInbound(t *testing.T) {
   481  	t.Run("incorrect data (with ProposeCredential)", func(t *testing.T) {
   482  		msg := service.NewDIDCommMsgMap(struct{}{})
   483  
   484  		followup, action, err := (&offerReceived{}).ExecuteInbound(&MetaData{
   485  			proposeCredentialV2: &ProposeCredentialV2{},
   486  			transitionalPayload: transitionalPayload{
   487  				Action: Action{Msg: msg},
   488  			},
   489  		})
   490  		require.NoError(t, err)
   491  		require.Equal(t, &proposalSent{}, followup)
   492  		require.NotNil(t, action)
   493  	})
   494  
   495  	t.Run("correct data (without ProposeCredential)", func(t *testing.T) {
   496  		followup, action, err := (&offerReceived{}).ExecuteInbound(&MetaData{})
   497  		require.NoError(t, err)
   498  		require.Equal(t, &requestSent{}, followup)
   499  		require.NotNil(t, action)
   500  
   501  		ctrl := gomock.NewController(t)
   502  		defer ctrl.Finish()
   503  
   504  		messenger := serviceMocks.NewMockMessenger(ctrl)
   505  		messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   506  
   507  		require.NoError(t, action(messenger))
   508  	})
   509  
   510  	t.Run("Decode error", func(t *testing.T) {
   511  		followup, action, err := (&offerReceived{}).ExecuteInbound(&MetaData{
   512  			transitionalPayload: transitionalPayload{
   513  				Action: Action{Msg: service.DIDCommMsgMap{"@type": map[int]int{}}},
   514  			},
   515  		})
   516  
   517  		require.Contains(t, fmt.Sprintf("%v", err), "got unconvertible type")
   518  		require.Nil(t, followup)
   519  		require.Nil(t, action)
   520  	})
   521  }
   522  
   523  func TestOfferReceived_ExecuteOutbound(t *testing.T) {
   524  	followup, action, err := (&offerReceived{}).ExecuteOutbound(&MetaData{})
   525  	require.Contains(t, fmt.Sprintf("%v", err), "is not implemented yet")
   526  	require.Nil(t, followup)
   527  	require.Nil(t, action)
   528  }
   529  
   530  func TestRequestSent_CanTransitionTo(t *testing.T) {
   531  	st := &requestSent{}
   532  	require.Equal(t, stateNameRequestSent, st.Name())
   533  	// common states
   534  	require.False(t, st.CanTransitionTo(&start{}))
   535  	require.True(t, st.CanTransitionTo(&abandoning{}))
   536  	require.False(t, st.CanTransitionTo(&done{}))
   537  	require.False(t, st.CanTransitionTo(&noOp{}))
   538  	// states for Issuer
   539  	require.False(t, st.CanTransitionTo(&proposalReceived{}))
   540  	require.False(t, st.CanTransitionTo(&offerSent{}))
   541  	require.False(t, st.CanTransitionTo(&requestReceived{}))
   542  	require.False(t, st.CanTransitionTo(&credentialIssued{}))
   543  	// states for Holder
   544  	require.False(t, st.CanTransitionTo(&proposalSent{}))
   545  	require.False(t, st.CanTransitionTo(&offerReceived{}))
   546  	require.False(t, st.CanTransitionTo(&requestSent{}))
   547  	require.True(t, st.CanTransitionTo(&credentialReceived{}))
   548  }
   549  
   550  func TestRequestSent_ExecuteInbound(t *testing.T) {
   551  	followup, action, err := (&requestSent{}).ExecuteInbound(&MetaData{})
   552  	require.NoError(t, err)
   553  	require.Equal(t, &noOp{}, followup)
   554  	require.NoError(t, action(nil))
   555  }
   556  
   557  func TestRequestSent_ExecuteOutbound(t *testing.T) {
   558  	followup, action, err := (&requestSent{}).ExecuteOutbound(&MetaData{})
   559  	require.NoError(t, err)
   560  	require.Equal(t, &noOp{}, followup)
   561  	require.NotNil(t, action)
   562  
   563  	ctrl := gomock.NewController(t)
   564  	defer ctrl.Finish()
   565  
   566  	messenger := serviceMocks.NewMockMessenger(ctrl)
   567  	messenger.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   568  
   569  	require.NoError(t, action(messenger))
   570  }
   571  
   572  func TestCredentialReceived_CanTransitionTo(t *testing.T) {
   573  	st := &credentialReceived{}
   574  	require.Equal(t, stateNameCredentialReceived, st.Name())
   575  	// common states
   576  	require.False(t, st.CanTransitionTo(&start{}))
   577  	require.True(t, st.CanTransitionTo(&abandoning{}))
   578  	require.True(t, st.CanTransitionTo(&done{}))
   579  	require.False(t, st.CanTransitionTo(&noOp{}))
   580  	// states for Issuer
   581  	require.False(t, st.CanTransitionTo(&proposalReceived{}))
   582  	require.False(t, st.CanTransitionTo(&offerSent{}))
   583  	require.False(t, st.CanTransitionTo(&requestReceived{}))
   584  	require.False(t, st.CanTransitionTo(&credentialIssued{}))
   585  	// states for Holder
   586  	require.False(t, st.CanTransitionTo(&proposalSent{}))
   587  	require.False(t, st.CanTransitionTo(&offerReceived{}))
   588  	require.False(t, st.CanTransitionTo(&requestSent{}))
   589  	require.False(t, st.CanTransitionTo(&credentialReceived{}))
   590  }
   591  
   592  func TestCredentialReceived_ExecuteInbound(t *testing.T) {
   593  	t.Run("Successes", func(t *testing.T) {
   594  		followup, action, err := (&credentialReceived{}).ExecuteInbound(&MetaData{issueCredentialV2: &IssueCredentialV2{}})
   595  		require.NoError(t, err)
   596  		require.Equal(t, &done{}, followup)
   597  		require.NotNil(t, action)
   598  
   599  		ctrl := gomock.NewController(t)
   600  		defer ctrl.Finish()
   601  
   602  		messenger := serviceMocks.NewMockMessenger(ctrl)
   603  		messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
   604  
   605  		require.NoError(t, action(messenger))
   606  	})
   607  }
   608  
   609  func TestCredentialReceived_ExecuteOutbound(t *testing.T) {
   610  	followup, action, err := (&credentialReceived{}).ExecuteOutbound(&MetaData{})
   611  	require.Contains(t, fmt.Sprintf("%v", err), "is not implemented yet")
   612  	require.Nil(t, followup)
   613  	require.Nil(t, action)
   614  }