github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/protocol/messagepickup/service_test.go (about) 1 /* 2 Copyright Scoir Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package messagepickup 8 9 import ( 10 "encoding/json" 11 "errors" 12 "fmt" 13 "testing" 14 "time" 15 16 "github.com/stretchr/testify/require" 17 18 "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service" 19 "github.com/hyperledger/aries-framework-go/pkg/didcomm/transport" 20 mockdispatcher "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/dispatcher" 21 mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider" 22 mockstore "github.com/hyperledger/aries-framework-go/pkg/mock/storage" 23 "github.com/hyperledger/aries-framework-go/pkg/store/connection" 24 "github.com/hyperledger/aries-framework-go/spi/storage" 25 ) 26 27 const ( 28 MYDID = "sample-my-did" 29 THEIRDID = "sample-their-did" 30 ) 31 32 func TestServiceNew(t *testing.T) { 33 t.Run("test new service - success", func(t *testing.T) { 34 svc, err := getService() 35 require.NoError(t, err) 36 require.Equal(t, MessagePickup, svc.Name()) 37 }) 38 39 t.Run("test new service name - store error", func(t *testing.T) { 40 svc, err := New(&mockprovider.Provider{ 41 StorageProviderValue: &mockstore.MockStoreProvider{ 42 ErrOpenStoreHandle: fmt.Errorf("error opening the store"), 43 }, 44 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 45 OutboundDispatcherValue: nil, 46 PackagerValue: &mockPackager{}, 47 }) 48 49 require.Error(t, err) 50 require.Contains(t, err.Error(), "open mailbox store") 51 require.Nil(t, svc) 52 }) 53 } 54 55 func TestService_Initialize(t *testing.T) { 56 t.Run("success", func(t *testing.T) { 57 prov := &mockprovider.Provider{ 58 StorageProviderValue: mockstore.NewMockStoreProvider(), 59 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 60 OutboundDispatcherValue: nil, 61 PackagerValue: &mockPackager{}, 62 } 63 64 svc := Service{} 65 66 err := svc.Initialize(prov) 67 require.NoError(t, err) 68 69 // second init is no-op 70 err = svc.Initialize(prov) 71 require.NoError(t, err) 72 }) 73 74 t.Run("failure, not given a valid provider", func(t *testing.T) { 75 svc := Service{} 76 77 err := svc.Initialize("not a provider") 78 require.Error(t, err) 79 require.Contains(t, err.Error(), "expected provider of type") 80 }) 81 } 82 83 func TestHandleInbound(t *testing.T) { 84 t.Run("test MessagePickupService.HandleInbound() - Status", func(t *testing.T) { 85 const jsonStr = `{ 86 "@id": "123456781", 87 "@type": "https://didcomm.org/messagepickup/1.0/status", 88 "message_count": 7, 89 "duration_waited": 3600, 90 "last_added_time": "2019-05-01T12:00:00Z", 91 "last_delivered_time": "2019-05-01T12:00:00Z", 92 "last_removed_time": "2019-05-01T12:00:00Z", 93 "total_size": 8096 94 }` 95 96 svc, err := getService() 97 require.NoError(t, err) 98 99 msg, err := service.ParseDIDCommMsgMap([]byte(jsonStr)) 100 require.NoError(t, err) 101 102 statusCh := make(chan Status) 103 svc.setStatusCh(msg.ID(), statusCh) 104 105 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(MYDID, THEIRDID, nil)) 106 require.NoError(t, err) 107 108 tyme, err := time.Parse(time.RFC3339, "2019-05-01T12:00:00Z") 109 require.NoError(t, err) 110 111 select { 112 case x := <-svc.statusMap[msg.ID()]: 113 require.NotNil(t, x) 114 require.Equal(t, "123456781", x.ID) 115 require.Equal(t, 3600, x.DurationWaited) 116 require.Equal(t, tyme, x.LastAddedTime) 117 require.Equal(t, tyme, x.LastDeliveredTime) 118 require.Equal(t, tyme, x.LastRemovedTime) 119 require.Equal(t, 7, x.MessageCount) 120 require.Equal(t, 8096, x.TotalSize) 121 122 case <-time.After(2 * time.Second): 123 require.Fail(t, "didn't receive message to handle") 124 } 125 }) 126 127 t.Run("test MessagePickupService.HandleInbound() - unknown type", func(t *testing.T) { 128 const jsonStr = `{ 129 "@id": "123456781", 130 "@type": "unknown" 131 }` 132 133 svc, err := getService() 134 require.NoError(t, err) 135 136 msg, err := service.ParseDIDCommMsgMap([]byte(jsonStr)) 137 require.NoError(t, err) 138 139 statusCh := make(chan Status) 140 svc.setStatusCh(msg.ID(), statusCh) 141 142 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(MYDID, THEIRDID, nil)) 143 require.NoError(t, err) 144 }) 145 146 t.Run("test MessagePickupService.HandleInbound() - Status - msg error", func(t *testing.T) { 147 svc, err := getService() 148 require.NoError(t, err) 149 150 msg := &service.DIDCommMsgMap{"@id": map[int]int{}} 151 err = svc.handleStatus(msg) 152 require.Error(t, err) 153 require.Contains(t, err.Error(), "status message unmarshal") 154 }) 155 156 t.Run("test MessagePickupService.HandleInbound() - StatusRequest success", func(t *testing.T) { 157 const jsonStr = `{ 158 "@id": "123456781", 159 "@type": "https://didcomm.org/messagepickup/1.0/status-request", 160 "~thread" : {"thid": "2d798168-8abf-4410-8535-bc1e8406a5ff"} 161 }` 162 msgID := make(chan string) 163 164 tyme, err := time.Parse(time.RFC3339, "2019-05-01T12:00:00Z") 165 require.NoError(t, err) 166 167 svc, err := New(&mockprovider.Provider{ 168 StorageProviderValue: mockstore.NewMockStoreProvider(), 169 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 170 OutboundDispatcherValue: &mockdispatcher.MockOutbound{ 171 ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error { 172 require.Equal(t, myDID, MYDID) 173 require.Equal(t, theirDID, THEIRDID) 174 175 reqMsgMap, ok := msg.(service.DIDCommMsgMap) 176 require.True(t, ok) 177 178 request := &Status{} 179 180 err = reqMsgMap.Decode(request) 181 require.NoError(t, err) 182 183 require.Equal(t, 1, request.MessageCount) 184 require.Equal(t, tyme, request.LastAddedTime) 185 require.Equal(t, tyme, request.LastDeliveredTime) 186 require.Equal(t, tyme, request.LastRemovedTime) 187 require.Equal(t, 3096, request.TotalSize) 188 require.Equal(t, "2d798168-8abf-4410-8535-bc1e8406a5ff", request.Thread.PID) 189 190 msgID <- request.ID 191 192 return nil 193 }, 194 }, 195 PackagerValue: &mockPackager{}, 196 }) 197 require.NoError(t, err) 198 199 b, err := json.Marshal(inbox{ 200 DID: "sample-their-did", 201 MessageCount: 1, 202 LastAddedTime: tyme, 203 LastDeliveredTime: tyme, 204 LastRemovedTime: tyme, 205 TotalSize: 3096, 206 Messages: []byte(`[{"test": "message"}]`), 207 }) 208 require.NoError(t, err) 209 210 err = svc.msgStore.Put(THEIRDID, b) 211 require.NoError(t, err) 212 213 msg, err := service.ParseDIDCommMsgMap([]byte(jsonStr)) 214 require.NoError(t, err) 215 216 go func() { 217 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(MYDID, THEIRDID, nil)) 218 require.NoError(t, err) 219 }() 220 221 select { 222 case id := <-msgID: 223 require.NotNil(t, id) 224 require.Equal(t, "123456781", id) 225 226 case <-time.After(2 * time.Second): 227 require.Fail(t, "didn't receive message to handle") 228 } 229 }) 230 231 t.Run("test MessagePickupService.HandleInbound() - StatusRequest - msg error", func(t *testing.T) { 232 svc, err := getService() 233 require.NoError(t, err) 234 235 msg := &service.DIDCommMsgMap{"@id": map[int]int{}} 236 err = svc.handleStatusRequest(msg, MYDID, THEIRDID) 237 require.Error(t, err) 238 require.Contains(t, err.Error(), "status request message unmarshal") 239 }) 240 241 t.Run("test MessagePickupService.HandleInbound() - StatusRequest - get error", func(t *testing.T) { 242 const jsonStr = `{ 243 "@id": "123456781", 244 "@type": "https://didcomm.org/messagepickup/1.0/status-request", 245 "~thread" : {"thid": "2d798168-8abf-4410-8535-bc1e8406a5ff"} 246 }` 247 248 svc, err := getService() 249 require.NoError(t, err) 250 251 msg, err := service.ParseDIDCommMsgMap([]byte(jsonStr)) 252 require.NoError(t, err) 253 254 err = svc.handleStatusRequest(msg, MYDID, "not found") 255 require.Error(t, err) 256 require.Contains(t, err.Error(), "error in status request getting inbox") 257 }) 258 259 t.Run("test MessagePickupService.HandleInbound() - BatchPickup", func(t *testing.T) { 260 msgID := make(chan string) 261 262 tyme, err := time.Parse(time.RFC3339, "2019-05-01T12:00:00Z") 263 require.NoError(t, err) 264 265 svc, err := New(&mockprovider.Provider{ 266 StorageProviderValue: mockstore.NewMockStoreProvider(), 267 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 268 OutboundDispatcherValue: &mockdispatcher.MockOutbound{ 269 ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error { 270 require.Equal(t, myDID, MYDID) 271 require.Equal(t, theirDID, THEIRDID) 272 273 reqMsgMap, ok := msg.(service.DIDCommMsgMap) 274 require.True(t, ok) 275 276 request := &Batch{} 277 278 err = reqMsgMap.Decode(request) 279 require.NoError(t, err) 280 281 require.Equal(t, 2, len(request.Messages)) 282 283 msgID <- request.ID 284 285 return nil 286 }, 287 }, 288 PackagerValue: &mockPackager{}, 289 }) 290 require.NoError(t, err) 291 292 b, err := json.Marshal(inbox{ 293 DID: "sample-their-did", 294 MessageCount: 2, 295 LastAddedTime: tyme, 296 LastDeliveredTime: tyme, 297 LastRemovedTime: tyme, 298 TotalSize: 3096, 299 Messages: []byte(`[{"id": "8910"}, {"id": "8911"}, {"id": "8912"}]`), 300 }) 301 require.NoError(t, err) 302 303 err = svc.msgStore.Put(THEIRDID, b) 304 require.NoError(t, err) 305 306 msg, err := service.ParseDIDCommMsgMap([]byte(`{ 307 "@id": "123456781", 308 "@type": "https://didcomm.org/messagepickup/1.0/batch-pickup", 309 "batch_size": 2, 310 "~thread" : {"thid": "2d798168-8abf-4410-8535-bc1e8406a5ff"} 311 }`)) 312 require.NoError(t, err) 313 314 go func() { 315 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(MYDID, THEIRDID, nil)) 316 require.NoError(t, err) 317 }() 318 319 select { 320 case id := <-msgID: 321 require.NotNil(t, id) 322 require.Equal(t, id, "123456781") 323 324 case <-time.After(2 * time.Second): 325 require.Fail(t, "didn't receive message to handle") 326 } 327 }) 328 329 t.Run("test MessagePickupService.HandleInbound() - BatchPickup - msg error", func(t *testing.T) { 330 svc, err := getService() 331 require.NoError(t, err) 332 333 msg := &service.DIDCommMsgMap{"@id": map[int]int{}} 334 err = svc.handleBatchPickup(msg, MYDID, THEIRDID) 335 require.Error(t, err) 336 require.Contains(t, err.Error(), "batch pickup message unmarshal") 337 }) 338 339 t.Run("test MessagePickupService.HandleInbound() - BatchPickup - get error", func(t *testing.T) { 340 mockStore := mockstore.NewMockStoreProvider() 341 svc, err := New(&mockprovider.Provider{ 342 StorageProviderValue: mockStore, 343 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 344 OutboundDispatcherValue: nil, 345 PackagerValue: &mockPackager{}, 346 }) 347 require.NoError(t, err) 348 349 mockStore.Store.ErrGet = errors.New("error get inbox") 350 351 msg, err := service.ParseDIDCommMsgMap([]byte(`{ 352 "@id": "123456781", 353 "@type": "https://didcomm.org/messagepickup/1.0/batch-pickup", 354 "batch_size": 2, 355 "~thread" : {"thid": "2d798168-8abf-4410-8535-bc1e8406a5ff"} 356 }`)) 357 require.NoError(t, err) 358 359 err = svc.handleBatchPickup(msg, MYDID, THEIRDID) 360 require.Error(t, err) 361 require.Contains(t, err.Error(), "error get inbox") 362 }) 363 364 t.Run("test MessagePickupService.pullMessages() - put inbox error", func(t *testing.T) { 365 mockStore := mockstore.NewMockStoreProvider() 366 svc, err := New(&mockprovider.Provider{ 367 StorageProviderValue: mockStore, 368 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 369 OutboundDispatcherValue: nil, 370 PackagerValue: &mockPackager{}, 371 }) 372 require.NoError(t, err) 373 374 b, err := json.Marshal(&inbox{DID: THEIRDID}) 375 require.NoError(t, err) 376 377 err = mockStore.Store.Put(THEIRDID, b) 378 require.NoError(t, err) 379 380 mockStore.Store.ErrPut = errors.New("error put inbox") 381 382 msg, err := service.ParseDIDCommMsgMap([]byte(`{ 383 "@id": "123456781", 384 "@type": "https://didcomm.org/messagepickup/1.0/batch-pickup", 385 "batch_size": 2, 386 "~thread" : {"thid": "2d798168-8abf-4410-8535-bc1e8406a5ff"} 387 }`)) 388 require.NoError(t, err) 389 390 err = svc.handleBatchPickup(msg, MYDID, THEIRDID) 391 require.Error(t, err) 392 require.Contains(t, err.Error(), "error put inbox") 393 }) 394 395 t.Run("test MessagePickupService.HandleInbound() - Batch", func(t *testing.T) { 396 const jsonStr = `{ 397 "@id": "123456781", 398 "@type": "https://didcomm.org/messagepickup/1.0/batch", 399 "messages~attach": [ 400 { 401 "@id" : "06ca25f6-d3c5-48ac-8eee-1a9e29120c31", 402 "message" : "{\"id\": \"8910\"}" 403 }, 404 { 405 "@id" : "344a51cf-379f-40ab-ab2c-711dab3f53a9a", 406 "message" : "{\"id\": \"8910\"}" 407 } 408 ] 409 }` 410 411 svc, err := getService() 412 require.NoError(t, err) 413 414 msg, err := service.ParseDIDCommMsgMap([]byte(jsonStr)) 415 require.NoError(t, err) 416 417 batchCh := make(chan Batch) 418 svc.setBatchCh(msg.ID(), batchCh) 419 420 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(MYDID, THEIRDID, nil)) 421 require.NoError(t, err) 422 423 select { 424 case x := <-svc.batchMap[msg.ID()]: 425 require.NotNil(t, x) 426 require.Equal(t, "123456781", x.ID) 427 require.Equal(t, 2, len(x.Messages)) 428 429 case <-time.After(2 * time.Second): 430 require.Fail(t, "didn't receive message to handle") 431 } 432 }) 433 434 t.Run("test MessagePickupService.HandleInbound() - Batch - msg error", func(t *testing.T) { 435 svc, err := getService() 436 require.NoError(t, err) 437 438 msg := &service.DIDCommMsgMap{"@id": map[int]int{}} 439 err = svc.handleBatch(msg) 440 require.Error(t, err) 441 require.Contains(t, err.Error(), "batch message unmarshal") 442 }) 443 444 t.Run("test MessagePickupService.HandleInbound() - Noop", func(t *testing.T) { 445 const jsonStr = `{ 446 "@id": "123456781", 447 "@type": "https://didcomm.org/messagepickup/1.0/noop" 448 }` 449 450 svc, err := getService() 451 require.NoError(t, err) 452 453 msg, err := service.ParseDIDCommMsgMap([]byte(jsonStr)) 454 require.NoError(t, err) 455 456 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(MYDID, THEIRDID, nil)) 457 require.NoError(t, err) 458 }) 459 460 t.Run("test MessagePickupService.HandleInbound() - Noop - msg error", func(t *testing.T) { 461 svc, err := getService() 462 require.NoError(t, err) 463 464 msg := &service.DIDCommMsgMap{"@id": map[int]int{}} 465 err = svc.handleNoop(msg) 466 require.Error(t, err) 467 require.Contains(t, err.Error(), "noop message unmarshal") 468 }) 469 } 470 471 func TestAccept(t *testing.T) { 472 t.Run("test MessagePickupService.Accept() - Status", func(t *testing.T) { 473 svc, err := getService() 474 require.NoError(t, err) 475 476 require.True(t, svc.Accept(StatusMsgType)) 477 require.True(t, svc.Accept(StatusRequestMsgType)) 478 require.True(t, svc.Accept(NoopMsgType)) 479 require.True(t, svc.Accept(BatchMsgType)) 480 require.True(t, svc.Accept(BatchPickupMsgType)) 481 require.False(t, svc.Accept("random-msg-type")) 482 }) 483 } 484 485 func TestAddMessage(t *testing.T) { 486 t.Run("test MessagePickupService.AddMessage() to new inbox - success", func(t *testing.T) { 487 mockStore := mockstore.NewMockStoreProvider() 488 svc, err := New(&mockprovider.Provider{ 489 StorageProviderValue: mockStore, 490 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 491 OutboundDispatcherValue: nil, 492 PackagerValue: &mockPackager{}, 493 }) 494 require.NoError(t, err) 495 496 message := []byte(`{ 497 Protected: "eyJ0eXAiOiJwcnMuaHlwZXJsZWRnZXIuYXJpZXMtYXV0aC1t" + 498 "ZXNzYWdlIiwiYWxnIjoiRUNESC1TUytYQzIwUEtXIiwiZW5jIjoiWEMyMFAifQ", 499 IV: "JS2FxjEKdndnt-J7QX5pEnVwyBTu0_3d", 500 CipherText: "qQyzvajdvCDJbwxM", 501 Tag: "2FqZMMQuNPYfL0JsSkj8LQ", 502 }`) 503 504 err = svc.AddMessage(message, THEIRDID) 505 require.NoError(t, err) 506 507 b, err := mockStore.Store.Get(THEIRDID) 508 require.NoError(t, err) 509 510 ibx := &inbox{} 511 err = json.Unmarshal(b, ibx) 512 require.NoError(t, err) 513 514 require.Equal(t, 1, ibx.MessageCount) 515 }) 516 517 t.Run("test MessagePickupService.AddMessage() to existing inbox - success", func(t *testing.T) { 518 mockStore := mockstore.NewMockStoreProvider() 519 svc, err := New(&mockprovider.Provider{ 520 StorageProviderValue: mockStore, 521 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 522 OutboundDispatcherValue: nil, 523 PackagerValue: &mockPackager{}, 524 }) 525 require.NoError(t, err) 526 527 message := []byte(`{ 528 Protected: "eyJ0eXAiOiJwcnMuaHlwZXJsZWRnZXIuYXJpZXMtYXV0aC1t" + 529 "ZXNzYWdlIiwiYWxnIjoiRUNESC1TUytYQzIwUEtXIiwiZW5jIjoiWEMyMFAifQ", 530 IV: "JS2FxjEKdndnt-J7QX5pEnVwyBTu0_3d", 531 CipherText: "qQyzvajdvCDJbwxM", 532 Tag: "2FqZMMQuNPYfL0JsSkj8LQ", 533 }`) 534 535 tyme, err := time.Parse(time.RFC3339, "2019-05-01T12:00:00Z") 536 require.NoError(t, err) 537 538 b, err := json.Marshal(inbox{ 539 DID: "sample-their-did", 540 MessageCount: 3, 541 LastAddedTime: tyme, 542 LastDeliveredTime: tyme, 543 LastRemovedTime: tyme, 544 TotalSize: 3096, 545 Messages: []byte(`[{"id": "8910"}, {"id": "8911"}, {"id": "8912"}]`), 546 }) 547 require.NoError(t, err) 548 549 err = svc.msgStore.Put(THEIRDID, b) 550 require.NoError(t, err) 551 552 err = svc.AddMessage(message, THEIRDID) 553 require.NoError(t, err) 554 555 b, err = mockStore.Store.Get(THEIRDID) 556 require.NoError(t, err) 557 558 ibx := &inbox{} 559 err = json.Unmarshal(b, ibx) 560 require.NoError(t, err) 561 562 require.Equal(t, 4, ibx.MessageCount) 563 }) 564 565 t.Run("test MessagePickupService.AddMessage() - put error", func(t *testing.T) { 566 mockStore := mockstore.NewMockStoreProvider() 567 svc, err := New(&mockprovider.Provider{ 568 StorageProviderValue: mockStore, 569 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 570 OutboundDispatcherValue: nil, 571 PackagerValue: &mockPackager{}, 572 }) 573 require.NoError(t, err) 574 575 b, err := json.Marshal(inbox{ 576 DID: "sample-their-did", 577 }) 578 require.NoError(t, err) 579 580 // seed data for initial get in AddMessage 581 err = mockStore.Store.Put(THEIRDID, b) 582 require.NoError(t, err) 583 584 mockStore.Store.ErrPut = errors.New("error put") 585 586 message := []byte("") 587 588 err = svc.AddMessage(message, THEIRDID) 589 require.Error(t, err) 590 require.Contains(t, err.Error(), "error put") 591 }) 592 593 t.Run("test MessagePickupService.AddMessage() - get error", func(t *testing.T) { 594 mockStore := mockstore.NewMockStoreProvider() 595 svc, err := New(&mockprovider.Provider{ 596 StorageProviderValue: mockStore, 597 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 598 OutboundDispatcherValue: nil, 599 PackagerValue: &mockPackager{}, 600 }) 601 require.NoError(t, err) 602 603 message := []byte("") 604 605 mockStore.Store.ErrGet = errors.New("error get") 606 607 err = svc.AddMessage(message, "not found") 608 require.Error(t, err) 609 require.Contains(t, err.Error(), "error get") 610 }) 611 } 612 613 func TestStatusRequest(t *testing.T) { 614 t.Run("test MessagePickupService.StatusRequest() - success", func(t *testing.T) { 615 msgID := make(chan string) 616 s := make(map[string][]byte) 617 618 provider := &mockprovider.Provider{ 619 StorageProviderValue: mockstore.NewMockStoreProvider(), 620 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 621 OutboundDispatcherValue: &mockdispatcher.MockOutbound{ 622 ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error { 623 require.Equal(t, myDID, MYDID) 624 require.Equal(t, theirDID, THEIRDID) 625 626 request, ok := msg.(*StatusRequest) 627 require.True(t, ok) 628 629 msgID <- request.ID 630 631 return nil 632 }, 633 }, 634 PackagerValue: &mockPackager{}, 635 } 636 637 connRec := &connection.Record{ 638 ConnectionID: "conn", MyDID: MYDID, TheirDID: THEIRDID, State: "completed", 639 } 640 connBytes, err := json.Marshal(connRec) 641 require.NoError(t, err) 642 643 s["conn_conn1"] = connBytes 644 645 r, err := connection.NewRecorder(provider) 646 require.NoError(t, err) 647 err = r.SaveConnectionRecord(connRec) 648 require.NoError(t, err) 649 650 svc, err := New(provider) 651 require.NoError(t, err) 652 653 go func() { 654 status, err := svc.StatusRequest("conn") 655 require.NoError(t, err) 656 657 require.Equal(t, 6, status.MessageCount) 658 }() 659 660 select { 661 case id := <-msgID: 662 require.NotNil(t, id) 663 s := Status{ 664 MessageCount: 6, 665 } 666 667 // outbound has been handled, simulate a callback to finish the trip 668 ch := svc.getStatusCh(id) 669 ch <- s 670 671 case <-time.After(2 * time.Second): 672 require.Fail(t, "didn't receive message to handle") 673 } 674 }) 675 676 t.Run("test MessagePickupService.StatusRequest() - connection error", func(t *testing.T) { 677 svc, err := getService() 678 require.NoError(t, err) 679 680 expected := errors.New("get error") 681 svc.connectionLookup = &connectionsStub{ 682 getConnRecord: func(string) (*connection.Record, error) { 683 return nil, expected 684 }, 685 } 686 687 _, err = svc.StatusRequest("conn") 688 require.Error(t, err) 689 require.True(t, errors.Is(err, expected)) 690 }) 691 692 t.Run("test MessagePickupService.StatusRequest() - send to DID error", func(t *testing.T) { 693 s := make(map[string][]byte) 694 695 provider := &mockprovider.Provider{ 696 StorageProviderValue: mockstore.NewMockStoreProvider(), 697 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 698 OutboundDispatcherValue: &mockdispatcher.MockOutbound{ 699 ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error { 700 return errors.New("send error") 701 }, 702 }, 703 PackagerValue: &mockPackager{}, 704 } 705 706 connRec := &connection.Record{ 707 ConnectionID: "conn", MyDID: MYDID, TheirDID: THEIRDID, State: "completed", 708 } 709 connBytes, err := json.Marshal(connRec) 710 require.NoError(t, err) 711 712 s["conn_conn1"] = connBytes 713 714 r, err := connection.NewRecorder(provider) 715 require.NoError(t, err) 716 err = r.SaveConnectionRecord(connRec) 717 require.NoError(t, err) 718 719 svc, err := New(provider) 720 require.NoError(t, err) 721 722 _, err = svc.StatusRequest("conn") 723 require.Error(t, err) 724 require.Contains(t, err.Error(), "send route request") 725 }) 726 } 727 728 func TestBatchPickup(t *testing.T) { 729 t.Run("test MessagePickupService.BatchPickup() - success", func(t *testing.T) { 730 msgID := make(chan string) 731 s := make(map[string][]byte) 732 733 provider := &mockprovider.Provider{ 734 StorageProviderValue: mockstore.NewMockStoreProvider(), 735 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 736 OutboundDispatcherValue: &mockdispatcher.MockOutbound{ 737 ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error { 738 require.Equal(t, myDID, MYDID) 739 require.Equal(t, theirDID, THEIRDID) 740 741 reqMsgMap, ok := msg.(service.DIDCommMsgMap) 742 require.True(t, ok) 743 744 batchpickup := &BatchPickup{} 745 746 err := reqMsgMap.Decode(batchpickup) 747 require.NoError(t, err) 748 749 require.True(t, ok) 750 751 require.Equal(t, 1, batchpickup.BatchSize) 752 msgID <- batchpickup.ID 753 754 return nil 755 }, 756 }, 757 PackagerValue: &mockPackager{}, 758 InboundMessageHandlerValue: (&mockTransportProvider{}).InboundMessageHandler(), 759 } 760 761 connRec := &connection.Record{ 762 ConnectionID: "conn", MyDID: MYDID, TheirDID: THEIRDID, State: "completed", 763 } 764 connBytes, err := json.Marshal(connRec) 765 require.NoError(t, err) 766 767 s["conn_conn1"] = connBytes 768 769 r, err := connection.NewRecorder(provider) 770 require.NoError(t, err) 771 err = r.SaveConnectionRecord(connRec) 772 require.NoError(t, err) 773 774 svc, err := New(provider) 775 require.NoError(t, err) 776 777 go func() { 778 id := <-msgID 779 require.NotNil(t, id) 780 781 s := Batch{ 782 Messages: []*Message{{Message: []byte(`{ 783 Protected: "eyJ0eXAiOiJwcnMuaHlwZXJsZWRnZXIuYXJpZXMtYXV0aC1t" + 784 "ZXNzYWdlIiwiYWxnIjoiRUNESC1TUytYQzIwUEtXIiwiZW5jIjoiWEMyMFAifQ", 785 IV: "JS2FxjEKdndnt-J7QX5pEnVwyBTu0_3d", 786 CipherText: "qQyzvajdvCDJbwxM", 787 Tag: "2FqZMMQuNPYfL0JsSkj8LQ", 788 }`)}}, 789 } 790 791 // outbound has been handled, simulate a callback to finish the trip 792 ch := svc.getBatchCh(id) 793 ch <- s 794 }() 795 796 p, err := svc.BatchPickup("conn", 1) 797 require.NoError(t, err) 798 799 require.Equal(t, 1, p) 800 }) 801 802 t.Run("test MessagePickupService.BatchPickup() - connection error", func(t *testing.T) { 803 svc, err := getService() 804 require.NoError(t, err) 805 806 expected := errors.New("get error") 807 svc.connectionLookup = &connectionsStub{ 808 getConnRecord: func(string) (*connection.Record, error) { 809 return nil, expected 810 }, 811 } 812 813 p, err := svc.BatchPickup("conn", 4) 814 require.Error(t, err) 815 require.True(t, errors.Is(err, expected)) 816 require.Equal(t, -1, p) 817 }) 818 819 t.Run("test MessagePickupService.BatchPickup() - send to DID error", func(t *testing.T) { 820 s := make(map[string][]byte) 821 822 provider := &mockprovider.Provider{ 823 StorageProviderValue: mockstore.NewMockStoreProvider(), 824 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 825 OutboundDispatcherValue: &mockdispatcher.MockOutbound{ 826 ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error { 827 return errors.New("send error") 828 }, 829 }, 830 PackagerValue: &mockPackager{}, 831 } 832 833 connRec := &connection.Record{ 834 ConnectionID: "conn", MyDID: MYDID, TheirDID: THEIRDID, State: "completed", 835 } 836 connBytes, err := json.Marshal(connRec) 837 require.NoError(t, err) 838 839 s["conn_conn1"] = connBytes 840 841 r, err := connection.NewRecorder(provider) 842 require.NoError(t, err) 843 err = r.SaveConnectionRecord(connRec) 844 require.NoError(t, err) 845 846 svc, err := New(provider) 847 require.NoError(t, err) 848 849 _, err = svc.BatchPickup("conn", 4) 850 require.Error(t, err) 851 require.Contains(t, err.Error(), "send batch pickup request") 852 }) 853 } 854 855 func TestDecodeMessages(t *testing.T) { 856 t.Run("test inbox.DecodeMessages() - success", func(t *testing.T) { 857 ibx := &inbox{} 858 859 msgs, err := ibx.DecodeMessages() 860 require.NoError(t, err) 861 require.Empty(t, msgs) 862 }) 863 864 t.Run("test inbox.DecodeMessages() - error", func(t *testing.T) { 865 b, err := json.Marshal([]*Message{}) 866 require.NoError(t, err) 867 868 ibx := &inbox{ 869 Messages: b, 870 } 871 872 _, err = ibx.DecodeMessages() 873 require.NoError(t, err) 874 }) 875 } 876 877 func TestHandleOutbound(t *testing.T) { 878 t.Run("test MessagePickupService.HandleOutbound() - not implemented", func(t *testing.T) { 879 svc, err := getService() 880 require.NoError(t, err) 881 882 svc.connectionLookup = &connectionsStub{ 883 getConnRecord: func(string) (*connection.Record, error) { 884 return nil, storage.ErrDataNotFound 885 }, 886 } 887 888 _, err = svc.HandleOutbound(nil, "not", "implemented") 889 require.Error(t, err) 890 require.Contains(t, err.Error(), "not implemented") 891 }) 892 } 893 894 func TestNoop(t *testing.T) { 895 t.Run("test MessagePickupService.Noop() - success", func(t *testing.T) { 896 s := make(map[string][]byte) 897 898 provider := &mockprovider.Provider{ 899 StorageProviderValue: mockstore.NewMockStoreProvider(), 900 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 901 OutboundDispatcherValue: &mockdispatcher.MockOutbound{ 902 ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error { 903 require.Equal(t, myDID, MYDID) 904 require.Equal(t, theirDID, THEIRDID) 905 906 reqMsgMap, ok := msg.(service.DIDCommMsgMap) 907 require.True(t, ok) 908 909 request := &Noop{} 910 911 err := reqMsgMap.Decode(request) 912 require.NoError(t, err) 913 914 return nil 915 }, 916 }, 917 PackagerValue: &mockPackager{}, 918 } 919 920 connRec := &connection.Record{ 921 ConnectionID: "conn", MyDID: MYDID, TheirDID: THEIRDID, State: "completed", 922 } 923 connBytes, err := json.Marshal(connRec) 924 require.NoError(t, err) 925 926 s["conn_conn1"] = connBytes 927 928 r, err := connection.NewRecorder(provider) 929 require.NoError(t, err) 930 err = r.SaveConnectionRecord(connRec) 931 require.NoError(t, err) 932 933 svc, err := New(provider) 934 require.NoError(t, err) 935 936 err = svc.Noop("conn") 937 require.NoError(t, err) 938 }) 939 940 t.Run("test MessagePickupService.Noop() - send to DID error", func(t *testing.T) { 941 s := make(map[string][]byte) 942 943 provider := &mockprovider.Provider{ 944 StorageProviderValue: mockstore.NewMockStoreProvider(), 945 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 946 OutboundDispatcherValue: &mockdispatcher.MockOutbound{ 947 ValidateSendToDID: func(msg interface{}, myDID, theirDID string) error { 948 return errors.New("send error") 949 }, 950 }, 951 PackagerValue: &mockPackager{}, 952 } 953 954 connRec := &connection.Record{ 955 ConnectionID: "conn", MyDID: MYDID, TheirDID: THEIRDID, State: "completed", 956 } 957 connBytes, err := json.Marshal(connRec) 958 require.NoError(t, err) 959 960 s["conn_conn1"] = connBytes 961 962 r, err := connection.NewRecorder(provider) 963 require.NoError(t, err) 964 err = r.SaveConnectionRecord(connRec) 965 require.NoError(t, err) 966 967 svc, err := New(provider) 968 require.NoError(t, err) 969 970 err = svc.Noop("conn") 971 require.Error(t, err) 972 require.Contains(t, err.Error(), "send noop request") 973 }) 974 975 t.Run("test MessagePickupService.Noop() - connection error", func(t *testing.T) { 976 svc, err := getService() 977 require.NoError(t, err) 978 979 expected := errors.New("get error") 980 svc.connectionLookup = &connectionsStub{ 981 getConnRecord: func(string) (*connection.Record, error) { 982 return nil, expected 983 }, 984 } 985 986 err = svc.Noop("conn") 987 require.Error(t, err) 988 require.True(t, errors.Is(err, expected)) 989 }) 990 } 991 992 func TestGetConnection(t *testing.T) { 993 t.Run("test MessagePickupService.getConnection() - error", func(t *testing.T) { 994 svc, err := getService() 995 require.NoError(t, err) 996 997 svc.connectionLookup = &connectionsStub{ 998 getConnRecord: func(string) (*connection.Record, error) { 999 return nil, storage.ErrDataNotFound 1000 }, 1001 } 1002 1003 _, err = svc.getConnection("test") 1004 require.Error(t, err) 1005 require.True(t, errors.Is(err, ErrConnectionNotFound)) 1006 }) 1007 } 1008 1009 func getService() (*Service, error) { 1010 svc, err := New(&mockprovider.Provider{ 1011 StorageProviderValue: mockstore.NewMockStoreProvider(), 1012 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 1013 OutboundDispatcherValue: nil, 1014 PackagerValue: &mockPackager{}, 1015 }) 1016 1017 return svc, err 1018 } 1019 1020 // mockProvider mock provider. 1021 type mockTransportProvider struct { 1022 packagerValue transport.Packager 1023 } 1024 1025 func (p *mockTransportProvider) Packager() transport.Packager { 1026 return p.packagerValue 1027 } 1028 1029 func (p *mockTransportProvider) InboundMessageHandler() transport.InboundMessageHandler { 1030 return func(envelope *transport.Envelope) error { 1031 logger.Debugf("message received is %s", envelope.Message) 1032 return nil 1033 } 1034 } 1035 1036 func (p *mockTransportProvider) AriesFrameworkID() string { 1037 return "aries-framework-instance-1" 1038 } 1039 1040 // mockPackager mock packager. 1041 type mockPackager struct{} 1042 1043 func (m *mockPackager) PackMessage(e *transport.Envelope) ([]byte, error) { 1044 return e.Message, nil 1045 } 1046 1047 func (m *mockPackager) UnpackMessage(encMessage []byte) (*transport.Envelope, error) { 1048 return &transport.Envelope{ 1049 Message: []byte(`{ 1050 "id": "8910", 1051 "~transport": { 1052 "return_route": "all" 1053 } 1054 }`), 1055 }, nil 1056 } 1057 1058 type connectionsStub struct { 1059 getConnIDByDIDs func(string, string) (string, error) 1060 getConnRecord func(string) (*connection.Record, error) 1061 } 1062 1063 func (c *connectionsStub) GetConnectionIDByDIDs(myDID, theirDID string) (string, error) { 1064 if c.getConnIDByDIDs != nil { 1065 return c.getConnIDByDIDs(myDID, theirDID) 1066 } 1067 1068 return "", nil 1069 } 1070 1071 func (c *connectionsStub) GetConnectionRecord(id string) (*connection.Record, error) { 1072 if c.getConnRecord != nil { 1073 return c.getConnRecord(id) 1074 } 1075 1076 return nil, nil 1077 }