github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/protocol/issuecredential/service_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 "time" 14 15 "github.com/golang/mock/gomock" 16 "github.com/google/uuid" 17 "github.com/stretchr/testify/require" 18 19 "github.com/hyperledger/aries-framework-go/component/storageutil/mem" 20 "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model" 21 "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service" 22 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator" 23 "github.com/hyperledger/aries-framework-go/pkg/doc/util" 24 "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" 25 serviceMocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/didcomm/common/service" 26 issuecredentialMocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/didcomm/protocol/issuecredential" 27 storageMocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/spi/storage" 28 "github.com/hyperledger/aries-framework-go/spi/storage" 29 ) 30 31 const ( 32 Alice = "Alice" 33 Bob = "Bob" 34 ) 35 36 func TestService_UseV2(t *testing.T) { 37 ctrl := gomock.NewController(t) 38 defer ctrl.Finish() 39 40 t.Run("Success (one function)", func(t *testing.T) { 41 storeProvider := mem.NewProvider() 42 43 provider := issuecredentialMocks.NewMockProvider(ctrl) 44 provider.EXPECT().Messenger().Return(nil) 45 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 46 47 svc, err := New(provider) 48 require.NoError(t, err) 49 require.NotNil(t, svc) 50 51 meta := &MetaData{ 52 state: &done{}, 53 msgClone: service.NewDIDCommMsgMap(struct { 54 Type string `json:"@type"` 55 }{ 56 Type: IssueCredentialMsgTypeV2, 57 }), 58 offerCredentialV2: &OfferCredentialV2{Type: OfferCredentialMsgTypeV2}, 59 proposeCredentialV2: &ProposeCredentialV2{Type: ProposeCredentialMsgTypeV2}, 60 issueCredentialV2: &IssueCredentialV2{Type: IssueCredentialMsgTypeV2}, 61 requestCredentialV2: &RequestCredentialV2{Type: RequestCredentialMsgTypeV2}, 62 credentialNames: []string{"name"}, 63 } 64 var executed bool 65 svc.Use(func(next Handler) Handler { 66 return HandlerFunc(func(metadata Metadata) error { 67 require.Equal(t, meta.msgClone, metadata.Message()) 68 require.Equal(t, metadata.Message().Type(), IssueCredentialMsgTypeV2) 69 require.Equal(t, meta.offerCredentialV2, metadata.OfferCredentialV2()) 70 require.Equal(t, meta.proposeCredentialV2, metadata.ProposeCredentialV2()) 71 require.Equal(t, meta.issueCredentialV2, metadata.IssueCredentialV2()) 72 require.Equal(t, meta.requestCredentialV2, metadata.RequestCredentialV2()) 73 require.Equal(t, meta.credentialNames, metadata.CredentialNames()) 74 require.Equal(t, meta.state.Name(), metadata.StateName()) 75 76 executed = true 77 return next.Handle(metadata) 78 }) 79 }) 80 81 _, _, err = svc.execute(meta.state, meta) 82 require.EqualError(t, err, "done: ExecuteOutbound is not implemented yet") 83 84 require.True(t, executed) 85 }) 86 87 t.Run("Success (two function)", func(t *testing.T) { 88 storeProvider := mem.NewProvider() 89 90 provider := issuecredentialMocks.NewMockProvider(ctrl) 91 provider.EXPECT().Messenger().Return(nil) 92 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 93 94 svc, err := New(provider) 95 require.NoError(t, err) 96 require.NotNil(t, svc) 97 98 var executed bool 99 svc.Use(func(next Handler) Handler { 100 return HandlerFunc(func(metadata Metadata) error { 101 executed = true 102 return next.Handle(metadata) 103 }) 104 }, func(next Handler) Handler { 105 return HandlerFunc(func(metadata Metadata) error { 106 require.True(t, executed) 107 return next.Handle(metadata) 108 }) 109 }) 110 111 _, _, err = svc.execute(&done{}, &MetaData{}) 112 require.EqualError(t, err, "done: ExecuteOutbound is not implemented yet") 113 }) 114 115 t.Run("Failed", func(t *testing.T) { 116 storeProvider := mem.NewProvider() 117 118 provider := issuecredentialMocks.NewMockProvider(ctrl) 119 provider.EXPECT().Messenger().Return(nil) 120 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 121 122 svc, err := New(provider) 123 require.NoError(t, err) 124 require.NotNil(t, svc) 125 126 const msgErr = "error message" 127 svc.Use(func(next Handler) Handler { 128 return HandlerFunc(func(metadata Metadata) error { 129 return errors.New(msgErr) 130 }) 131 }) 132 133 _, _, err = svc.execute(&done{}, &MetaData{}) 134 require.EqualError(t, err, "middleware: "+msgErr) 135 }) 136 } 137 138 func TestService_UseV3(t *testing.T) { 139 ctrl := gomock.NewController(t) 140 defer ctrl.Finish() 141 142 t.Run("Success (one function)", func(t *testing.T) { 143 storeProvider := mem.NewProvider() 144 145 provider := issuecredentialMocks.NewMockProvider(ctrl) 146 provider.EXPECT().Messenger().Return(nil) 147 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 148 149 svc, err := New(provider) 150 require.NoError(t, err) 151 require.NotNil(t, svc) 152 153 meta := &MetaData{ 154 state: &done{}, 155 msgClone: service.NewDIDCommMsgMap(struct { 156 Type string `json:"@type"` 157 }{ 158 Type: IssueCredentialMsgTypeV3, 159 }), 160 offerCredentialV2: &OfferCredentialV2{Type: OfferCredentialMsgTypeV3}, 161 proposeCredentialV2: &ProposeCredentialV2{Type: ProposeCredentialMsgTypeV3}, 162 issueCredentialV2: &IssueCredentialV2{Type: IssueCredentialMsgTypeV3}, 163 requestCredentialV2: &RequestCredentialV2{Type: RequestCredentialMsgTypeV3}, 164 credentialNames: []string{"name"}, 165 } 166 var executed bool 167 svc.Use(func(next Handler) Handler { 168 return HandlerFunc(func(metadata Metadata) error { 169 require.Equal(t, meta.msgClone, metadata.Message()) 170 require.Equal(t, metadata.Message().Type(), IssueCredentialMsgTypeV3) 171 require.Equal(t, meta.offerCredentialV2, metadata.OfferCredentialV2()) 172 require.Equal(t, meta.proposeCredentialV2, metadata.ProposeCredentialV2()) 173 require.Equal(t, meta.issueCredentialV2, metadata.IssueCredentialV2()) 174 require.Equal(t, meta.requestCredentialV2, metadata.RequestCredentialV2()) 175 require.Equal(t, meta.credentialNames, metadata.CredentialNames()) 176 require.Equal(t, meta.state.Name(), metadata.StateName()) 177 178 executed = true 179 return next.Handle(metadata) 180 }) 181 }) 182 183 _, _, err = svc.execute(meta.state, meta) 184 require.EqualError(t, err, "done: ExecuteOutbound is not implemented yet") 185 186 require.True(t, executed) 187 }) 188 } 189 190 func TestNew(t *testing.T) { 191 ctrl := gomock.NewController(t) 192 defer ctrl.Finish() 193 194 t.Run("Success", func(t *testing.T) { 195 storeProvider := mem.NewProvider() 196 197 provider := issuecredentialMocks.NewMockProvider(ctrl) 198 provider.EXPECT().Messenger().Return(nil) 199 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 200 201 svc, err := New(provider) 202 require.NoError(t, err) 203 require.NotNil(t, svc) 204 }) 205 206 t.Run("Error open store", func(t *testing.T) { 207 const errMsg = "error" 208 209 storeProvider := storageMocks.NewMockProvider(ctrl) 210 storeProvider.EXPECT().OpenStore(Name).Return(nil, errors.New(errMsg)) 211 212 provider := issuecredentialMocks.NewMockProvider(ctrl) 213 provider.EXPECT().StorageProvider().Return(storeProvider) 214 215 svc, err := New(provider) 216 require.Contains(t, fmt.Sprintf("%v", err), errMsg) 217 require.Nil(t, svc) 218 }) 219 } 220 221 func TestService_Initialize(t *testing.T) { 222 ctrl := gomock.NewController(t) 223 defer ctrl.Finish() 224 225 t.Run("Success", func(t *testing.T) { 226 storeProvider := mem.NewProvider() 227 228 provider := issuecredentialMocks.NewMockProvider(ctrl) 229 provider.EXPECT().Messenger().Return(nil) 230 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 231 232 svc := Service{} 233 234 err := svc.Initialize(provider) 235 require.NoError(t, err) 236 237 // second init is no-op 238 err = svc.Initialize(provider) 239 require.NoError(t, err) 240 }) 241 242 t.Run("failure, not given a valid provider", func(t *testing.T) { 243 svc := Service{} 244 245 err := svc.Initialize("not a provider") 246 require.Error(t, err) 247 require.Contains(t, err.Error(), "expected provider of type") 248 }) 249 } 250 251 // nolint: gocyclo,gocognit 252 func TestService_HandleInboundV2(t *testing.T) { 253 ctrl := gomock.NewController(t) 254 defer ctrl.Finish() 255 256 const errMsg = "error" 257 258 store := storageMocks.NewMockStore(ctrl) 259 260 storeProvider := storageMocks.NewMockProvider(ctrl) 261 storeProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil).AnyTimes() 262 storeProvider.EXPECT().SetStoreConfig(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 263 264 messenger := serviceMocks.NewMockMessenger(ctrl) 265 266 provider := issuecredentialMocks.NewMockProvider(ctrl) 267 provider.EXPECT().Messenger().Return(messenger).AnyTimes() 268 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 269 270 t.Run("No clients", func(t *testing.T) { 271 svc, err := New(provider) 272 require.NoError(t, err) 273 274 _, err = svc.HandleInbound(nil, service.EmptyDIDCommContext()) 275 require.Contains(t, fmt.Sprintf("%v", err), "no clients") 276 }) 277 278 t.Run("DB error", func(t *testing.T) { 279 store.EXPECT().Get(gomock.Any()).Return(nil, errors.New(errMsg)) 280 281 svc, err := New(provider) 282 require.NoError(t, err) 283 284 require.NoError(t, svc.RegisterActionEvent(make(chan<- service.DIDCommAction))) 285 286 msg := service.NewDIDCommMsgMap(struct{}{}) 287 msg.SetID(uuid.New().String()) 288 _, err = svc.HandleInbound(msg, service.EmptyDIDCommContext()) 289 require.Contains(t, fmt.Sprintf("%v", err), "doHandle: getCurrentStateNameAndPIID: currentStateName: "+errMsg) 290 }) 291 292 t.Run("DB error (saveTransitionalPayload)", func(t *testing.T) { 293 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 294 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New(errMsg)) 295 296 svc, err := New(provider) 297 require.NoError(t, err) 298 299 require.NoError(t, svc.RegisterActionEvent(make(chan<- service.DIDCommAction))) 300 301 msg := service.NewDIDCommMsgMap(ProposeCredentialV2{ 302 Type: ProposeCredentialMsgTypeV2, 303 }) 304 msg.SetID(uuid.New().String()) 305 _, err = svc.HandleInbound(msg, service.EmptyDIDCommContext()) 306 require.Contains(t, fmt.Sprintf("%v", err), "save transitional payload: "+errMsg) 307 }) 308 309 t.Run("Unrecognized msgType", func(t *testing.T) { 310 svc, err := New(provider) 311 require.NoError(t, err) 312 313 require.NoError(t, svc.RegisterActionEvent(make(chan<- service.DIDCommAction))) 314 315 _, err = svc.HandleInbound(service.NewDIDCommMsgMap(struct{}{}), service.EmptyDIDCommContext()) 316 require.Contains(t, fmt.Sprintf("%v", err), "doHandle: nextState: unrecognized msgType: ") 317 }) 318 319 t.Run("Receive Propose Credential Stop", func(t *testing.T) { 320 done := make(chan struct{}) 321 322 messenger.EXPECT(). 323 ReplyToNested(gomock.Any(), gomock.Any()). 324 Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error { 325 defer close(done) 326 327 r := &model.ProblemReport{} 328 require.NoError(t, msg.Decode(r)) 329 require.Equal(t, codeRejectedError, r.Description.Code) 330 require.Equal(t, ProblemReportMsgTypeV2, r.Type) 331 332 return nil 333 }) 334 335 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 336 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 337 store.EXPECT().Delete(gomock.Any()).Return(nil) 338 store.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 339 require.Equal(t, "done", string(name)) 340 341 return nil 342 }) 343 344 svc, err := New(provider) 345 require.NoError(t, err) 346 347 ch := make(chan service.DIDCommAction, 1) 348 require.NoError(t, svc.RegisterActionEvent(ch)) 349 350 msg := service.NewDIDCommMsgMap(ProposeCredentialV2{ 351 Type: ProposeCredentialMsgTypeV2, 352 }) 353 354 msg.SetID(uuid.New().String()) 355 356 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 357 require.NoError(t, err) 358 359 action := <-ch 360 361 properties, ok := action.Properties.(*eventProps) 362 require.True(t, ok) 363 require.NotEmpty(t, properties.PIID()) 364 require.Equal(t, properties.MyDID(), Alice) 365 require.Equal(t, properties.TheirDID(), Bob) 366 require.Equal(t, properties.All()["myDID"], Alice) 367 require.Equal(t, properties.All()["theirDID"], Bob) 368 369 action.Stop(nil) 370 371 select { 372 case <-done: 373 return 374 case <-time.After(time.Second): 375 t.Error("timeout") 376 } 377 }) 378 379 t.Run("Receive Propose Credential Continue", func(t *testing.T) { 380 done := make(chan struct{}) 381 382 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 383 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 384 defer close(done) 385 386 r := &OfferCredentialV2{} 387 require.NoError(t, msg.Decode(r)) 388 require.Equal(t, OfferCredentialMsgTypeV2, r.Type) 389 390 return nil 391 }) 392 393 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 394 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 395 store.EXPECT().Delete(gomock.Any()).Return(nil) 396 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 397 require.Equal(t, "offer-sent", string(name)) 398 399 return nil 400 }) 401 402 svc, err := New(provider) 403 require.NoError(t, err) 404 405 ch := make(chan service.DIDCommAction, 1) 406 require.NoError(t, svc.RegisterActionEvent(ch)) 407 408 msg := service.NewDIDCommMsgMap(ProposeCredentialV2{ 409 Type: ProposeCredentialMsgTypeV2, 410 }) 411 412 msg.SetID(uuid.New().String()) 413 414 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 415 require.NoError(t, err) 416 417 action := <-ch 418 419 properties, ok := action.Properties.(*eventProps) 420 require.True(t, ok) 421 require.NotEmpty(t, properties.PIID()) 422 require.Equal(t, properties.MyDID(), Alice) 423 require.Equal(t, properties.TheirDID(), Bob) 424 425 action.Continue(WithOfferCredential(&OfferCredentialParams{})) 426 427 select { 428 case <-done: 429 return 430 case <-time.After(time.Second): 431 t.Error("timeout") 432 } 433 }) 434 435 t.Run("Receive Propose Credential Continue (async)", func(t *testing.T) { 436 done := make(chan struct{}) 437 438 newProvider := issuecredentialMocks.NewMockProvider(ctrl) 439 newProvider.EXPECT().Messenger().Return(messenger).AnyTimes() 440 newProvider.EXPECT().StorageProvider().Return(mem.NewProvider()).AnyTimes() 441 442 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 443 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 444 defer close(done) 445 446 r := &OfferCredentialV2{} 447 require.NoError(t, msg.Decode(r)) 448 require.Equal(t, OfferCredentialMsgTypeV2, r.Type) 449 450 return nil 451 }) 452 453 svc, err := New(newProvider) 454 require.NoError(t, err) 455 456 ch := make(chan service.DIDCommAction, 1) 457 require.NoError(t, svc.RegisterActionEvent(ch)) 458 459 msg := service.NewDIDCommMsgMap(ProposeCredentialV2{ 460 Type: ProposeCredentialMsgTypeV2, 461 }) 462 463 msg.SetID(uuid.New().String()) 464 465 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 466 require.NoError(t, err) 467 468 actions, err := svc.Actions() 469 require.NoError(t, err) 470 for _, action := range actions { 471 require.Equal(t, action.MyDID, Alice) 472 require.Equal(t, action.TheirDID, Bob) 473 require.NoError(t, svc.ActionContinue(action.PIID, WithOfferCredential(&OfferCredentialParams{}))) 474 } 475 476 select { 477 case <-done: 478 return 479 case <-time.After(time.Second): 480 t.Error("timeout") 481 } 482 }) 483 484 t.Run("Receive Propose Credential Stop (async)", func(t *testing.T) { 485 done := make(chan struct{}) 486 487 newProvider := issuecredentialMocks.NewMockProvider(ctrl) 488 newProvider.EXPECT().Messenger().Return(messenger).AnyTimes() 489 newProvider.EXPECT().StorageProvider().Return(mem.NewProvider()).AnyTimes() 490 491 messenger.EXPECT(). 492 ReplyToNested(gomock.Any(), gomock.Any()). 493 Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error { 494 defer close(done) 495 496 r := &model.ProblemReport{} 497 require.NoError(t, msg.Decode(r)) 498 require.Equal(t, codeRejectedError, r.Description.Code) 499 require.Equal(t, ProblemReportMsgTypeV2, r.Type) 500 501 return nil 502 }) 503 504 svc, err := New(newProvider) 505 require.NoError(t, err) 506 507 ch := make(chan service.DIDCommAction, 1) 508 require.NoError(t, svc.RegisterActionEvent(ch)) 509 510 msg := service.NewDIDCommMsgMap(ProposeCredentialV2{ 511 Type: ProposeCredentialMsgTypeV2, 512 }) 513 514 msg.SetID(uuid.New().String()) 515 516 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 517 require.NoError(t, err) 518 519 actions, err := svc.Actions() 520 require.NoError(t, err) 521 for _, action := range actions { 522 require.Equal(t, action.MyDID, Alice) 523 require.Equal(t, action.TheirDID, Bob) 524 require.NoError(t, svc.ActionStop(action.PIID, nil)) 525 } 526 527 select { 528 case <-done: 529 return 530 case <-time.After(time.Second): 531 t.Error("timeout") 532 } 533 }) 534 535 t.Run("Receive Offer Credential Stop", func(t *testing.T) { 536 done := make(chan struct{}) 537 538 messenger.EXPECT(). 539 ReplyToNested(gomock.Any(), gomock.Any()). 540 Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error { 541 defer close(done) 542 543 r := &model.ProblemReport{} 544 require.NoError(t, msg.Decode(r)) 545 require.Equal(t, codeRejectedError, r.Description.Code) 546 require.Equal(t, ProblemReportMsgTypeV2, r.Type) 547 548 return nil 549 }) 550 551 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 552 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 553 store.EXPECT().Delete(gomock.Any()).Return(nil) 554 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 555 require.Equal(t, "done", string(name)) 556 557 return nil 558 }) 559 560 svc, err := New(provider) 561 require.NoError(t, err) 562 563 ch := make(chan service.DIDCommAction, 1) 564 require.NoError(t, svc.RegisterActionEvent(ch)) 565 566 msg := service.NewDIDCommMsgMap(OfferCredentialV2{ 567 Type: OfferCredentialMsgTypeV2, 568 }) 569 570 msg.SetID(uuid.New().String()) 571 572 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 573 require.NoError(t, err) 574 575 action := <-ch 576 577 properties, ok := action.Properties.(*eventProps) 578 require.True(t, ok) 579 require.NotEmpty(t, properties.PIID()) 580 require.Equal(t, properties.MyDID(), Alice) 581 require.Equal(t, properties.TheirDID(), Bob) 582 583 action.Stop(nil) 584 585 select { 586 case <-done: 587 return 588 case <-time.After(time.Second): 589 t.Error("timeout") 590 } 591 }) 592 593 t.Run("Receive Offer Credential Continue with Proposal", func(t *testing.T) { 594 done := make(chan struct{}) 595 596 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 597 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 598 defer close(done) 599 600 r := &ProposeCredentialV2{} 601 require.NoError(t, msg.Decode(r)) 602 require.Equal(t, ProposeCredentialMsgTypeV2, r.Type) 603 604 return nil 605 }) 606 607 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 608 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 609 store.EXPECT().Delete(gomock.Any()).Return(nil) 610 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 611 require.Equal(t, "proposal-sent", string(name)) 612 613 return nil 614 }) 615 616 svc, err := New(provider) 617 require.NoError(t, err) 618 619 ch := make(chan service.DIDCommAction, 1) 620 require.NoError(t, svc.RegisterActionEvent(ch)) 621 622 msg := service.NewDIDCommMsgMap(OfferCredentialV2{ 623 Type: OfferCredentialMsgTypeV2, 624 }) 625 626 msg.SetID(uuid.New().String()) 627 628 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 629 require.NoError(t, err) 630 631 action := <-ch 632 633 properties, ok := action.Properties.(*eventProps) 634 require.True(t, ok) 635 require.NotEmpty(t, properties.PIID()) 636 require.Equal(t, properties.MyDID(), Alice) 637 require.Equal(t, properties.TheirDID(), Bob) 638 639 action.Continue(WithProposeCredential(&ProposeCredentialParams{})) 640 641 select { 642 case <-done: 643 return 644 case <-time.After(time.Second): 645 t.Error("timeout") 646 } 647 }) 648 649 t.Run("Receive Offer Credential Continue with Invitation", func(t *testing.T) { 650 done := make(chan struct{}) 651 652 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 653 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 654 defer close(done) 655 656 r := &RequestCredentialV2{} 657 require.NoError(t, msg.Decode(r)) 658 require.Equal(t, RequestCredentialMsgTypeV2, r.Type) 659 660 return nil 661 }) 662 663 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 664 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 665 store.EXPECT().Delete(gomock.Any()).Return(nil) 666 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 667 require.Equal(t, "request-sent", string(name)) 668 669 return nil 670 }) 671 672 svc, err := New(provider) 673 require.NoError(t, err) 674 675 ch := make(chan service.DIDCommAction, 1) 676 require.NoError(t, svc.RegisterActionEvent(ch)) 677 678 msg := service.NewDIDCommMsgMap(OfferCredentialV2{ 679 Type: OfferCredentialMsgTypeV2, 680 }) 681 682 msg.SetID(uuid.New().String()) 683 684 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 685 require.NoError(t, err) 686 687 action := <-ch 688 689 properties, ok := action.Properties.(*eventProps) 690 require.True(t, ok) 691 require.NotEmpty(t, properties.PIID()) 692 require.Equal(t, properties.MyDID(), Alice) 693 require.Equal(t, properties.TheirDID(), Bob) 694 695 action.Continue(WithRequestCredential(&RequestCredentialParams{Comment: "test"})) 696 697 select { 698 case <-done: 699 return 700 case <-time.After(time.Second): 701 t.Error("timeout") 702 } 703 }) 704 705 t.Run("Receive Offer Credential", func(t *testing.T) { 706 done := make(chan struct{}) 707 attachment := []decorator.Attachment{{ID: "ID1"}, {ID: "ID2"}} 708 709 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 710 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 711 defer close(done) 712 713 r := &RequestCredentialV2{} 714 require.NoError(t, msg.Decode(r)) 715 require.Equal(t, RequestCredentialMsgTypeV2, r.Type) 716 require.Equal(t, attachment, r.RequestsAttach) 717 718 return nil 719 }) 720 721 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 722 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 723 store.EXPECT().Delete(gomock.Any()).Return(nil) 724 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 725 require.Equal(t, "request-sent", string(name)) 726 727 return nil 728 }) 729 730 svc, err := New(provider) 731 require.NoError(t, err) 732 733 ch := make(chan service.DIDCommAction, 1) 734 require.NoError(t, svc.RegisterActionEvent(ch)) 735 736 msg := service.NewDIDCommMsgMap(OfferCredentialV2{ 737 Type: OfferCredentialMsgTypeV2, 738 OffersAttach: attachment, 739 }) 740 741 msg.SetID(uuid.New().String()) 742 743 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 744 require.NoError(t, err) 745 746 action := <-ch 747 748 properties, ok := action.Properties.(*eventProps) 749 require.True(t, ok) 750 require.NotEmpty(t, properties.PIID()) 751 require.Equal(t, properties.MyDID(), Alice) 752 require.Equal(t, properties.TheirDID(), Bob) 753 754 action.Continue(nil) 755 756 select { 757 case <-done: 758 return 759 case <-time.After(time.Second): 760 t.Error("timeout") 761 } 762 }) 763 764 t.Run("Receive Invitation Credential Stop", func(t *testing.T) { 765 done := make(chan struct{}) 766 767 messenger.EXPECT(). 768 ReplyToNested(gomock.Any(), gomock.Any()). 769 Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error { 770 defer close(done) 771 772 r := &model.ProblemReport{} 773 require.NoError(t, msg.Decode(r)) 774 require.Equal(t, codeRejectedError, r.Description.Code) 775 require.Equal(t, ProblemReportMsgTypeV2, r.Type) 776 777 return nil 778 }) 779 780 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 781 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 782 store.EXPECT().Delete(gomock.Any()).Return(nil) 783 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 784 require.Equal(t, "done", string(name)) 785 786 return nil 787 }) 788 789 svc, err := New(provider) 790 require.NoError(t, err) 791 792 ch := make(chan service.DIDCommAction, 1) 793 require.NoError(t, svc.RegisterActionEvent(ch)) 794 795 msg := service.NewDIDCommMsgMap(RequestCredentialV2{ 796 Type: RequestCredentialMsgTypeV2, 797 }) 798 799 msg.SetID(uuid.New().String()) 800 801 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 802 require.NoError(t, err) 803 804 action := <-ch 805 806 properties, ok := action.Properties.(*eventProps) 807 require.True(t, ok) 808 require.NotEmpty(t, properties.PIID()) 809 require.Equal(t, properties.MyDID(), Alice) 810 require.Equal(t, properties.TheirDID(), Bob) 811 812 action.Stop(nil) 813 814 select { 815 case <-done: 816 return 817 case <-time.After(time.Second): 818 t.Error("timeout") 819 } 820 }) 821 822 t.Run("Receive Invitation Credential Continue", func(t *testing.T) { 823 done := make(chan struct{}) 824 825 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 826 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 827 defer close(done) 828 829 r := &IssueCredentialV2{} 830 require.NoError(t, msg.Decode(r)) 831 require.Equal(t, IssueCredentialMsgTypeV2, r.Type) 832 833 return nil 834 }) 835 836 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 837 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 838 store.EXPECT().Delete(gomock.Any()).Return(nil) 839 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 840 require.Equal(t, "credential-issued", string(name)) 841 842 return nil 843 }) 844 845 svc, err := New(provider) 846 require.NoError(t, err) 847 848 ch := make(chan service.DIDCommAction, 1) 849 require.NoError(t, svc.RegisterActionEvent(ch)) 850 851 msg := service.NewDIDCommMsgMap(RequestCredentialV2{ 852 Type: RequestCredentialMsgTypeV2, 853 }) 854 855 msg.SetID(uuid.New().String()) 856 857 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 858 require.NoError(t, err) 859 860 action := <-ch 861 862 properties, ok := action.Properties.(*eventProps) 863 require.True(t, ok) 864 require.NotEmpty(t, properties.PIID()) 865 require.Equal(t, properties.MyDID(), Alice) 866 require.Equal(t, properties.TheirDID(), Bob) 867 868 action.Continue(WithIssueCredential(&IssueCredentialParams{})) 869 870 select { 871 case <-done: 872 return 873 case <-time.After(time.Second): 874 t.Error("timeout") 875 } 876 }) 877 878 t.Run("Receive Problem Report (continue)", func(t *testing.T) { 879 done := make(chan struct{}) 880 881 store.EXPECT().Get(gomock.Any()).Return([]byte("request-sent"), nil) 882 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 883 store.EXPECT().Delete(gomock.Any()).Return(nil) 884 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 885 defer close(done) 886 887 require.Equal(t, "done", string(name)) 888 889 return nil 890 }) 891 892 svc, err := New(provider) 893 require.NoError(t, err) 894 895 ch := make(chan service.DIDCommAction, 1) 896 require.NoError(t, svc.RegisterActionEvent(ch)) 897 898 msg := service.NewDIDCommMsgMap(RequestCredentialV2{ 899 Type: ProblemReportMsgTypeV2, 900 }) 901 902 msg.SetID(uuid.New().String()) 903 904 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 905 require.NoError(t, err) 906 907 action := <-ch 908 909 properties, ok := action.Properties.(*eventProps) 910 require.True(t, ok) 911 require.NotEmpty(t, properties.PIID()) 912 require.Equal(t, properties.MyDID(), Alice) 913 require.Equal(t, properties.TheirDID(), Bob) 914 915 action.Continue(WithIssueCredential(&IssueCredentialParams{})) 916 917 select { 918 case <-done: 919 return 920 case <-time.After(time.Second): 921 t.Error("timeout") 922 } 923 }) 924 925 t.Run("Receive Problem Report (stop)", func(t *testing.T) { 926 done := make(chan struct{}) 927 928 store.EXPECT().Get(gomock.Any()).Return([]byte("request-sent"), nil) 929 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 930 store.EXPECT().Delete(gomock.Any()).Return(nil) 931 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 932 defer close(done) 933 934 require.Equal(t, "done", string(name)) 935 936 return nil 937 }) 938 939 svc, err := New(provider) 940 require.NoError(t, err) 941 942 ch := make(chan service.DIDCommAction, 1) 943 require.NoError(t, svc.RegisterActionEvent(ch)) 944 945 msg := service.NewDIDCommMsgMap(RequestCredentialV2{ 946 Type: ProblemReportMsgTypeV2, 947 }) 948 949 msg.SetID(uuid.New().String()) 950 951 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 952 require.NoError(t, err) 953 954 action := <-ch 955 956 properties, ok := action.Properties.(*eventProps) 957 require.True(t, ok) 958 require.NotEmpty(t, properties.PIID()) 959 require.Equal(t, properties.MyDID(), Alice) 960 require.Equal(t, properties.TheirDID(), Bob) 961 962 action.Stop(nil) 963 964 select { 965 case <-done: 966 return 967 case <-time.After(time.Second): 968 t.Error("timeout") 969 } 970 }) 971 972 t.Run("Receive Issue Credential Continue", func(t *testing.T) { 973 done := make(chan struct{}) 974 975 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 976 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 977 defer close(done) 978 979 r := &model.Ack{} 980 require.NoError(t, msg.Decode(r)) 981 require.Equal(t, AckMsgTypeV2, r.Type) 982 983 return nil 984 }) 985 986 store.EXPECT().Get(gomock.Any()).Return([]byte("request-sent"), nil) 987 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 988 store.EXPECT().Delete(gomock.Any()).Return(nil) 989 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 990 require.Equal(t, "done", string(name)) 991 992 return nil 993 }) 994 995 svc, err := New(provider) 996 require.NoError(t, err) 997 998 ch := make(chan service.DIDCommAction, 1) 999 require.NoError(t, svc.RegisterActionEvent(ch)) 1000 issued := time.Date(2010, time.January, 1, 19, 23, 24, 0, time.UTC) 1001 msg := service.NewDIDCommMsgMap(IssueCredentialV2{ 1002 Type: IssueCredentialMsgTypeV2, 1003 CredentialsAttach: []decorator.Attachment{ 1004 {Data: decorator.AttachmentData{JSON: &verifiable.Credential{ 1005 Context: []string{ 1006 "https://www.w3.org/2018/credentials/v1", 1007 "https://www.w3.org/2018/credentials/examples/v1", 1008 }, 1009 ID: "http://example.edu/credentials/1872", 1010 Types: []string{ 1011 "VerifiableCredential", 1012 "UniversityDegreeCredential", 1013 }, 1014 Subject: struct { 1015 ID string 1016 }{ID: "SubjectID"}, 1017 Issuer: verifiable.Issuer{ 1018 ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", 1019 CustomFields: verifiable.CustomFields{"name": "Example University"}, 1020 }, 1021 Issued: util.NewTime(issued), 1022 Schemas: []verifiable.TypedID{}, 1023 CustomFields: map[string]interface{}{ 1024 "referenceNumber": 83294847, 1025 }, 1026 }}}, 1027 }, 1028 }) 1029 1030 msg.SetID(uuid.New().String()) 1031 1032 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1033 require.NoError(t, err) 1034 1035 action := <-ch 1036 1037 properties, ok := action.Properties.(*eventProps) 1038 require.True(t, ok) 1039 require.NotEmpty(t, properties.PIID()) 1040 require.Equal(t, properties.MyDID(), Alice) 1041 require.Equal(t, properties.TheirDID(), Bob) 1042 1043 action.Continue(WithFriendlyNames("UniversityDegree")) 1044 1045 select { 1046 case <-done: 1047 return 1048 case <-time.After(time.Second * 5): 1049 t.Error("timeout") 1050 } 1051 }) 1052 1053 t.Run("Receive Issue Credential Stop", func(t *testing.T) { 1054 done := make(chan struct{}) 1055 1056 messenger.EXPECT().ReplyToNested(gomock.Any(), gomock.Any()). 1057 Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error { 1058 defer close(done) 1059 1060 r := &model.ProblemReport{} 1061 require.NoError(t, msg.Decode(r)) 1062 require.Equal(t, codeRejectedError, r.Description.Code) 1063 require.Equal(t, ProblemReportMsgTypeV2, r.Type) 1064 1065 return nil 1066 }) 1067 1068 store.EXPECT().Get(gomock.Any()).Return([]byte("request-sent"), nil) 1069 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1070 store.EXPECT().Delete(gomock.Any()).Return(nil) 1071 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1072 require.Equal(t, "done", string(name)) 1073 1074 return nil 1075 }) 1076 1077 svc, err := New(provider) 1078 require.NoError(t, err) 1079 1080 ch := make(chan service.DIDCommAction, 1) 1081 require.NoError(t, svc.RegisterActionEvent(ch)) 1082 1083 msg := service.NewDIDCommMsgMap(IssueCredentialV2{ 1084 Type: IssueCredentialMsgTypeV2, 1085 }) 1086 1087 msg.SetID(uuid.New().String()) 1088 1089 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1090 require.NoError(t, err) 1091 1092 action := <-ch 1093 1094 properties, ok := action.Properties.(*eventProps) 1095 require.True(t, ok) 1096 require.NotEmpty(t, properties.PIID()) 1097 require.Equal(t, properties.MyDID(), Alice) 1098 require.Equal(t, properties.TheirDID(), Bob) 1099 1100 action.Stop(errors.New("invalid credential")) 1101 1102 select { 1103 case <-done: 1104 return 1105 case <-time.After(time.Second): 1106 t.Error("timeout") 1107 } 1108 }) 1109 1110 t.Run("Receive Ack message", func(t *testing.T) { 1111 done := make(chan struct{}) 1112 1113 store.EXPECT().Get(gomock.Any()).Return([]byte("credential-issued"), nil) 1114 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1115 defer close(done) 1116 1117 require.Equal(t, "done", string(name)) 1118 1119 return nil 1120 }) 1121 1122 svc, err := New(provider) 1123 require.NoError(t, err) 1124 1125 require.NoError(t, svc.RegisterActionEvent(make(chan service.DIDCommAction))) 1126 1127 msg := service.NewDIDCommMsgMap(model.Ack{ 1128 Type: AckMsgTypeV2, 1129 }) 1130 1131 msg.SetID(uuid.New().String()) 1132 1133 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1134 require.NoError(t, err) 1135 1136 select { 1137 case <-done: 1138 return 1139 case <-time.After(time.Second): 1140 t.Error("timeout") 1141 } 1142 }) 1143 1144 t.Run("Invalid state transition", func(t *testing.T) { 1145 svc, err := New(provider) 1146 require.NoError(t, err) 1147 1148 ch := make(chan service.DIDCommAction, 1) 1149 require.NoError(t, svc.RegisterActionEvent(ch)) 1150 1151 chState := make(chan service.StateMsg, 2) 1152 require.NoError(t, svc.RegisterMsgEvent(chState)) 1153 1154 _, err = svc.HandleInbound(service.NewDIDCommMsgMap(model.ProblemReport{ 1155 Type: ProblemReportMsgTypeV2, 1156 }), service.EmptyDIDCommContext()) 1157 require.Contains(t, fmt.Sprintf("%v", err), "doHandle: invalid state transition") 1158 }) 1159 } 1160 1161 // nolint: gocyclo,gocognit 1162 func TestService_HandleInboundV3(t *testing.T) { 1163 ctrl := gomock.NewController(t) 1164 defer ctrl.Finish() 1165 1166 const errMsg = "error" 1167 1168 initMocks := func(controller *gomock.Controller) ( 1169 store *storageMocks.MockStore, 1170 messenger *serviceMocks.MockMessenger, 1171 provider *issuecredentialMocks.MockProvider, 1172 ) { 1173 store = storageMocks.NewMockStore(controller) 1174 1175 storeProvider := storageMocks.NewMockProvider(controller) 1176 storeProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil).AnyTimes() 1177 storeProvider.EXPECT().SetStoreConfig(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 1178 1179 messenger = serviceMocks.NewMockMessenger(controller) 1180 1181 provider = issuecredentialMocks.NewMockProvider(controller) 1182 provider.EXPECT().Messenger().Return(messenger).AnyTimes() 1183 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 1184 1185 return store, messenger, provider 1186 } 1187 1188 t.Run("DB error (saveTransitionalPayload)", func(t *testing.T) { 1189 store, _, provider := initMocks(ctrl) 1190 1191 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 1192 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New(errMsg)) 1193 1194 svc, err := New(provider) 1195 require.NoError(t, err) 1196 1197 require.NoError(t, svc.RegisterActionEvent(make(chan<- service.DIDCommAction))) 1198 1199 msg := service.NewDIDCommMsgMap(ProposeCredentialV2{ 1200 Type: ProposeCredentialMsgTypeV3, 1201 }) 1202 msg.SetID(uuid.New().String()) 1203 _, err = svc.HandleInbound(msg, service.EmptyDIDCommContext()) 1204 require.Contains(t, fmt.Sprintf("%v", err), "save transitional payload: "+errMsg) 1205 }) 1206 1207 t.Run("Receive Propose Credential Stop", func(t *testing.T) { 1208 store, messenger, provider := initMocks(ctrl) 1209 1210 done := make(chan struct{}) 1211 1212 messenger.EXPECT(). 1213 ReplyToNested(gomock.Any(), gomock.Any()). 1214 Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error { 1215 defer close(done) 1216 1217 r := &model.ProblemReportV2{} 1218 require.NoError(t, msg.Decode(r)) 1219 require.Equal(t, codeRejectedError, r.Body.Code) 1220 require.Equal(t, ProblemReportMsgTypeV3, r.Type) 1221 1222 return nil 1223 }) 1224 1225 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 1226 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1227 store.EXPECT().Delete(gomock.Any()).Return(nil) 1228 store.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1229 require.Equal(t, "done", string(name)) 1230 1231 return nil 1232 }) 1233 1234 svc, err := New(provider) 1235 require.NoError(t, err) 1236 1237 ch := make(chan service.DIDCommAction, 1) 1238 require.NoError(t, svc.RegisterActionEvent(ch)) 1239 1240 msg := service.NewDIDCommMsgMap(ProposeCredentialV2{ 1241 Type: ProposeCredentialMsgTypeV3, 1242 }) 1243 1244 msg.SetID(uuid.New().String()) 1245 1246 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1247 require.NoError(t, err) 1248 1249 action := <-ch 1250 1251 properties, ok := action.Properties.(*eventProps) 1252 require.True(t, ok) 1253 require.NotEmpty(t, properties.PIID()) 1254 require.Equal(t, properties.MyDID(), Alice) 1255 require.Equal(t, properties.TheirDID(), Bob) 1256 require.Equal(t, properties.All()["myDID"], Alice) 1257 require.Equal(t, properties.All()["theirDID"], Bob) 1258 1259 action.Stop(nil) 1260 1261 select { 1262 case <-done: 1263 return 1264 case <-time.After(time.Second): 1265 t.Error("timeout") 1266 } 1267 }) 1268 1269 t.Run("Receive Propose Credential Continue", func(t *testing.T) { 1270 store, messenger, provider := initMocks(ctrl) 1271 1272 done := make(chan struct{}) 1273 1274 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 1275 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 1276 defer close(done) 1277 1278 r := &OfferCredentialV3{} 1279 require.NoError(t, msg.Decode(r)) 1280 require.Equal(t, OfferCredentialMsgTypeV3, r.Type) 1281 1282 return nil 1283 }) 1284 1285 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 1286 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1287 store.EXPECT().Delete(gomock.Any()).Return(nil) 1288 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1289 require.Equal(t, "offer-sent", string(name)) 1290 1291 return nil 1292 }) 1293 1294 svc, err := New(provider) 1295 require.NoError(t, err) 1296 1297 ch := make(chan service.DIDCommAction, 1) 1298 require.NoError(t, svc.RegisterActionEvent(ch)) 1299 1300 msg := service.NewDIDCommMsgMap(ProposeCredentialV3{ 1301 Type: ProposeCredentialMsgTypeV3, 1302 }) 1303 1304 msg.SetID(uuid.New().String()) 1305 1306 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1307 require.NoError(t, err) 1308 1309 action := <-ch 1310 1311 properties, ok := action.Properties.(*eventProps) 1312 require.True(t, ok) 1313 require.NotEmpty(t, properties.PIID()) 1314 require.Equal(t, properties.MyDID(), Alice) 1315 require.Equal(t, properties.TheirDID(), Bob) 1316 1317 action.Continue(WithOfferCredential(&OfferCredentialParams{})) 1318 1319 select { 1320 case <-done: 1321 return 1322 case <-time.After(time.Second): 1323 t.Error("timeout") 1324 } 1325 }) 1326 1327 t.Run("Receive Propose Credential Continue (async)", func(t *testing.T) { 1328 _, messenger, _ := initMocks(ctrl) 1329 1330 done := make(chan struct{}) 1331 1332 newProvider := issuecredentialMocks.NewMockProvider(ctrl) 1333 newProvider.EXPECT().Messenger().Return(messenger).AnyTimes() 1334 newProvider.EXPECT().StorageProvider().Return(mem.NewProvider()).AnyTimes() 1335 1336 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 1337 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 1338 defer close(done) 1339 1340 r := &OfferCredentialV3{} 1341 require.NoError(t, msg.Decode(r)) 1342 require.Equal(t, OfferCredentialMsgTypeV3, r.Type) 1343 1344 return nil 1345 }) 1346 1347 svc, err := New(newProvider) 1348 require.NoError(t, err) 1349 1350 ch := make(chan service.DIDCommAction, 1) 1351 require.NoError(t, svc.RegisterActionEvent(ch)) 1352 1353 msg := service.NewDIDCommMsgMap(ProposeCredentialV3{ 1354 Type: ProposeCredentialMsgTypeV3, 1355 }) 1356 1357 msg.SetID(uuid.New().String()) 1358 1359 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1360 require.NoError(t, err) 1361 1362 actions, err := svc.Actions() 1363 require.NoError(t, err) 1364 for _, action := range actions { 1365 require.Equal(t, action.MyDID, Alice) 1366 require.Equal(t, action.TheirDID, Bob) 1367 require.NoError(t, svc.ActionContinue(action.PIID, WithOfferCredential(&OfferCredentialParams{}))) 1368 } 1369 1370 select { 1371 case <-done: 1372 return 1373 case <-time.After(time.Second): 1374 t.Error("timeout") 1375 } 1376 }) 1377 1378 t.Run("Receive Propose Credential Stop (async)", func(t *testing.T) { 1379 _, messenger, _ := initMocks(ctrl) 1380 1381 done := make(chan struct{}) 1382 1383 newProvider := issuecredentialMocks.NewMockProvider(ctrl) 1384 newProvider.EXPECT().Messenger().Return(messenger).AnyTimes() 1385 newProvider.EXPECT().StorageProvider().Return(mem.NewProvider()).AnyTimes() 1386 1387 messenger.EXPECT(). 1388 ReplyToNested(gomock.Any(), gomock.Any()). 1389 Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error { 1390 defer close(done) 1391 1392 r := &model.ProblemReportV2{} 1393 require.NoError(t, msg.Decode(r)) 1394 require.Equal(t, codeRejectedError, r.Body.Code) 1395 require.Equal(t, ProblemReportMsgTypeV3, r.Type) 1396 1397 return nil 1398 }) 1399 1400 svc, err := New(newProvider) 1401 require.NoError(t, err) 1402 1403 ch := make(chan service.DIDCommAction, 1) 1404 require.NoError(t, svc.RegisterActionEvent(ch)) 1405 1406 msg := service.NewDIDCommMsgMap(ProposeCredentialV3{ 1407 Type: ProposeCredentialMsgTypeV3, 1408 }) 1409 1410 msg.SetID(uuid.New().String()) 1411 1412 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1413 require.NoError(t, err) 1414 1415 actions, err := svc.Actions() 1416 require.NoError(t, err) 1417 for _, action := range actions { 1418 require.Equal(t, action.MyDID, Alice) 1419 require.Equal(t, action.TheirDID, Bob) 1420 require.NoError(t, svc.ActionStop(action.PIID, nil)) 1421 } 1422 1423 select { 1424 case <-done: 1425 return 1426 case <-time.After(time.Second): 1427 t.Error("timeout") 1428 } 1429 }) 1430 1431 t.Run("Receive Offer Credential Stop", func(t *testing.T) { 1432 store, messenger, provider := initMocks(ctrl) 1433 1434 done := make(chan struct{}) 1435 1436 messenger.EXPECT(). 1437 ReplyToNested(gomock.Any(), gomock.Any()). 1438 Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error { 1439 defer close(done) 1440 1441 r := &model.ProblemReportV2{} 1442 require.NoError(t, msg.Decode(r)) 1443 require.Equal(t, codeRejectedError, r.Body.Code) 1444 require.Equal(t, ProblemReportMsgTypeV3, r.Type) 1445 1446 return nil 1447 }) 1448 1449 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 1450 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1451 store.EXPECT().Delete(gomock.Any()).Return(nil) 1452 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1453 require.Equal(t, "done", string(name)) 1454 1455 return nil 1456 }) 1457 1458 svc, err := New(provider) 1459 require.NoError(t, err) 1460 1461 ch := make(chan service.DIDCommAction, 1) 1462 require.NoError(t, svc.RegisterActionEvent(ch)) 1463 1464 msg := service.NewDIDCommMsgMap(OfferCredentialV3{ 1465 Type: OfferCredentialMsgTypeV3, 1466 }) 1467 1468 msg.SetID(uuid.New().String()) 1469 1470 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1471 require.NoError(t, err) 1472 1473 action := <-ch 1474 1475 properties, ok := action.Properties.(*eventProps) 1476 require.True(t, ok) 1477 require.NotEmpty(t, properties.PIID()) 1478 require.Equal(t, properties.MyDID(), Alice) 1479 require.Equal(t, properties.TheirDID(), Bob) 1480 1481 action.Stop(nil) 1482 1483 select { 1484 case <-done: 1485 return 1486 case <-time.After(time.Second): 1487 t.Error("timeout") 1488 } 1489 }) 1490 1491 t.Run("Receive Offer Credential Continue with Proposal", func(t *testing.T) { 1492 store, messenger, provider := initMocks(ctrl) 1493 1494 done := make(chan struct{}) 1495 1496 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 1497 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 1498 defer close(done) 1499 1500 r := &ProposeCredentialV3{} 1501 require.NoError(t, msg.Decode(r)) 1502 require.Equal(t, ProposeCredentialMsgTypeV3, r.Type) 1503 1504 return nil 1505 }) 1506 1507 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 1508 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1509 store.EXPECT().Delete(gomock.Any()).Return(nil) 1510 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1511 require.Equal(t, "proposal-sent", string(name)) 1512 1513 return nil 1514 }) 1515 1516 svc, err := New(provider) 1517 require.NoError(t, err) 1518 1519 ch := make(chan service.DIDCommAction, 1) 1520 require.NoError(t, svc.RegisterActionEvent(ch)) 1521 1522 msg := service.NewDIDCommMsgMap(OfferCredentialV3{ 1523 Type: OfferCredentialMsgTypeV3, 1524 }) 1525 1526 msg.SetID(uuid.New().String()) 1527 1528 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1529 require.NoError(t, err) 1530 1531 action := <-ch 1532 1533 properties, ok := action.Properties.(*eventProps) 1534 require.True(t, ok) 1535 require.NotEmpty(t, properties.PIID()) 1536 require.Equal(t, properties.MyDID(), Alice) 1537 require.Equal(t, properties.TheirDID(), Bob) 1538 1539 action.Continue(WithProposeCredential(&ProposeCredentialParams{})) 1540 1541 select { 1542 case <-done: 1543 return 1544 case <-time.After(time.Second): 1545 t.Error("timeout") 1546 } 1547 }) 1548 1549 t.Run("Receive Offer Credential Continue with Invitation", func(t *testing.T) { 1550 store, messenger, provider := initMocks(ctrl) 1551 1552 done := make(chan struct{}) 1553 1554 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 1555 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 1556 defer close(done) 1557 1558 r := &RequestCredentialV3{} 1559 require.NoError(t, msg.Decode(r)) 1560 require.Equal(t, RequestCredentialMsgTypeV3, r.Type) 1561 1562 return nil 1563 }) 1564 1565 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 1566 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1567 store.EXPECT().Delete(gomock.Any()).Return(nil) 1568 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1569 require.Equal(t, "request-sent", string(name)) 1570 1571 return nil 1572 }) 1573 1574 svc, err := New(provider) 1575 require.NoError(t, err) 1576 1577 ch := make(chan service.DIDCommAction, 1) 1578 require.NoError(t, svc.RegisterActionEvent(ch)) 1579 1580 msg := service.NewDIDCommMsgMap(OfferCredentialV3{ 1581 Type: OfferCredentialMsgTypeV3, 1582 }) 1583 1584 msg.SetID(uuid.New().String()) 1585 1586 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1587 require.NoError(t, err) 1588 1589 action := <-ch 1590 1591 properties, ok := action.Properties.(*eventProps) 1592 require.True(t, ok) 1593 require.NotEmpty(t, properties.PIID()) 1594 require.Equal(t, properties.MyDID(), Alice) 1595 require.Equal(t, properties.TheirDID(), Bob) 1596 1597 action.Continue(WithRequestCredential(&RequestCredentialParams{Comment: "test"})) 1598 1599 select { 1600 case <-done: 1601 return 1602 case <-time.After(time.Second): 1603 t.Error("timeout") 1604 } 1605 }) 1606 1607 t.Run("Receive Offer Credential", func(t *testing.T) { 1608 store, messenger, provider := initMocks(ctrl) 1609 1610 done := make(chan struct{}) 1611 attachment := []decorator.AttachmentV2{{ID: "ID1"}, {ID: "ID2"}} 1612 1613 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 1614 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 1615 defer close(done) 1616 1617 r := &RequestCredentialV3{} 1618 require.NoError(t, msg.Decode(r)) 1619 require.Equal(t, RequestCredentialMsgTypeV3, r.Type) 1620 require.Equal(t, attachment, r.Attachments) 1621 1622 return nil 1623 }) 1624 1625 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 1626 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1627 store.EXPECT().Delete(gomock.Any()).Return(nil) 1628 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1629 require.Equal(t, "request-sent", string(name)) 1630 1631 return nil 1632 }) 1633 1634 svc, err := New(provider) 1635 require.NoError(t, err) 1636 1637 ch := make(chan service.DIDCommAction, 1) 1638 require.NoError(t, svc.RegisterActionEvent(ch)) 1639 1640 msg := service.NewDIDCommMsgMap(OfferCredentialV3{ 1641 Type: OfferCredentialMsgTypeV3, 1642 Attachments: attachment, 1643 }) 1644 1645 msg.SetID(uuid.New().String()) 1646 1647 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1648 require.NoError(t, err) 1649 1650 action := <-ch 1651 1652 properties, ok := action.Properties.(*eventProps) 1653 require.True(t, ok) 1654 require.NotEmpty(t, properties.PIID()) 1655 require.Equal(t, properties.MyDID(), Alice) 1656 require.Equal(t, properties.TheirDID(), Bob) 1657 1658 action.Continue(nil) 1659 1660 select { 1661 case <-done: 1662 return 1663 case <-time.After(time.Second): 1664 t.Error("timeout") 1665 } 1666 }) 1667 1668 t.Run("Receive Invitation Credential Stop", func(t *testing.T) { 1669 store, messenger, provider := initMocks(ctrl) 1670 1671 done := make(chan struct{}) 1672 1673 messenger.EXPECT(). 1674 ReplyToNested(gomock.Any(), gomock.Any()). 1675 Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error { 1676 defer close(done) 1677 1678 r := &model.ProblemReportV2{} 1679 require.NoError(t, msg.Decode(r)) 1680 require.Equal(t, codeRejectedError, r.Body.Code) 1681 require.Equal(t, ProblemReportMsgTypeV3, r.Type) 1682 1683 return nil 1684 }) 1685 1686 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 1687 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1688 store.EXPECT().Delete(gomock.Any()).Return(nil) 1689 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1690 require.Equal(t, "done", string(name)) 1691 1692 return nil 1693 }) 1694 1695 svc, err := New(provider) 1696 require.NoError(t, err) 1697 1698 ch := make(chan service.DIDCommAction, 1) 1699 require.NoError(t, svc.RegisterActionEvent(ch)) 1700 1701 msg := service.NewDIDCommMsgMap(RequestCredentialV3{ 1702 Type: RequestCredentialMsgTypeV3, 1703 }) 1704 1705 msg.SetID(uuid.New().String()) 1706 1707 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1708 require.NoError(t, err) 1709 1710 action := <-ch 1711 1712 properties, ok := action.Properties.(*eventProps) 1713 require.True(t, ok) 1714 require.NotEmpty(t, properties.PIID()) 1715 require.Equal(t, properties.MyDID(), Alice) 1716 require.Equal(t, properties.TheirDID(), Bob) 1717 1718 action.Stop(nil) 1719 1720 select { 1721 case <-done: 1722 return 1723 case <-time.After(time.Second): 1724 t.Error("timeout") 1725 } 1726 }) 1727 1728 t.Run("Receive Invitation Credential Continue", func(t *testing.T) { 1729 store, messenger, provider := initMocks(ctrl) 1730 1731 done := make(chan struct{}) 1732 1733 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 1734 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 1735 defer close(done) 1736 1737 r := &IssueCredentialV3{} 1738 require.NoError(t, msg.Decode(r)) 1739 require.Equal(t, IssueCredentialMsgTypeV3, r.Type) 1740 1741 return nil 1742 }) 1743 1744 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 1745 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1746 store.EXPECT().Delete(gomock.Any()).Return(nil) 1747 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1748 require.Equal(t, "credential-issued", string(name)) 1749 1750 return nil 1751 }) 1752 1753 svc, err := New(provider) 1754 require.NoError(t, err) 1755 1756 ch := make(chan service.DIDCommAction, 1) 1757 require.NoError(t, svc.RegisterActionEvent(ch)) 1758 1759 msg := service.NewDIDCommMsgMap(RequestCredentialV3{ 1760 Type: RequestCredentialMsgTypeV3, 1761 }) 1762 1763 msg.SetID(uuid.New().String()) 1764 1765 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1766 require.NoError(t, err) 1767 1768 action := <-ch 1769 1770 properties, ok := action.Properties.(*eventProps) 1771 require.True(t, ok) 1772 require.NotEmpty(t, properties.PIID()) 1773 require.Equal(t, properties.MyDID(), Alice) 1774 require.Equal(t, properties.TheirDID(), Bob) 1775 1776 action.Continue(WithIssueCredential(&IssueCredentialParams{})) 1777 1778 select { 1779 case <-done: 1780 return 1781 case <-time.After(time.Second): 1782 t.Error("timeout") 1783 } 1784 }) 1785 1786 t.Run("Receive Problem Report (continue)", func(t *testing.T) { 1787 store, _, provider := initMocks(ctrl) 1788 1789 done := make(chan struct{}) 1790 1791 store.EXPECT().Get(gomock.Any()).Return([]byte("request-sent"), nil) 1792 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1793 store.EXPECT().Delete(gomock.Any()).Return(nil) 1794 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1795 defer close(done) 1796 1797 require.Equal(t, "done", string(name)) 1798 1799 return nil 1800 }) 1801 1802 svc, err := New(provider) 1803 require.NoError(t, err) 1804 1805 ch := make(chan service.DIDCommAction, 1) 1806 require.NoError(t, svc.RegisterActionEvent(ch)) 1807 1808 msg := service.NewDIDCommMsgMap(RequestCredentialV3{ 1809 Type: ProblemReportMsgTypeV3, 1810 }) 1811 1812 msg.SetID(uuid.New().String()) 1813 1814 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1815 require.NoError(t, err) 1816 1817 action := <-ch 1818 1819 properties, ok := action.Properties.(*eventProps) 1820 require.True(t, ok) 1821 require.NotEmpty(t, properties.PIID()) 1822 require.Equal(t, properties.MyDID(), Alice) 1823 require.Equal(t, properties.TheirDID(), Bob) 1824 1825 action.Continue(WithIssueCredential(&IssueCredentialParams{})) 1826 1827 select { 1828 case <-done: 1829 return 1830 case <-time.After(time.Second): 1831 t.Error("timeout") 1832 } 1833 }) 1834 1835 t.Run("Receive Problem Report (stop)", func(t *testing.T) { 1836 store, _, provider := initMocks(ctrl) 1837 1838 done := make(chan struct{}) 1839 1840 store.EXPECT().Get(gomock.Any()).Return([]byte("request-sent"), nil) 1841 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1842 store.EXPECT().Delete(gomock.Any()).Return(nil) 1843 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1844 defer close(done) 1845 1846 require.Equal(t, "done", string(name)) 1847 1848 return nil 1849 }) 1850 1851 svc, err := New(provider) 1852 require.NoError(t, err) 1853 1854 ch := make(chan service.DIDCommAction, 1) 1855 require.NoError(t, svc.RegisterActionEvent(ch)) 1856 1857 msg := service.NewDIDCommMsgMap(RequestCredentialV3{ 1858 Type: ProblemReportMsgTypeV3, 1859 }) 1860 1861 msg.SetID(uuid.New().String()) 1862 1863 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1864 require.NoError(t, err) 1865 1866 action := <-ch 1867 1868 properties, ok := action.Properties.(*eventProps) 1869 require.True(t, ok) 1870 require.NotEmpty(t, properties.PIID()) 1871 require.Equal(t, properties.MyDID(), Alice) 1872 require.Equal(t, properties.TheirDID(), Bob) 1873 1874 action.Stop(nil) 1875 1876 select { 1877 case <-done: 1878 return 1879 case <-time.After(time.Second): 1880 t.Error("timeout") 1881 } 1882 }) 1883 1884 t.Run("Receive Issue Credential Continue", func(t *testing.T) { 1885 store, messenger, provider := initMocks(ctrl) 1886 1887 done := make(chan struct{}) 1888 1889 messenger.EXPECT().ReplyToMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). 1890 Do(func(_, msg service.DIDCommMsgMap, _, _ string, opts ...service.Opt) error { 1891 defer close(done) 1892 1893 r := &model.AckV2{} 1894 require.NoError(t, msg.Decode(r)) 1895 require.Equal(t, AckMsgTypeV3, r.Type) 1896 1897 return nil 1898 }) 1899 1900 store.EXPECT().Get(gomock.Any()).Return([]byte("request-sent"), nil) 1901 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1902 store.EXPECT().Delete(gomock.Any()).Return(nil) 1903 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1904 require.Equal(t, "done", string(name)) 1905 1906 return nil 1907 }) 1908 1909 svc, err := New(provider) 1910 require.NoError(t, err) 1911 1912 ch := make(chan service.DIDCommAction, 1) 1913 require.NoError(t, svc.RegisterActionEvent(ch)) 1914 issued := time.Date(2010, time.January, 1, 19, 23, 24, 0, time.UTC) 1915 msg := service.NewDIDCommMsgMap(IssueCredentialV3{ 1916 Type: IssueCredentialMsgTypeV3, 1917 Attachments: []decorator.AttachmentV2{ 1918 {Data: decorator.AttachmentData{JSON: &verifiable.Credential{ 1919 Context: []string{ 1920 "https://www.w3.org/2018/credentials/v1", 1921 "https://www.w3.org/2018/credentials/examples/v1", 1922 }, 1923 ID: "http://example.edu/credentials/1872", 1924 Types: []string{ 1925 "VerifiableCredential", 1926 "UniversityDegreeCredential", 1927 }, 1928 Subject: struct { 1929 ID string 1930 }{ID: "SubjectID"}, 1931 Issuer: verifiable.Issuer{ 1932 ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", 1933 CustomFields: verifiable.CustomFields{"name": "Example University"}, 1934 }, 1935 Issued: util.NewTime(issued), 1936 Schemas: []verifiable.TypedID{}, 1937 CustomFields: map[string]interface{}{ 1938 "referenceNumber": 83294847, 1939 }, 1940 }}}, 1941 }, 1942 }) 1943 1944 msg.SetID(uuid.New().String()) 1945 1946 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 1947 require.NoError(t, err) 1948 1949 action := <-ch 1950 1951 properties, ok := action.Properties.(*eventProps) 1952 require.True(t, ok) 1953 require.NotEmpty(t, properties.PIID()) 1954 require.Equal(t, properties.MyDID(), Alice) 1955 require.Equal(t, properties.TheirDID(), Bob) 1956 1957 action.Continue(WithFriendlyNames("UniversityDegree")) 1958 1959 select { 1960 case <-done: 1961 return 1962 case <-time.After(time.Second * 5): 1963 t.Error("timeout") 1964 } 1965 }) 1966 1967 t.Run("Receive Issue Credential Stop", func(t *testing.T) { 1968 store, messenger, provider := initMocks(ctrl) 1969 1970 done := make(chan struct{}) 1971 1972 messenger.EXPECT().ReplyToNested(gomock.Any(), gomock.Any()). 1973 Do(func(msg service.DIDCommMsgMap, opts *service.NestedReplyOpts) error { 1974 defer close(done) 1975 1976 r := &model.ProblemReportV2{} 1977 require.NoError(t, msg.Decode(r)) 1978 require.Equal(t, codeRejectedError, r.Body.Code) 1979 require.Equal(t, ProblemReportMsgTypeV3, r.Type) 1980 1981 return nil 1982 }) 1983 1984 store.EXPECT().Get(gomock.Any()).Return([]byte("request-sent"), nil) 1985 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 1986 store.EXPECT().Delete(gomock.Any()).Return(nil) 1987 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 1988 require.Equal(t, "done", string(name)) 1989 1990 return nil 1991 }) 1992 1993 svc, err := New(provider) 1994 require.NoError(t, err) 1995 1996 ch := make(chan service.DIDCommAction, 1) 1997 require.NoError(t, svc.RegisterActionEvent(ch)) 1998 1999 msg := service.NewDIDCommMsgMap(IssueCredentialV3{ 2000 Type: IssueCredentialMsgTypeV3, 2001 }) 2002 2003 msg.SetID(uuid.New().String()) 2004 2005 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 2006 require.NoError(t, err) 2007 2008 action := <-ch 2009 2010 properties, ok := action.Properties.(*eventProps) 2011 require.True(t, ok) 2012 require.NotEmpty(t, properties.PIID()) 2013 require.Equal(t, properties.MyDID(), Alice) 2014 require.Equal(t, properties.TheirDID(), Bob) 2015 2016 action.Stop(errors.New("invalid credential")) 2017 2018 select { 2019 case <-done: 2020 return 2021 case <-time.After(time.Second): 2022 t.Error("timeout") 2023 } 2024 }) 2025 2026 t.Run("Receive Ack message", func(t *testing.T) { 2027 store, _, provider := initMocks(ctrl) 2028 2029 done := make(chan struct{}) 2030 2031 store.EXPECT().Get(gomock.Any()).Return([]byte("credential-issued"), nil) 2032 store.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 2033 defer close(done) 2034 2035 require.Equal(t, "done", string(name)) 2036 2037 return nil 2038 }) 2039 2040 svc, err := New(provider) 2041 require.NoError(t, err) 2042 2043 require.NoError(t, svc.RegisterActionEvent(make(chan service.DIDCommAction))) 2044 2045 msg := service.NewDIDCommMsgMap(model.AckV2{ 2046 Type: AckMsgTypeV3, 2047 }) 2048 2049 msg.SetID(uuid.New().String()) 2050 2051 _, err = svc.HandleInbound(msg, service.NewDIDCommContext(Alice, Bob, nil)) 2052 require.NoError(t, err) 2053 2054 select { 2055 case <-done: 2056 return 2057 case <-time.After(time.Second): 2058 t.Error("timeout") 2059 } 2060 }) 2061 2062 t.Run("Invalid state transition", func(t *testing.T) { 2063 store, _, provider := initMocks(ctrl) 2064 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 2065 2066 svc, err := New(provider) 2067 require.NoError(t, err) 2068 2069 ch := make(chan service.DIDCommAction, 1) 2070 require.NoError(t, svc.RegisterActionEvent(ch)) 2071 2072 chState := make(chan service.StateMsg, 2) 2073 require.NoError(t, svc.RegisterMsgEvent(chState)) 2074 2075 _, err = svc.HandleInbound(service.NewDIDCommMsgMap(model.ProblemReportV2{ 2076 Type: ProblemReportMsgTypeV3, 2077 }), service.EmptyDIDCommContext()) 2078 require.Contains(t, fmt.Sprintf("%v", err), "doHandle: invalid state transition") 2079 }) 2080 } 2081 2082 func TestService_HandleOutbound(t *testing.T) { 2083 ctrl := gomock.NewController(t) 2084 defer ctrl.Finish() 2085 2086 const errMsg = "error" 2087 2088 initMocks := func(controller *gomock.Controller) ( 2089 store *storageMocks.MockStore, 2090 messenger *serviceMocks.MockMessenger, 2091 provider *issuecredentialMocks.MockProvider, 2092 ) { 2093 store = storageMocks.NewMockStore(controller) 2094 2095 storeProvider := storageMocks.NewMockProvider(controller) 2096 storeProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil).AnyTimes() 2097 storeProvider.EXPECT().SetStoreConfig(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 2098 2099 messenger = serviceMocks.NewMockMessenger(controller) 2100 2101 provider = issuecredentialMocks.NewMockProvider(controller) 2102 provider.EXPECT().Messenger().Return(messenger).AnyTimes() 2103 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 2104 2105 return store, messenger, provider 2106 } 2107 2108 t.Run("DB error", func(t *testing.T) { 2109 store, _, provider := initMocks(ctrl) 2110 2111 store.EXPECT().Get(gomock.Any()).Return(nil, errors.New(errMsg)) 2112 2113 svc, err := New(provider) 2114 require.NoError(t, err) 2115 2116 msg := service.NewDIDCommMsgMap(struct{}{}) 2117 msg.SetID(uuid.New().String()) 2118 2119 piid, err := svc.HandleOutbound(msg, "", "") 2120 require.Empty(t, piid) 2121 require.Contains(t, fmt.Sprintf("%v", err), "doHandle: getCurrentStateNameAndPIID: currentStateName: "+errMsg) 2122 }) 2123 2124 t.Run("Unrecognized msgType", func(t *testing.T) { 2125 store, _, provider := initMocks(ctrl) 2126 2127 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound).AnyTimes() 2128 2129 svc, err := New(provider) 2130 require.NoError(t, err) 2131 2132 piid, err := svc.HandleOutbound(service.NewDIDCommMsgMap(ProposeCredentialV2{ 2133 Type: "none", 2134 }), "", "") 2135 require.Empty(t, piid) 2136 require.Contains(t, fmt.Sprintf("%v", err), "doHandle: nextState: unrecognized msgType: none") 2137 }) 2138 2139 t.Run("Send Propose Credential", func(t *testing.T) { 2140 store, messenger, provider := initMocks(ctrl) 2141 2142 done := make(chan struct{}) 2143 2144 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound) 2145 store.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 2146 require.Equal(t, "proposal-sent", string(name)) 2147 2148 return nil 2149 }) 2150 2151 svc, err := New(provider) 2152 require.NoError(t, err) 2153 2154 msg := service.NewDIDCommMsgMap(ProposeCredentialV2{ 2155 Type: ProposeCredentialMsgTypeV2, 2156 }) 2157 2158 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()). 2159 Do(func(msg service.DIDCommMsgMap, myDID, theirDID string, opts ...service.Opt) error { 2160 defer close(done) 2161 2162 return nil 2163 }) 2164 2165 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2166 require.NoError(t, err) 2167 require.NotEmpty(t, piid) 2168 2169 select { 2170 case <-done: 2171 return 2172 case <-time.After(time.Second): 2173 t.Error("timeout") 2174 } 2175 }) 2176 2177 t.Run("Send Propose Credential with error", func(t *testing.T) { 2178 store, messenger, provider := initMocks(ctrl) 2179 2180 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound).AnyTimes() 2181 store.EXPECT().Put(gomock.Any(), gomock.Any()).Return(nil) 2182 2183 svc, err := New(provider) 2184 require.NoError(t, err) 2185 2186 msg := service.NewDIDCommMsgMap(ProposeCredentialV2{ 2187 Type: ProposeCredentialMsgTypeV2, 2188 }) 2189 2190 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()).Return(errors.New(errMsg)) 2191 2192 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2193 require.Empty(t, piid) 2194 require.Contains(t, fmt.Sprintf("%v", err), "action proposal-sent: "+errMsg) 2195 }) 2196 2197 t.Run("Send Offer Credential", func(t *testing.T) { 2198 store, messenger, provider := initMocks(ctrl) 2199 2200 done := make(chan struct{}) 2201 2202 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound).AnyTimes() 2203 store.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 2204 require.Equal(t, "offer-sent", string(name)) 2205 2206 return nil 2207 }) 2208 2209 svc, err := New(provider) 2210 require.NoError(t, err) 2211 2212 msg := service.NewDIDCommMsgMap(OfferCredentialV2{ 2213 Type: OfferCredentialMsgTypeV2, 2214 }) 2215 2216 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()). 2217 Do(func(msg service.DIDCommMsgMap, myDID, theirDID string, opts ...service.Opt) error { 2218 defer close(done) 2219 2220 return nil 2221 }) 2222 2223 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2224 require.NotEmpty(t, piid) 2225 require.NoError(t, err) 2226 2227 select { 2228 case <-done: 2229 return 2230 case <-time.After(time.Second): 2231 t.Error("timeout") 2232 } 2233 }) 2234 2235 t.Run("Send Offer with error", func(t *testing.T) { 2236 store, messenger, provider := initMocks(ctrl) 2237 2238 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound).AnyTimes() 2239 store.EXPECT().Put(gomock.Any(), gomock.Any()).Return(nil) 2240 2241 svc, err := New(provider) 2242 require.NoError(t, err) 2243 2244 msg := service.NewDIDCommMsgMap(OfferCredentialV2{ 2245 Type: OfferCredentialMsgTypeV2, 2246 }) 2247 2248 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()).Return(errors.New(errMsg)) 2249 2250 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2251 require.Empty(t, piid) 2252 require.Contains(t, fmt.Sprintf("%v", err), "action offer-sent: "+errMsg) 2253 }) 2254 2255 t.Run("Send Invitation Credential", func(t *testing.T) { 2256 store, messenger, provider := initMocks(ctrl) 2257 2258 done := make(chan struct{}) 2259 2260 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound).AnyTimes() 2261 store.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 2262 require.Equal(t, "request-sent", string(name)) 2263 2264 return nil 2265 }) 2266 2267 svc, err := New(provider) 2268 require.NoError(t, err) 2269 2270 msg := service.NewDIDCommMsgMap(RequestCredentialV2{ 2271 Type: RequestCredentialMsgTypeV2, 2272 }) 2273 2274 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()). 2275 Do(func(msg service.DIDCommMsgMap, myDID, theirDID string, opts ...service.Opt) error { 2276 defer close(done) 2277 2278 return nil 2279 }) 2280 2281 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2282 require.NotEmpty(t, piid) 2283 require.NoError(t, err) 2284 2285 select { 2286 case <-done: 2287 return 2288 case <-time.After(time.Second): 2289 t.Error("timeout") 2290 } 2291 }) 2292 2293 t.Run("Send Invitation with error", func(t *testing.T) { 2294 store, messenger, provider := initMocks(ctrl) 2295 2296 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound).AnyTimes() 2297 store.EXPECT().Put(gomock.Any(), gomock.Any()).Return(nil) 2298 2299 svc, err := New(provider) 2300 require.NoError(t, err) 2301 2302 msg := service.NewDIDCommMsgMap(RequestCredentialV2{ 2303 Type: RequestCredentialMsgTypeV2, 2304 }) 2305 2306 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()).Return(errors.New(errMsg)) 2307 2308 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2309 require.Empty(t, piid) 2310 require.Contains(t, fmt.Sprintf("%v", err), "action request-sent: "+errMsg) 2311 }) 2312 } 2313 2314 func TestService_HandleOutboundV3(t *testing.T) { 2315 ctrl := gomock.NewController(t) 2316 defer ctrl.Finish() 2317 2318 const errMsg = "error" 2319 2320 initMocks := func(controller *gomock.Controller) ( 2321 store *storageMocks.MockStore, 2322 messenger *serviceMocks.MockMessenger, 2323 provider *issuecredentialMocks.MockProvider, 2324 ) { 2325 store = storageMocks.NewMockStore(controller) 2326 store.EXPECT().Get(gomock.Any()).Return(nil, storage.ErrDataNotFound).AnyTimes() 2327 2328 storeProvider := storageMocks.NewMockProvider(controller) 2329 storeProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil).AnyTimes() 2330 storeProvider.EXPECT().SetStoreConfig(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 2331 2332 messenger = serviceMocks.NewMockMessenger(controller) 2333 2334 provider = issuecredentialMocks.NewMockProvider(controller) 2335 provider.EXPECT().Messenger().Return(messenger).AnyTimes() 2336 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 2337 2338 return store, messenger, provider 2339 } 2340 2341 t.Run("Send Propose Credential", func(t *testing.T) { 2342 store, messenger, provider := initMocks(ctrl) 2343 2344 done := make(chan struct{}) 2345 2346 store.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 2347 require.Equal(t, "proposal-sent", string(name)) 2348 2349 return nil 2350 }) 2351 2352 svc, err := New(provider) 2353 require.NoError(t, err) 2354 2355 msg := service.NewDIDCommMsgMap(ProposeCredentialV3{ 2356 Type: ProposeCredentialMsgTypeV3, 2357 }) 2358 2359 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()). 2360 Do(func(msg service.DIDCommMsgMap, myDID, theirDID string, opts ...service.Opt) error { 2361 defer close(done) 2362 2363 return nil 2364 }) 2365 2366 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2367 require.NotEmpty(t, piid) 2368 require.NoError(t, err) 2369 2370 select { 2371 case <-done: 2372 return 2373 case <-time.After(time.Second): 2374 t.Error("timeout") 2375 } 2376 }) 2377 2378 t.Run("Send Propose Credential with error", func(t *testing.T) { 2379 store, messenger, provider := initMocks(ctrl) 2380 2381 store.EXPECT().Put(gomock.Any(), gomock.Any()).Return(nil) 2382 2383 svc, err := New(provider) 2384 require.NoError(t, err) 2385 2386 msg := service.NewDIDCommMsgMap(ProposeCredentialV3{ 2387 Type: ProposeCredentialMsgTypeV3, 2388 }) 2389 2390 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()).Return(errors.New(errMsg)) 2391 2392 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2393 require.Empty(t, piid) 2394 require.Contains(t, fmt.Sprintf("%v", err), "action proposal-sent: "+errMsg) 2395 }) 2396 2397 t.Run("Send Offer Credential", func(t *testing.T) { 2398 store, messenger, provider := initMocks(ctrl) 2399 2400 done := make(chan struct{}) 2401 2402 store.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 2403 require.Equal(t, "offer-sent", string(name)) 2404 2405 return nil 2406 }) 2407 2408 svc, err := New(provider) 2409 require.NoError(t, err) 2410 2411 msg := service.NewDIDCommMsgMap(OfferCredentialV3{ 2412 Type: OfferCredentialMsgTypeV3, 2413 }) 2414 2415 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()). 2416 Do(func(msg service.DIDCommMsgMap, myDID, theirDID string, opts ...service.Opt) error { 2417 defer close(done) 2418 2419 return nil 2420 }) 2421 2422 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2423 require.NotEmpty(t, piid) 2424 require.NoError(t, err) 2425 2426 select { 2427 case <-done: 2428 return 2429 case <-time.After(time.Second): 2430 t.Error("timeout") 2431 } 2432 }) 2433 2434 t.Run("Send Offer with error", func(t *testing.T) { 2435 store, messenger, provider := initMocks(ctrl) 2436 2437 store.EXPECT().Put(gomock.Any(), gomock.Any()).Return(nil) 2438 2439 svc, err := New(provider) 2440 require.NoError(t, err) 2441 2442 msg := service.NewDIDCommMsgMap(OfferCredentialV3{ 2443 Type: OfferCredentialMsgTypeV3, 2444 }) 2445 2446 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()).Return(errors.New(errMsg)) 2447 2448 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2449 require.Empty(t, piid) 2450 require.Contains(t, fmt.Sprintf("%v", err), "action offer-sent: "+errMsg) 2451 }) 2452 2453 t.Run("Send Invitation Credential", func(t *testing.T) { 2454 store, messenger, provider := initMocks(ctrl) 2455 2456 done := make(chan struct{}) 2457 2458 store.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(_ string, name []byte) error { 2459 require.Equal(t, "request-sent", string(name)) 2460 2461 return nil 2462 }) 2463 2464 svc, err := New(provider) 2465 require.NoError(t, err) 2466 2467 msg := service.NewDIDCommMsgMap(RequestCredentialV3{ 2468 Type: RequestCredentialMsgTypeV3, 2469 }) 2470 2471 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()). 2472 Do(func(msg service.DIDCommMsgMap, myDID, theirDID string, opts ...service.Opt) error { 2473 defer close(done) 2474 2475 return nil 2476 }) 2477 2478 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2479 require.NotEmpty(t, piid) 2480 require.NoError(t, err) 2481 2482 select { 2483 case <-done: 2484 return 2485 case <-time.After(time.Second): 2486 t.Error("timeout") 2487 } 2488 }) 2489 2490 t.Run("Send Invitation with error", func(t *testing.T) { 2491 store, messenger, provider := initMocks(ctrl) 2492 2493 store.EXPECT().Put(gomock.Any(), gomock.Any()).Return(nil) 2494 2495 svc, err := New(provider) 2496 require.NoError(t, err) 2497 2498 msg := service.NewDIDCommMsgMap(RequestCredentialV3{ 2499 Type: RequestCredentialMsgTypeV3, 2500 }) 2501 2502 messenger.EXPECT().Send(msg, Alice, Bob, gomock.Any()).Return(errors.New(errMsg)) 2503 2504 piid, err := svc.HandleOutbound(msg, Alice, Bob) 2505 require.Empty(t, piid) 2506 require.Contains(t, fmt.Sprintf("%v", err), "action request-sent: "+errMsg) 2507 }) 2508 } 2509 2510 func TestService_ActionContinue(t *testing.T) { 2511 t.Run("Error transitional payload (get)", func(t *testing.T) { 2512 ctrl := gomock.NewController(t) 2513 defer ctrl.Finish() 2514 2515 const errMsg = "error" 2516 2517 store := storageMocks.NewMockStore(ctrl) 2518 store.EXPECT().Get(gomock.Any()).Return(nil, errors.New(errMsg)) 2519 2520 storeProvider := storageMocks.NewMockProvider(ctrl) 2521 storeProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil).AnyTimes() 2522 storeProvider.EXPECT().SetStoreConfig(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 2523 2524 messenger := serviceMocks.NewMockMessenger(ctrl) 2525 2526 provider := issuecredentialMocks.NewMockProvider(ctrl) 2527 provider.EXPECT().Messenger().Return(messenger) 2528 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 2529 2530 svc, err := New(provider) 2531 require.NoError(t, err) 2532 2533 err = svc.ActionContinue("piID", nil) 2534 require.Contains(t, fmt.Sprintf("%v", err), "get transitional payload: store get: "+errMsg) 2535 }) 2536 2537 t.Run("Error transitional payload (delete)", func(t *testing.T) { 2538 ctrl := gomock.NewController(t) 2539 defer ctrl.Finish() 2540 2541 const errMsg = "error" 2542 2543 store := storageMocks.NewMockStore(ctrl) 2544 store.EXPECT().Get(gomock.Any()).Return([]byte(`{}`), nil) 2545 store.EXPECT().Delete(gomock.Any()).Return(errors.New(errMsg)) 2546 2547 storeProvider := storageMocks.NewMockProvider(ctrl) 2548 storeProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil).AnyTimes() 2549 storeProvider.EXPECT().SetStoreConfig(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 2550 2551 messenger := serviceMocks.NewMockMessenger(ctrl) 2552 2553 provider := issuecredentialMocks.NewMockProvider(ctrl) 2554 provider.EXPECT().Messenger().Return(messenger) 2555 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 2556 2557 svc, err := New(provider) 2558 require.NoError(t, err) 2559 2560 err = svc.ActionContinue("piID") 2561 require.Contains(t, fmt.Sprintf("%v", err), "delete transitional payload: "+errMsg) 2562 }) 2563 } 2564 2565 func TestService_ActionStop(t *testing.T) { 2566 t.Run("Error transitional payload (get)", func(t *testing.T) { 2567 ctrl := gomock.NewController(t) 2568 defer ctrl.Finish() 2569 2570 const errMsg = "error" 2571 2572 store := storageMocks.NewMockStore(ctrl) 2573 store.EXPECT().Get(gomock.Any()).Return(nil, errors.New(errMsg)) 2574 2575 storeProvider := storageMocks.NewMockProvider(ctrl) 2576 storeProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil).AnyTimes() 2577 storeProvider.EXPECT().SetStoreConfig(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 2578 2579 messenger := serviceMocks.NewMockMessenger(ctrl) 2580 2581 provider := issuecredentialMocks.NewMockProvider(ctrl) 2582 provider.EXPECT().Messenger().Return(messenger) 2583 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 2584 2585 svc, err := New(provider) 2586 require.NoError(t, err) 2587 2588 err = svc.ActionStop("piID", nil) 2589 require.Contains(t, fmt.Sprintf("%v", err), "get transitional payload: store get: "+errMsg) 2590 }) 2591 2592 t.Run("Error transitional payload (delete)", func(t *testing.T) { 2593 ctrl := gomock.NewController(t) 2594 defer ctrl.Finish() 2595 2596 const errMsg = "error" 2597 2598 store := storageMocks.NewMockStore(ctrl) 2599 store.EXPECT().Get(gomock.Any()).Return([]byte(`{}`), nil) 2600 store.EXPECT().Delete(gomock.Any()).Return(errors.New(errMsg)) 2601 2602 storeProvider := storageMocks.NewMockProvider(ctrl) 2603 storeProvider.EXPECT().OpenStore(gomock.Any()).Return(store, nil).AnyTimes() 2604 storeProvider.EXPECT().SetStoreConfig(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 2605 2606 messenger := serviceMocks.NewMockMessenger(ctrl) 2607 2608 provider := issuecredentialMocks.NewMockProvider(ctrl) 2609 provider.EXPECT().Messenger().Return(messenger) 2610 provider.EXPECT().StorageProvider().Return(storeProvider).AnyTimes() 2611 2612 svc, err := New(provider) 2613 require.NoError(t, err) 2614 2615 err = svc.ActionStop("piID", nil) 2616 require.Contains(t, fmt.Sprintf("%v", err), "delete transitional payload: "+errMsg) 2617 }) 2618 } 2619 2620 func Test_stateFromName(t *testing.T) { 2621 require.Equal(t, stateFromName(stateNameStart, SpecV2), &start{}) 2622 require.Equal(t, stateFromName(stateNameAbandoning, SpecV2), &abandoning{V: SpecV2}) 2623 require.Equal(t, stateFromName(stateNameDone, SpecV2), &done{V: SpecV2}) 2624 require.Equal(t, stateFromName(stateNameProposalReceived, SpecV2), &proposalReceived{V: SpecV2}) 2625 require.Equal(t, stateFromName(stateNameOfferSent, SpecV2), &offerSent{V: SpecV2}) 2626 require.Equal(t, stateFromName(stateNameRequestReceived, SpecV2), &requestReceived{V: SpecV2}) 2627 require.Equal(t, stateFromName(stateNameCredentialIssued, SpecV2), &credentialIssued{V: SpecV2}) 2628 require.Equal(t, stateFromName(stateNameProposalSent, SpecV2), &proposalSent{V: SpecV2}) 2629 require.Equal(t, stateFromName(stateNameOfferReceived, SpecV2), &offerReceived{V: SpecV2}) 2630 require.Equal(t, stateFromName(stateNameRequestSent, SpecV2), &requestSent{V: SpecV2}) 2631 require.Equal(t, stateFromName(stateNameCredentialReceived, SpecV2), &credentialReceived{V: SpecV2}) 2632 require.Equal(t, stateFromName("unknown", SpecV2), &noOp{}) 2633 } 2634 2635 func Test_nextState(t *testing.T) { 2636 next, err := nextState(service.NewDIDCommMsgMap(ProposeCredentialV2{ 2637 Type: ProposeCredentialMsgTypeV2, 2638 }), true) 2639 require.NoError(t, err) 2640 require.Equal(t, next, &proposalSent{V: SpecV2}) 2641 2642 next, err = nextState(service.NewDIDCommMsgMap(ProposeCredentialV2{ 2643 Type: ProposeCredentialMsgTypeV2, 2644 }), false) 2645 require.NoError(t, err) 2646 require.Equal(t, next, &proposalReceived{V: SpecV2}) 2647 2648 next, err = nextState(service.NewDIDCommMsgMap(OfferCredentialV2{ 2649 Type: OfferCredentialMsgTypeV2, 2650 }), true) 2651 require.NoError(t, err) 2652 require.Equal(t, next, &offerSent{V: SpecV2}) 2653 2654 next, err = nextState(service.NewDIDCommMsgMap(OfferCredentialV2{ 2655 Type: OfferCredentialMsgTypeV2, 2656 }), false) 2657 require.NoError(t, err) 2658 require.Equal(t, next, &offerReceived{V: SpecV2}) 2659 2660 next, err = nextState(service.NewDIDCommMsgMap(RequestCredentialV2{ 2661 Type: RequestCredentialMsgTypeV2, 2662 }), true) 2663 require.NoError(t, err) 2664 require.Equal(t, next, &requestSent{V: SpecV2}) 2665 2666 next, err = nextState(service.NewDIDCommMsgMap(RequestCredentialV2{ 2667 Type: RequestCredentialMsgTypeV2, 2668 }), false) 2669 require.NoError(t, err) 2670 require.Equal(t, next, &requestReceived{V: SpecV2}) 2671 2672 next, err = nextState(service.NewDIDCommMsgMap(IssueCredentialV2{ 2673 Type: IssueCredentialMsgTypeV2, 2674 }), false) 2675 require.NoError(t, err) 2676 require.Equal(t, next, &credentialReceived{V: SpecV2}) 2677 2678 next, err = nextState(service.NewDIDCommMsgMap(model.Ack{ 2679 Type: AckMsgTypeV2, 2680 }), false) 2681 require.NoError(t, err) 2682 require.Equal(t, next, &done{V: SpecV2}) 2683 2684 next, err = nextState(service.NewDIDCommMsgMap(model.ProblemReport{ 2685 Type: ProblemReportMsgTypeV2, 2686 }), false) 2687 require.NoError(t, err) 2688 require.Equal(t, next, &abandoning{V: SpecV2}) 2689 2690 next, err = nextState(service.NewDIDCommMsgMap(struct{}{}), false) 2691 require.Error(t, err) 2692 require.Nil(t, next) 2693 } 2694 2695 func TestService_Name(t *testing.T) { 2696 require.Equal(t, (*Service).Name(nil), Name) 2697 } 2698 2699 func TestService_Accept(t *testing.T) { 2700 require.True(t, (*Service).Accept(nil, ProposeCredentialMsgTypeV2)) 2701 require.True(t, (*Service).Accept(nil, OfferCredentialMsgTypeV2)) 2702 require.True(t, (*Service).Accept(nil, RequestCredentialMsgTypeV2)) 2703 require.True(t, (*Service).Accept(nil, IssueCredentialMsgTypeV2)) 2704 require.True(t, (*Service).Accept(nil, AckMsgTypeV2)) 2705 require.True(t, (*Service).Accept(nil, ProblemReportMsgTypeV2)) 2706 require.False(t, (*Service).Accept(nil, "unknown")) 2707 } 2708 2709 func TestService_canTriggerActionEvents(t *testing.T) { 2710 require.True(t, canTriggerActionEvents(service.NewDIDCommMsgMap(ProposeCredentialV2{ 2711 Type: ProposeCredentialMsgTypeV2, 2712 }))) 2713 2714 require.True(t, canTriggerActionEvents(service.NewDIDCommMsgMap(OfferCredentialV2{ 2715 Type: OfferCredentialMsgTypeV2, 2716 }))) 2717 2718 require.True(t, canTriggerActionEvents(service.NewDIDCommMsgMap(IssueCredentialV2{ 2719 Type: IssueCredentialMsgTypeV2, 2720 }))) 2721 2722 require.True(t, canTriggerActionEvents(service.NewDIDCommMsgMap(RequestCredentialV2{ 2723 Type: RequestCredentialMsgTypeV2, 2724 }))) 2725 2726 require.False(t, canTriggerActionEvents(service.NewDIDCommMsgMap(struct{}{}))) 2727 }