github.com/hyperledger/aries-framework-go@v0.3.2/pkg/client/messaging/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 messaging 8 9 import ( 10 "bytes" 11 "context" 12 "encoding/json" 13 "fmt" 14 "strings" 15 "testing" 16 "time" 17 18 "github.com/stretchr/testify/require" 19 20 "github.com/hyperledger/aries-framework-go/component/storageutil/mem" 21 "github.com/hyperledger/aries-framework-go/pkg/common/model" 22 "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service" 23 "github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher" 24 "github.com/hyperledger/aries-framework-go/pkg/doc/did" 25 vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr" 26 "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/msghandler" 27 "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol" 28 "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/generic" 29 mocksvc "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/service" 30 mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/mock/diddoc" 31 mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms" 32 "github.com/hyperledger/aries-framework-go/pkg/mock/storage" 33 mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr" 34 "github.com/hyperledger/aries-framework-go/pkg/store/connection" 35 spi "github.com/hyperledger/aries-framework-go/spi/storage" 36 ) 37 38 func TestNew(t *testing.T) { 39 t.Run("Test create new command success", func(t *testing.T) { 40 client, err := New(&protocol.MockProvider{}, msghandler.NewMockMsgServiceProvider(), &mockNotifier{}) 41 require.NoError(t, err) 42 require.NotNil(t, client) 43 }) 44 45 t.Run("Test create new command success failure", func(t *testing.T) { 46 const errMsg = "sample-error" 47 client, err := New(&protocol.MockProvider{ 48 StoreProvider: &storage.MockStoreProvider{ 49 ErrOpenStoreHandle: fmt.Errorf(errMsg), 50 }, 51 }, msghandler.NewMockMsgServiceProvider(), &mockNotifier{}) 52 require.Error(t, err) 53 require.Nil(t, client) 54 require.Contains(t, err.Error(), errMsg) 55 }) 56 } 57 58 func TestCommand_RegisterService(t *testing.T) { 59 t.Run("Successful Register Message Service", func(t *testing.T) { 60 msgRegistrar := msghandler.NewMockMsgServiceProvider() 61 cmd, err := New(&protocol.MockProvider{}, msgRegistrar, &mockNotifier{}) 62 require.NoError(t, err) 63 require.NotNil(t, cmd) 64 65 err = cmd.RegisterService("json-msg-01", "https://didcomm.org/json/1.0/msg", "prp-01", "prp-02") 66 require.NoError(t, err) 67 68 // verify if new service is registered 69 require.NotEmpty(t, msgRegistrar.Services()) 70 require.Equal(t, "json-msg-01", msgRegistrar.Services()[0].Name()) 71 require.True(t, msgRegistrar.Services()[0].Accept( 72 "https://didcomm.org/json/1.0/msg", 73 []string{"prp-01", "prp-02"}, 74 )) 75 }) 76 77 t.Run("Register Message Service failure", func(t *testing.T) { 78 const errMsg = "sample-error" 79 mhandler := msghandler.NewMockMsgServiceProvider() 80 mhandler.RegisterErr = fmt.Errorf(errMsg) 81 82 cmd, err := New(&protocol.MockProvider{}, mhandler, &mockNotifier{}) 83 require.NoError(t, err) 84 require.NotNil(t, cmd) 85 86 err = cmd.RegisterService("json-msg-01", "https://didcomm.org/json/1.0/msg", "prp-01", "prp-02") 87 require.Error(t, err) 88 require.Contains(t, err.Error(), errMsg) 89 }) 90 } 91 92 func TestCommand_UnregisterService(t *testing.T) { 93 t.Run("Unregistering non existing message service", func(t *testing.T) { 94 cmd, err := New(&protocol.MockProvider{}, msghandler.NewMockMsgServiceProvider(), &mockNotifier{}) 95 require.NoError(t, err) 96 require.NotNil(t, cmd) 97 98 err = cmd.UnregisterService("json-msg-01") 99 require.Error(t, err) 100 }) 101 102 t.Run("Unregistering message service successfully", func(t *testing.T) { 103 msgRegistrar := msghandler.NewMockMsgServiceProvider() 104 cmd, err := New(&protocol.MockProvider{}, msgRegistrar, &mockNotifier{}) 105 require.NoError(t, err) 106 require.NotNil(t, cmd) 107 108 svcNames := []string{"svc-01", "svc-02", "svc-03", "svc-04"} 109 for _, svcName := range svcNames { 110 err := msgRegistrar.Register(generic.NewCustomMockMessageSvc("test", svcName)) 111 require.NoError(t, err) 112 } 113 114 require.Len(t, msgRegistrar.Services(), 4) 115 116 for _, svcName := range svcNames { 117 err := cmd.UnregisterService(svcName) 118 require.NoError(t, err) 119 } 120 121 require.Len(t, msgRegistrar.Services(), 0) 122 }) 123 } 124 125 func TestCommand_Services(t *testing.T) { 126 msgRegistrar := msghandler.NewMockMsgServiceProvider() 127 cmd, err := New(&protocol.MockProvider{}, msgRegistrar, &mockNotifier{}) 128 require.NoError(t, err) 129 require.NotNil(t, cmd) 130 131 svcs := cmd.Services() 132 require.Empty(t, svcs) 133 134 testMsgSvcs := []dispatcher.MessageService{ 135 generic.NewCustomMockMessageSvc("type-01", "svc-name-01"), 136 generic.NewCustomMockMessageSvc("type-02", "svc-name-02"), 137 generic.NewCustomMockMessageSvc("type-03", "svc-name-03"), 138 generic.NewCustomMockMessageSvc("type-04", "svc-name-04"), 139 generic.NewCustomMockMessageSvc("type-05", "svc-name-05"), 140 } 141 err = msgRegistrar.Register(testMsgSvcs...) 142 require.NoError(t, err) 143 144 svcs = cmd.Services() 145 require.Len(t, svcs, len(testMsgSvcs)) 146 } 147 148 func TestCommand_Send(t *testing.T) { // nolint: gocognit, gocyclo 149 t.Run("Test send new message success", func(t *testing.T) { 150 tests := []struct { 151 name string 152 testConnection *connection.Record 153 msgBody string 154 option SendMessageOpions 155 }{ 156 { 157 name: "send message to connection ID", 158 testConnection: &connection.Record{ 159 ConnectionID: "sample-conn-ID-001", 160 State: "completed", MyDID: "mydid", TheirDID: "theirDID-001", 161 }, 162 option: SendByConnectionID("sample-conn-ID-001"), 163 }, 164 { 165 name: "send message to their DID", 166 testConnection: &connection.Record{ 167 ConnectionID: "sample-conn-ID-001", 168 State: "completed", MyDID: "mydid", TheirDID: "theirDID-001", 169 }, 170 option: SendByTheirDID("theirDID-001"), 171 }, 172 { 173 name: "send message to destination", 174 option: SendByDestination(&service.Destination{ 175 RecipientKeys: []string{"test"}, 176 ServiceEndpoint: model.NewDIDCommV1Endpoint("dfsdf"), 177 RoutingKeys: []string{"test"}, 178 }), 179 }, 180 } 181 182 // Note: copied from store/connection/connection_lookup.go 183 mockDIDTagFunc := func(dids ...string) string { 184 for i, v := range dids { 185 dids[i] = strings.ReplaceAll(v, ":", "$") 186 } 187 188 return strings.Join(dids, "|") 189 } 190 191 t.Parallel() 192 193 for _, test := range tests { 194 tc := test 195 t.Run(tc.name, func(t *testing.T) { 196 memProvider := mem.NewProvider() 197 198 memStore, err := memProvider.OpenStore("didexchange") 199 require.NoError(t, err) 200 201 if tc.testConnection != nil { 202 connBytes, errMarshal := json.Marshal(tc.testConnection) 203 require.NoError(t, errMarshal) 204 require.NoError(t, 205 memStore.Put(fmt.Sprintf("conn_%s", tc.testConnection.ConnectionID), connBytes, 206 spi.Tag{Name: "conn_"}, 207 spi.Tag{Name: "bothDIDs", Value: mockDIDTagFunc(tc.testConnection.MyDID, tc.testConnection.TheirDID)}, 208 spi.Tag{Name: "theirDID", Value: mockDIDTagFunc(tc.testConnection.TheirDID)}, 209 )) 210 } 211 212 cmd, err := New(&protocol.MockProvider{ 213 StoreProvider: memProvider, 214 ProtocolStateStoreProvider: mem.NewProvider(), 215 }, 216 msghandler.NewMockMsgServiceProvider(), &mockNotifier{}) 217 require.NoError(t, err) 218 require.NotNil(t, cmd) 219 220 var b bytes.Buffer 221 res, err := cmd.Send(json.RawMessage([]byte(`{"text":"sample"}`)), tc.option) 222 require.NoError(t, err) 223 require.Empty(t, b.String()) 224 require.Empty(t, res) 225 }) 226 } 227 }) 228 229 const msgStr = `{"@id": "2d798168-8abf-4410-8535-bc1e8406a5ff","text":"sample"}` 230 231 const replyMsgStr = `{ 232 "@id": "123456781", 233 "@type": "sample-response-type", 234 "~thread" : {"thid": "2d798168-8abf-4410-8535-bc1e8406a5ff"} 235 }` 236 237 t.Run("Test send new message and await response success", func(t *testing.T) { 238 tests := []struct { 239 name string 240 testConnection *connection.Record 241 msgBody string 242 option []SendMessageOpions 243 }{ 244 { 245 name: "send message to connection ID", 246 testConnection: &connection.Record{ 247 ConnectionID: "sample-conn-ID-001", 248 State: "completed", MyDID: "mydid", TheirDID: "theirDID-001", 249 }, 250 option: []SendMessageOpions{ 251 SendByConnectionID("sample-conn-ID-001"), 252 WaitForResponse(context.Background(), "sample-response-type"), 253 }, 254 }, 255 { 256 name: "send message to their DID", 257 testConnection: &connection.Record{ 258 ConnectionID: "sample-conn-ID-001", 259 State: "completed", MyDID: "mydid", TheirDID: "theirDID-001", 260 }, 261 option: []SendMessageOpions{ 262 SendByTheirDID("theirDID-001"), 263 WaitForResponse(context.Background(), "sample-response-type"), 264 }, 265 }, 266 { 267 name: "send message to destination", 268 option: []SendMessageOpions{ 269 SendByDestination(&service.Destination{ 270 RecipientKeys: []string{"test"}, 271 ServiceEndpoint: model.NewDIDCommV1Endpoint("sdfsdf"), 272 RoutingKeys: []string{"test"}, 273 }), 274 WaitForResponse(context.Background(), "sample-response-type"), 275 }, 276 }, 277 } 278 279 // Note: copied from store/connection/connection_lookup.go 280 mockDIDTagFunc := func(dids ...string) string { 281 for i, v := range dids { 282 dids[i] = strings.ReplaceAll(v, ":", "$") 283 } 284 285 return strings.Join(dids, "|") 286 } 287 288 t.Parallel() 289 290 for _, test := range tests { 291 tc := test 292 t.Run(tc.name, func(t *testing.T) { 293 memProvider := mem.NewProvider() 294 295 memStore, err := memProvider.OpenStore("didexchange") 296 require.NoError(t, err) 297 298 if tc.testConnection != nil { 299 connBytes, errMarshal := json.Marshal(tc.testConnection) 300 require.NoError(t, errMarshal) 301 require.NoError(t, 302 memStore.Put(fmt.Sprintf("conn_%s", tc.testConnection.ConnectionID), connBytes, 303 spi.Tag{Name: "conn_"}, 304 spi.Tag{Name: "bothDIDs", Value: mockDIDTagFunc(tc.testConnection.MyDID, tc.testConnection.TheirDID)}, 305 spi.Tag{Name: "theirDID", Value: mockDIDTagFunc(tc.testConnection.TheirDID)}, 306 )) 307 } 308 309 registrar := msghandler.NewMockMsgServiceProvider() 310 311 cmd, err := New(&protocol.MockProvider{ 312 StoreProvider: memProvider, 313 ProtocolStateStoreProvider: mem.NewProvider(), 314 }, 315 registrar, &mockNotifier{}) 316 require.NoError(t, err) 317 require.NotNil(t, cmd) 318 319 replyMsg, err := service.ParseDIDCommMsgMap([]byte(replyMsgStr)) 320 require.NoError(t, err) 321 322 go func() { 323 for { 324 services := registrar.Services() 325 if len(services) > 0 { 326 _, e := services[0].HandleInbound(replyMsg, service.NewDIDCommContext("sampleDID", "sampleTheirDID", nil)) 327 require.NoError(t, e) 328 329 break 330 } 331 } 332 }() 333 334 res, err := cmd.Send( 335 json.RawMessage(msgStr), 336 tc.option...) 337 require.NoError(t, err) 338 339 var response map[string]interface{} 340 err = json.Unmarshal(res, &response) 341 require.NoError(t, err) 342 require.NotEmpty(t, response) 343 require.NotEmpty(t, response["message"]) 344 }) 345 } 346 }) 347 348 t.Run("Test send new message failures with bad context", func(t *testing.T) { 349 badContext, cancel := context.WithTimeout(context.Background(), 0*time.Second) 350 defer cancel() 351 352 connBytes, err := json.Marshal(&connection.Record{ 353 ConnectionID: "sample-conn-ID-001", 354 State: "completed", MyDID: "mydid", TheirDID: "theirDID-001", 355 }) 356 require.NoError(t, err) 357 358 mockStore := &storage.MockStore{Store: make(map[string]storage.DBEntry)} 359 require.NoError(t, mockStore.Put("conn_sample-conn-ID-001", connBytes)) 360 361 cmd, err := New(&protocol.MockProvider{StoreProvider: storage.NewCustomMockStoreProvider(mockStore)}, 362 msghandler.NewMockMsgServiceProvider(), &mockNotifier{}) 363 require.NoError(t, err) 364 require.NotNil(t, cmd) 365 366 res, err := cmd.Send( 367 json.RawMessage([]byte(msgStr)), 368 SendByConnectionID("sample-conn-ID-001"), 369 WaitForResponse(badContext, "sample-rep-type"), 370 ) 371 require.Error(t, err) 372 require.Contains(t, err.Error(), "failed to get reply, context deadline exceeded") 373 require.Empty(t, res) 374 }) 375 376 t.Run("Test send new message failures", func(t *testing.T) { 377 tests := []struct { 378 name string 379 testConnection *connection.Record 380 messenger *mocksvc.MockMessenger 381 kms *mockkms.KeyManager 382 vdr *mockvdr.MockVDRegistry 383 option SendMessageOpions 384 errorMsg string 385 msgBody json.RawMessage 386 }{ 387 { 388 name: "send message to connection ID data not found error", 389 testConnection: nil, 390 errorMsg: "data not found", 391 option: SendByConnectionID("sample-conn-ID-001"), 392 }, 393 { 394 name: "send message without any options", 395 testConnection: nil, 396 errorMsg: "missing message destination", 397 option: SendByConnectionID(""), 398 }, 399 { 400 name: "send message to connection ID send error", 401 testConnection: &connection.Record{ 402 ConnectionID: "sample-conn-ID-001", 403 State: "completed", MyDID: "mydid", TheirDID: "theirDID-001", 404 }, 405 option: SendByConnectionID("sample-conn-ID-001"), 406 messenger: &mocksvc.MockMessenger{ErrSend: fmt.Errorf("sample-err-01")}, 407 errorMsg: "sample-err-01", 408 }, 409 { 410 name: "send message to their DID data not found error", 411 testConnection: &connection.Record{ 412 ConnectionID: "sample-conn-ID-001", 413 State: "completed", MyDID: "mydid", TheirDID: "theirDID-z", 414 }, 415 option: SendByTheirDID("theirDID-001"), 416 errorMsg: vdrapi.ErrNotFound.Error(), 417 }, 418 { 419 name: "send message to destination - failure 1", 420 option: SendByDestination(&service.Destination{ 421 RecipientKeys: []string{"test"}, 422 ServiceEndpoint: model.NewDIDCommV1Endpoint("sdfsdf"), 423 RoutingKeys: []string{"test"}, 424 }), 425 messenger: &mocksvc.MockMessenger{ErrSendToDestination: fmt.Errorf("sample-err-01")}, 426 errorMsg: "sample-err-01", 427 }, 428 { 429 name: "send message to destination - failure 2", 430 kms: &mockkms.KeyManager{CrAndExportPubKeyErr: fmt.Errorf("sample-kmserr-01")}, 431 option: SendByDestination(&service.Destination{ 432 RecipientKeys: []string{"test"}, 433 ServiceEndpoint: model.NewDIDCommV1Endpoint("sdfsdf"), 434 RoutingKeys: []string{"test"}, 435 }), 436 errorMsg: "sample-kmserr-01", 437 }, 438 { 439 name: "failed to resolve destination from DID", 440 option: SendByTheirDID("theirDID-001"), 441 vdr: &mockvdr.MockVDRegistry{ResolveErr: fmt.Errorf("sample-err-01")}, 442 errorMsg: "sample-err-01", 443 }, 444 { 445 name: "invalid message body - scenario 1", 446 option: SendByTheirDID("theirDID-001"), 447 vdr: &mockvdr.MockVDRegistry{ 448 ResolveFunc: func(didID string, opts ...vdrapi.DIDMethodOption) (doc *did.DocResolution, e error) { 449 return &did.DocResolution{DIDDocument: mockdiddoc.GetMockDIDDoc(t, false)}, nil 450 }, 451 }, 452 errorMsg: "invalid payload data format", 453 msgBody: json.RawMessage([]byte("--")), 454 }, 455 { 456 name: "invalid message body - scenario 2", 457 testConnection: &connection.Record{ 458 ConnectionID: "sample-conn-ID-001", 459 State: "completed", MyDID: "mydid", TheirDID: "theirDID-001", 460 }, 461 option: SendByConnectionID("sample-conn-ID-001"), 462 errorMsg: "invalid payload data format", 463 msgBody: json.RawMessage([]byte("--")), 464 }, 465 } 466 467 t.Parallel() 468 469 for _, test := range tests { 470 tc := test 471 t.Run(tc.name, func(t *testing.T) { 472 provider := &protocol.MockProvider{ProtocolStateStoreProvider: mem.NewProvider()} 473 474 memProvider := mem.NewProvider() 475 476 memStore, err := memProvider.OpenStore("didexchange") 477 require.NoError(t, err) 478 479 if tc.testConnection != nil { 480 connBytes, errMarshal := json.Marshal(tc.testConnection) 481 require.NoError(t, errMarshal) 482 483 require.NoError(t, memStore.Put(fmt.Sprintf("conn_%s", tc.testConnection.ConnectionID), connBytes)) 484 } 485 486 provider.StoreProvider = memProvider 487 488 if tc.messenger != nil { 489 provider.CustomMessenger = tc.messenger 490 } 491 492 if tc.kms != nil { 493 provider.CustomKMS = tc.kms 494 } 495 496 if tc.vdr != nil { 497 provider.CustomVDR = tc.vdr 498 } 499 500 cmd, err := New(provider, msghandler.NewMockMsgServiceProvider(), &mockNotifier{}) 501 require.NoError(t, err) 502 require.NotNil(t, cmd) 503 504 msgBody := json.RawMessage([]byte(`{"text":"sample"}`)) 505 506 if tc.msgBody != nil { 507 msgBody = tc.msgBody 508 } 509 510 res, err := cmd.Send(msgBody, tc.option) 511 require.Error(t, err, "failed test : %s", tc.name) 512 require.Contains(t, err.Error(), tc.errorMsg) 513 require.Empty(t, res) 514 }) 515 } 516 }) 517 } 518 519 func TestCommand_Reply(t *testing.T) { 520 t.Run("Test reply validation and failures", func(t *testing.T) { 521 tests := []struct { 522 name string 523 msgBody string 524 msgID string 525 messenger *mocksvc.MockMessenger 526 errorMsg string 527 }{ 528 { 529 name: "invalid message format", 530 msgBody: `"sample-msg"`, 531 errorMsg: "invalid payload data format", 532 }, 533 { 534 name: "message reply error", 535 msgBody: `{"msg":"Hello !!"}`, 536 messenger: &mocksvc.MockMessenger{ErrReplyTo: fmt.Errorf("sample-err-01")}, 537 errorMsg: "sample-err-01", 538 }, 539 } 540 541 t.Parallel() 542 543 for _, test := range tests { 544 tc := test 545 t.Run(tc.name, func(t *testing.T) { 546 provider := &protocol.MockProvider{} 547 548 if tc.messenger != nil { 549 provider.CustomMessenger = tc.messenger 550 } 551 552 cmd, err := New(provider, msghandler.NewMockMsgServiceProvider(), &mockNotifier{}) 553 require.NoError(t, err) 554 require.NotNil(t, cmd) 555 556 res, err := cmd.Reply(context.Background(), json.RawMessage([]byte(tc.msgBody)), tc.msgID, false, "") 557 require.Error(t, err) 558 require.Contains(t, err.Error(), tc.errorMsg) 559 require.Empty(t, res) 560 }) 561 } 562 }) 563 564 t.Run("Test send message reply", func(t *testing.T) { 565 cmd, err := New(&protocol.MockProvider{}, msghandler.NewMockMsgServiceProvider(), &mockNotifier{}) 566 require.NoError(t, err) 567 require.NotNil(t, cmd) 568 569 res, err := cmd.Reply(context.Background(), json.RawMessage([]byte(`{"msg":"Hello !!"}`)), "msg-id", false, "") 570 require.NoError(t, err) 571 require.Empty(t, res) 572 }) 573 574 t.Run("Test send message reply by starting new thread", func(t *testing.T) { 575 cmd, err := New(&protocol.MockProvider{}, msghandler.NewMockMsgServiceProvider(), &mockNotifier{}) 576 require.NoError(t, err) 577 require.NotNil(t, cmd) 578 579 res, err := cmd.Reply(context.Background(), json.RawMessage([]byte(`{"msg":"Hello !!"}`)), "msg-id", true, "") 580 require.NoError(t, err) 581 require.Empty(t, res) 582 }) 583 584 const msgStr = `{"@id": "2d798168-8abf-4410-8535-bc1e8406a5ff","text":"sample"}` 585 586 const replyMsgStr = `{ 587 "@id": "123456781", 588 "@type": "sample-response-type", 589 "~thread" : {"thid": "2d798168-8abf-4410-8535-bc1e8406a5ff"} 590 }` 591 592 t.Run("Test send message reply and await response", func(t *testing.T) { 593 registrar := msghandler.NewMockMsgServiceProvider() 594 595 cmd, err := New(&protocol.MockProvider{}, registrar, &mockNotifier{}) 596 require.NoError(t, err) 597 require.NotNil(t, cmd) 598 599 replyMsg, err := service.ParseDIDCommMsgMap([]byte(replyMsgStr)) 600 require.NoError(t, err) 601 602 go func() { 603 for { 604 services := registrar.Services() 605 606 if len(services) > 0 { 607 _, e := services[0].HandleInbound(replyMsg, service.NewDIDCommContext("sampleDID", "sampleTheirDID", nil)) 608 require.NoError(t, e) 609 } 610 } 611 }() 612 613 res, err := cmd.Reply(context.Background(), json.RawMessage([]byte(msgStr)), "msg-id", false, "sample-response-type") 614 require.NoError(t, err) 615 616 var response map[string]interface{} 617 err = json.Unmarshal(res, &response) 618 require.NoError(t, err) 619 require.NotEmpty(t, response) 620 require.NotEmpty(t, response["message"]) 621 }) 622 623 t.Run("Test send message reply by starting new thread and await response", func(t *testing.T) { 624 registrar := msghandler.NewMockMsgServiceProvider() 625 626 cmd, err := New(&protocol.MockProvider{}, registrar, &mockNotifier{}) 627 require.NoError(t, err) 628 require.NotNil(t, cmd) 629 630 replyMsg, err := service.ParseDIDCommMsgMap([]byte(replyMsgStr)) 631 require.NoError(t, err) 632 633 go func() { 634 for { 635 svcs := registrar.Services() 636 if len(svcs) > 0 { 637 _, e := svcs[0].HandleInbound( 638 replyMsg, service.NewDIDCommContext("sampleDID", "sampleTheirDID", nil)) 639 require.NoError(t, e) 640 } 641 } 642 }() 643 644 res, err := cmd.Reply(context.Background(), json.RawMessage([]byte(msgStr)), "msg-id", true, "sample-response-type") 645 require.NoError(t, err) 646 647 var response map[string]interface{} 648 err = json.Unmarshal(res, &response) 649 require.NoError(t, err) 650 require.NotEmpty(t, response) 651 require.NotEmpty(t, response["message"]) 652 }) 653 } 654 655 // mockNotifier is mock implementation of Notifier. 656 type mockNotifier struct { 657 NotifyFunc func(topic string, message []byte) error 658 } 659 660 // Notify is mock implementation of Notifier Notify(). 661 func (n *mockNotifier) Notify(topic string, message []byte) error { 662 if n.NotifyFunc != nil { 663 return n.NotifyFunc(topic, message) 664 } 665 666 return nil 667 }