github.com/hyperledger/aries-framework-go@v0.3.2/pkg/client/outofbandv2/client_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package outofbandv2 8 9 import ( 10 "encoding/base64" 11 "encoding/json" 12 "errors" 13 "fmt" 14 "testing" 15 "time" 16 17 "github.com/google/uuid" 18 "github.com/stretchr/testify/require" 19 20 "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service" 21 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator" 22 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator" 23 oobv2 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofbandv2" 24 mockroute "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/mediator" 25 mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms" 26 mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider" 27 mockstore "github.com/hyperledger/aries-framework-go/pkg/mock/storage" 28 ) 29 30 func TestNew(t *testing.T) { 31 t.Run("returns client", func(t *testing.T) { 32 c, err := New(withTestProvider()) 33 require.NoError(t, err) 34 require.NotNil(t, c) 35 }) 36 37 t.Run("client creation fails with empty service map", func(t *testing.T) { 38 badProvider := withTestProvider() 39 badProvider.ServiceMap = map[string]interface{}{} 40 41 c, err := New(badProvider) 42 require.EqualError(t, err, "failed to cast service out-of-band/2.0 as a dependency") 43 require.Empty(t, c) 44 }) 45 46 t.Run("client creation fails with service call returning error", func(t *testing.T) { 47 badProvider := withTestProvider() 48 badProvider.ServiceErr = fmt.Errorf("service error") 49 50 c, err := New(badProvider) 51 require.EqualError(t, err, "failed to look up service out-of-band/2.0 : service error") 52 require.Empty(t, c) 53 }) 54 } 55 56 func TestCreateInvitation(t *testing.T) { 57 t.Run("sets an id", func(t *testing.T) { 58 c, err := New(withTestProvider()) 59 require.NoError(t, err) 60 inv, err := c.CreateInvitation() 61 require.NoError(t, err) 62 require.NotEmpty(t, inv.ID) 63 }) 64 t.Run("sets correct type", func(t *testing.T) { 65 c, err := New(withTestProvider()) 66 require.NoError(t, err) 67 inv, err := c.CreateInvitation() 68 require.NoError(t, err) 69 require.Equal(t, "https://didcomm.org/out-of-band/2.0/invitation", inv.Type) 70 }) 71 t.Run("WithLabel", func(t *testing.T) { 72 c, err := New(withTestProvider()) 73 require.NoError(t, err) 74 expected := uuid.New().String() 75 inv, err := c.CreateInvitation(WithLabel(expected)) 76 require.NoError(t, err) 77 require.Equal(t, expected, inv.Label) 78 }) 79 t.Run("WithFrom", func(t *testing.T) { 80 c, err := New(withTestProvider()) 81 require.NoError(t, err) 82 expected := uuid.New().String() 83 inv, err := c.CreateInvitation(WithFrom(expected)) 84 require.NoError(t, err) 85 require.Equal(t, expected, inv.From) 86 }) 87 t.Run("WithGoal", func(t *testing.T) { 88 c, err := New(withTestProvider()) 89 require.NoError(t, err) 90 expectedGoal := uuid.New().String() 91 expectedGoalCode := uuid.New().String() 92 inv, err := c.CreateInvitation(WithGoal(expectedGoal, expectedGoalCode)) 93 require.NoError(t, err) 94 require.Equal(t, expectedGoal, inv.Body.Goal) 95 require.Equal(t, expectedGoalCode, inv.Body.GoalCode) 96 }) 97 t.Run("WithAttachments", func(t *testing.T) { 98 c, err := New(withTestProvider()) 99 require.NoError(t, err) 100 expected := dummyAttachment(t) 101 inv, err := c.CreateInvitation(WithAttachments(expected)) 102 require.NoError(t, err) 103 require.Contains(t, inv.Requests, expected) 104 }) 105 t.Run("WithAttachments", func(t *testing.T) { 106 c, err := New(withTestProvider()) 107 require.NoError(t, err) 108 expected := dummyAttachment(t) 109 inv, err := c.CreateInvitation(WithAttachments(expected)) 110 require.NoError(t, err) 111 require.Contains(t, inv.Requests, expected) 112 }) 113 t.Run("fails to save", func(t *testing.T) { 114 expectErr := fmt.Errorf("expected error") 115 116 prov := withTestProvider() 117 prov.ServiceMap[oobv2.Name] = &stubOOBService{saveInvErr: expectErr} 118 119 c, err := New(prov) 120 require.NoError(t, err) 121 122 _, err = c.CreateInvitation() 123 require.Error(t, err) 124 require.ErrorIs(t, err, expectErr) 125 }) 126 } 127 128 func TestAcceptInvitation(t *testing.T) { 129 t.Run("returns connection ID", func(t *testing.T) { 130 provider := withTestProvider() 131 provider.ServiceMap = map[string]interface{}{ 132 oobv2.Name: &stubOOBService{ 133 acceptInvFunc: func(*oobv2.Invitation) error { 134 return nil 135 }, 136 connID: "123", 137 }, 138 } 139 c, err := New(provider) 140 require.NoError(t, err) 141 connID, err := c.AcceptInvitation(&oobv2.Invitation{}) 142 require.NoError(t, err) 143 require.NotEmpty(t, connID) 144 }) 145 t.Run("wraps error from outofband service", func(t *testing.T) { 146 expected := errors.New("test") 147 provider := withTestProvider() 148 provider.ServiceMap = map[string]interface{}{ 149 oobv2.Name: &stubOOBService{ 150 acceptInvFunc: func(*oobv2.Invitation) error { 151 return expected 152 }, 153 }, 154 } 155 c, err := New(provider) 156 require.NoError(t, err) 157 connID, err := c.AcceptInvitation(&oobv2.Invitation{}) 158 require.Error(t, err) 159 require.Empty(t, connID) 160 }) 161 } 162 163 func dummyAttachment(t *testing.T) *decorator.AttachmentV2 { 164 t.Helper() 165 166 return base64Attachment(t, &didcommMsg{ 167 ID: uuid.New().String(), 168 Type: uuid.New().String(), 169 }) 170 } 171 172 func base64Attachment(t *testing.T, data interface{}) *decorator.AttachmentV2 { 173 t.Helper() 174 175 bytes, err := json.Marshal(data) 176 require.NoError(t, err) 177 178 return &decorator.AttachmentV2{ 179 ID: uuid.New().String(), 180 Description: uuid.New().String(), 181 FileName: uuid.New().String(), 182 MediaType: uuid.New().String(), 183 LastModTime: time.Now(), 184 ByteCount: 0, 185 Data: decorator.AttachmentData{ 186 Base64: base64.StdEncoding.EncodeToString(bytes), 187 }, 188 } 189 } 190 191 type didcommMsg struct { 192 ID string 193 Type string 194 } 195 196 func withTestProvider() *mockprovider.Provider { 197 mockKey, err := mockkms.CreateMockED25519KeyHandle() 198 if err != nil { 199 return nil 200 } 201 202 return &mockprovider.Provider{ 203 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 204 StorageProviderValue: mockstore.NewMockStoreProvider(), 205 KMSValue: &mockkms.KeyManager{CreateKeyValue: mockKey}, 206 ServiceMap: map[string]interface{}{ 207 mediator.Coordination: &mockroute.MockMediatorSvc{Connections: []string{"xyz"}}, 208 oobv2.Name: &stubOOBService{}, 209 }, 210 ServiceEndpointValue: "endpoint", 211 } 212 } 213 214 type stubOOBService struct { 215 service.Event 216 acceptInvFunc func(*oobv2.Invitation) error 217 connID string 218 saveInvErr error 219 } 220 221 func (s *stubOOBService) SaveInvitation(i *oobv2.Invitation) error { 222 return s.saveInvErr 223 } 224 225 func (s *stubOOBService) AcceptInvitation(i *oobv2.Invitation, opts ...oobv2.AcceptOption) (string, error) { 226 if s.acceptInvFunc != nil { 227 return s.connID, s.acceptInvFunc(i) 228 } 229 230 return "", nil 231 }