github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/messaging/service/http/httpmsgsvc_test.go (about) 1 /* 2 * 3 * Copyright SecureKey Technologies Inc. All Rights Reserved. 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 * / 7 * 8 */ 9 10 package http 11 12 import ( 13 "encoding/json" 14 "fmt" 15 "net/http" 16 "testing" 17 "time" 18 19 "github.com/stretchr/testify/require" 20 21 "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service" 22 ) 23 24 func TestNewOverDIDComm(t *testing.T) { 25 tests := []struct { 26 name string 27 svcName string 28 purpose []string 29 handle RequestHandle 30 failure string 31 }{ 32 { 33 "Successfully create new HTTP Over DIDComm service with all args", 34 "sample-name-01", 35 []string{"prp-01", "prp-02"}, 36 newMockHandle(), "", 37 }, 38 { 39 "Successfully create new HTTP Over DIDComm service without purpose", 40 "sample-name-01", nil, newMockHandle(), "", 41 }, 42 { 43 "Failed to create new HTTP Over DIDComm service without name", 44 "", 45 []string{"prp-01", "prp-02"}, 46 newMockHandle(), errNameAndHandleMandatory, 47 }, 48 { 49 "Failed to create new HTTP Over DIDComm service without handle", 50 "sample-name-01", 51 []string{"prp-01", "prp-02"}, 52 nil, errNameAndHandleMandatory, 53 }, 54 } 55 56 t.Parallel() 57 58 for _, test := range tests { 59 tc := test 60 t.Run(tc.name, func(t *testing.T) { 61 svc, err := NewOverDIDComm(tc.svcName, tc.handle, tc.purpose...) 62 if tc.failure != "" { 63 require.Error(t, err) 64 require.Nil(t, svc) 65 require.Contains(t, err.Error(), tc.failure) 66 return 67 } 68 require.NoError(t, err) 69 require.NotNil(t, svc) 70 }) 71 } 72 } 73 74 func TestOverDIDComm_Name(t *testing.T) { 75 const sampleName = "sample-name-01" 76 77 svc, err := NewOverDIDComm("sample-name-01", newMockHandle(), "prp-01", "prp-02") 78 require.NoError(t, err) 79 require.NotNil(t, svc) 80 require.Equal(t, sampleName, svc.Name()) 81 } 82 83 func TestOverDIDComm_Accept(t *testing.T) { 84 tests := []struct { 85 name string 86 svcName string 87 purpose []string 88 testdatas []struct { 89 msgType string 90 purpose []string 91 result bool 92 } 93 }{ 94 { 95 "Test acceptance criteria with purpose", 96 "sample-name-01", 97 []string{"foo", "bar"}, 98 []struct { 99 msgType string 100 purpose []string 101 result bool 102 }{ 103 { 104 "sample-msgtype-01", []string{"baz"}, false, 105 }, 106 { 107 "sample-msgtype-01", []string{""}, false, 108 }, 109 { 110 "sample-msgtype-01", nil, false, 111 }, 112 { 113 "sample-msgtype-01", []string{"foo"}, false, 114 }, 115 { 116 "sample-msgtype-01", []string{"bar"}, false, 117 }, 118 { 119 "sample-msgtype-01", []string{"foo", "bar"}, false, 120 }, 121 { 122 OverDIDCommMsgRequestType, []string{"bla"}, false, 123 }, 124 { 125 OverDIDCommMsgRequestType, []string{}, false, 126 }, 127 { 128 OverDIDCommMsgRequestType, nil, false, 129 }, 130 { 131 OverDIDCommMsgRequestType, []string{"foo"}, true, 132 }, 133 { 134 OverDIDCommMsgRequestType, []string{"bar"}, true, 135 }, 136 { 137 OverDIDCommMsgRequestType, []string{"foo", "bar"}, true, 138 }, 139 }, 140 }, 141 { 142 "Test acceptance criteria without purpose", 143 "sample-name-01", nil, 144 []struct { 145 msgType string 146 purpose []string 147 result bool 148 }{ 149 { 150 "sample-msgtype-01", []string{"baz"}, false, 151 }, 152 { 153 "sample-msgtype-01", []string{""}, false, 154 }, 155 { 156 "sample-msgtype-01", nil, false, 157 }, 158 { 159 "sample-msgtype-01", []string{"foo"}, false, 160 }, 161 { 162 "sample-msgtype-01", []string{"bar"}, false, 163 }, 164 { 165 "sample-msgtype-01", []string{"foo", "bar"}, false, 166 }, 167 { 168 OverDIDCommMsgRequestType, []string{"bla"}, true, 169 }, 170 { 171 OverDIDCommMsgRequestType, []string{}, true, 172 }, 173 { 174 OverDIDCommMsgRequestType, nil, true, 175 }, 176 { 177 OverDIDCommMsgRequestType, []string{"foo"}, true, 178 }, 179 { 180 OverDIDCommMsgRequestType, []string{"bar"}, true, 181 }, 182 { 183 OverDIDCommMsgRequestType, []string{"foo", "bar"}, true, 184 }, 185 }, 186 }, 187 } 188 189 t.Parallel() 190 191 for _, test := range tests { 192 tc := test 193 t.Run(tc.name, func(t *testing.T) { 194 svc, err := NewOverDIDComm(tc.svcName, newMockHandle(), tc.purpose...) 195 require.NoError(t, err) 196 require.NotNil(t, svc) 197 for _, testdata := range tc.testdatas { 198 require.Equal(t, testdata.result, svc.Accept(testdata.msgType, testdata.purpose), 199 "testdata: %v", testdata) 200 } 201 }) 202 } 203 } 204 205 func TestOverDIDComm_HandleInbound(t *testing.T) { 206 tests := []struct { 207 name string 208 jsonStr string 209 expected struct { 210 method string 211 resourceURI string 212 body string 213 version string 214 header []struct { 215 key string 216 value string 217 } 218 failure string 219 } 220 }{ 221 { 222 name: "Testing request handle with empty didcomm msg", 223 jsonStr: `{"@id":"sample-id", "@type":"https://didcomm.org/http-over-didcomm/1.0/request"}`, 224 expected: struct { 225 method string 226 resourceURI string 227 body string 228 version string 229 header []struct { 230 key string 231 value string 232 } 233 failure string 234 }{ 235 http.MethodGet, "", "", "HTTP/1.1", nil, "", 236 }, 237 }, 238 { 239 name: "Testing request handle with valid didcomm msg", 240 jsonStr: `{"@id":"sample-id", "@type":"https://didcomm.org/http-over-didcomm/1.0/request", 241 "method":"POST", "resource-uri":"/sample-resource-uri", "headers":[{"name":"header1","value":"value1"}, 242 {"name":"header2","value":"value2"}],"body":"eyJjb2RlIjoiMDExMjM0In0="}`, 243 expected: struct { 244 method string 245 resourceURI string 246 body string 247 version string 248 header []struct { 249 key string 250 value string 251 } 252 failure string 253 }{ 254 http.MethodPost, "/sample-resource-uri", "011234", "HTTP/1.1", []struct { 255 key string 256 value string 257 }{{"header1", "value1"}, {"header2", "value2"}}, "", 258 }, 259 }, 260 { 261 name: "Testing failure in handleInBound due to invalid message body", 262 jsonStr: `{"@id":"sample-id", "@type":"https://didcomm.org/http-over-didcomm/1.0/request", "body":"--$#@!"}`, 263 expected: struct { 264 method string 265 resourceURI string 266 body string 267 version string 268 header []struct { 269 key string 270 value string 271 } 272 failure string 273 }{ 274 "", "", "", "", nil, "unable to decode message body", 275 }, 276 }, 277 { 278 name: "Testing failure in handleInBound due to invalid request fields", 279 jsonStr: `{"@id":"sample-id", "@type":"https://didcomm.org/http-over-didcomm/1.0/request", "method":"--$#@!"}`, 280 expected: struct { 281 method string 282 resourceURI string 283 body string 284 version string 285 header []struct { 286 key string 287 value string 288 } 289 failure string 290 }{ 291 "", "", "", "", nil, "failed to create http request from incoming message", 292 }, 293 }, 294 } 295 296 rqCh := make(chan *http.Request) 297 298 handle := func(id string, rq *http.Request) error { 299 require.Equal(t, "sample-id", id) 300 rqCh <- rq 301 302 return nil 303 } 304 305 svc, err := NewOverDIDComm("sample-service", handle) 306 require.NoError(t, err) 307 require.NotNil(t, svc) 308 309 t.Parallel() 310 311 for _, test := range tests { 312 tc := test 313 t.Run(tc.name, func(t *testing.T) { 314 didCommMsg, err := service.ParseDIDCommMsgMap([]byte(tc.jsonStr)) 315 require.NoError(t, err) 316 317 if tc.expected.failure != "" { 318 _, err = svc.HandleInbound(didCommMsg, service.EmptyDIDCommContext()) 319 require.Error(t, err) 320 require.Contains(t, err.Error(), tc.expected.failure) 321 return 322 } 323 324 go func() { 325 _, err = svc.HandleInbound(didCommMsg, service.EmptyDIDCommContext()) 326 require.NoError(t, err) 327 }() 328 329 select { 330 case rqst := <-rqCh: 331 // test request properties 332 require.Equal(t, tc.expected.method, rqst.Method) 333 require.Equal(t, tc.expected.version, rqst.Proto) 334 require.Equal(t, tc.expected.resourceURI, rqst.URL.String()) 335 336 // test body 337 if tc.expected.body != "" { 338 v := struct { 339 Code string `json:"code"` 340 }{} 341 342 require.NoError(t, json.NewDecoder(rqst.Body).Decode(&v)) 343 require.Equal(t, tc.expected.body, v.Code) 344 } 345 346 // test headers 347 for _, h := range tc.expected.header { 348 require.Equal(t, h.value, rqst.Header.Get(h.key)) 349 } 350 351 case <-time.After(2 * time.Second): 352 require.Fail(t, "didn't receive post event responded") 353 } 354 }) 355 } 356 } 357 358 func TestOverDIDComm_HandleInbound_InvalidMsg(t *testing.T) { 359 svc, err := NewOverDIDComm("sample-service", newMockHandle()) 360 require.NoError(t, err) 361 require.NotNil(t, svc) 362 363 _, err = svc.HandleInbound(&mockMsg{err: fmt.Errorf("sample-error")}, service.EmptyDIDCommContext()) 364 require.Error(t, err) 365 require.Contains(t, err.Error(), "unable to decode DID comm message") 366 } 367 368 func newMockHandle() RequestHandle { 369 return func(string, *http.Request) error { return nil } 370 } 371 372 type mockMsg struct { 373 *service.DIDCommMsgMap 374 err error 375 } 376 377 func (m *mockMsg) Decode(v interface{}) error { 378 return m.err 379 }