flamingo.me/flamingo-commerce/v3@v3.11.0/cart/application/cartService_test.go (about) 1 package application_test 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "testing" 8 9 "flamingo.me/flamingo/v3/core/auth" 10 "github.com/go-test/deep" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/mock" 13 "github.com/stretchr/testify/require" 14 15 mocks2 "flamingo.me/flamingo-commerce/v3/cart/domain/cart/mocks" 16 mocks3 "flamingo.me/flamingo-commerce/v3/cart/domain/validation/mocks" 17 "flamingo.me/flamingo-commerce/v3/cart/infrastructure" 18 "flamingo.me/flamingo-commerce/v3/product/domain/mocks" 19 20 "flamingo.me/flamingo-commerce/v3/cart/domain/decorator" 21 "flamingo.me/flamingo-commerce/v3/cart/domain/events" 22 "flamingo.me/flamingo-commerce/v3/cart/domain/placeorder" 23 "flamingo.me/flamingo-commerce/v3/cart/domain/validation" 24 25 "flamingo.me/flamingo/v3/framework/flamingo" 26 "flamingo.me/flamingo/v3/framework/web" 27 28 cartApplication "flamingo.me/flamingo-commerce/v3/cart/application" 29 cartDomain "flamingo.me/flamingo-commerce/v3/cart/domain/cart" 30 productDomain "flamingo.me/flamingo-commerce/v3/product/domain" 31 ) 32 33 func TestCartService_DeleteSavedSessionGuestCartID(t *testing.T) { 34 type fields struct { 35 CartReceiverService *cartApplication.CartReceiverService 36 ProductService productDomain.ProductService 37 Logger flamingo.Logger 38 EventPublisher events.EventPublisher 39 EventRouter flamingo.EventRouter 40 RestrictionService *validation.RestrictionService 41 config *struct { 42 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 43 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 44 } 45 DeliveryInfoBuilder cartDomain.DeliveryInfoBuilder 46 CartCache cartApplication.CartCache 47 PlaceOrderService placeorder.Service 48 } 49 type args struct { 50 session *web.Session 51 } 52 tests := []struct { 53 name string 54 fields fields 55 args args 56 wantErr bool 57 valuesCleared bool 58 }{ 59 { 60 name: "basic clearing of guest cart session value", 61 fields: fields{ 62 CartReceiverService: func() *cartApplication.CartReceiverService { 63 result := &cartApplication.CartReceiverService{} 64 result.Inject( 65 new(MockGuestCartServiceAdapter), 66 new(MockCustomerCartService), 67 func() *decorator.DecoratedCartFactory { 68 result := &decorator.DecoratedCartFactory{} 69 result.Inject( 70 &MockProductService{}, 71 flamingo.NullLogger{}, 72 ) 73 74 return result 75 }(), 76 nil, 77 flamingo.NullLogger{}, 78 new(MockEventRouter), 79 &struct { 80 CartCache cartApplication.CartCache `inject:",optional"` 81 }{ 82 CartCache: new(MockCartCache), 83 }, 84 ) 85 return result 86 }(), 87 ProductService: &MockProductService{}, 88 Logger: flamingo.NullLogger{}, 89 EventPublisher: new(MockEventPublisher), 90 config: &struct { 91 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 92 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 93 }{ 94 DefaultDeliveryCode: "default_delivery_code", 95 DeleteEmptyDelivery: false, 96 }, 97 DeliveryInfoBuilder: new(MockDeliveryInfoBuilder), 98 CartCache: new(MockCartCache), 99 }, 100 args: args{ 101 session: web.EmptySession().Store(cartApplication.GuestCartSessionKey, "some_guest_id"), 102 }, 103 wantErr: false, 104 valuesCleared: true, 105 }, 106 } 107 108 for _, tt := range tests { 109 t.Run(tt.name, func(t *testing.T) { 110 cs := &cartApplication.CartService{} 111 cs.Inject( 112 tt.fields.CartReceiverService, 113 tt.fields.ProductService, 114 tt.fields.EventPublisher, 115 tt.fields.EventRouter, 116 tt.fields.DeliveryInfoBuilder, 117 tt.fields.RestrictionService, 118 nil, 119 tt.fields.Logger, 120 tt.fields.config, 121 nil, 122 ) 123 124 err := cs.DeleteSavedSessionGuestCartID(tt.args.session) 125 126 if (err != nil) != tt.wantErr { 127 t.Errorf("CartService.DeleteSavedSessionGuestCartID() error = %v, wantErr %v", err, tt.wantErr) 128 129 return 130 } 131 132 if tt.valuesCleared == true { 133 if len(tt.args.session.Keys()) > 0 { 134 t.Error("Session Values should be empty, but aren't") 135 } 136 } 137 }) 138 } 139 } 140 141 func TestCartService_AdjustItemsToRestrictedQty(t *testing.T) { 142 type fields struct { 143 CartReceiverService *cartApplication.CartReceiverService 144 ProductService productDomain.ProductService 145 Logger flamingo.Logger 146 EventPublisher *MockEventPublisher 147 EventRouter *MockEventRouter 148 RestrictionService *validation.RestrictionService 149 config *struct { 150 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 151 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 152 } 153 DeliveryInfoBuilder cartDomain.DeliveryInfoBuilder 154 CartCache cartApplication.CartCache 155 PlaceOrderService placeorder.Service 156 } 157 type args struct { 158 ctx context.Context 159 session *web.Session 160 } 161 tests := []struct { 162 name string 163 fields fields 164 args args 165 want cartApplication.QtyAdjustmentResults 166 }{ 167 { 168 name: "restrictors higher than qty dont reduce qty", 169 fields: fields{ 170 CartReceiverService: func() *cartApplication.CartReceiverService { 171 result := &cartApplication.CartReceiverService{} 172 result.Inject( 173 new(MockGuestCartServiceWithModifyBehaviour), 174 new(MockCustomerCartService), 175 func() *decorator.DecoratedCartFactory { 176 result := &decorator.DecoratedCartFactory{} 177 result.Inject( 178 &MockProductService{}, 179 flamingo.NullLogger{}, 180 ) 181 182 return result 183 }(), 184 nil, 185 flamingo.NullLogger{}, 186 new(MockEventRouter), 187 &struct { 188 CartCache cartApplication.CartCache `inject:",optional"` 189 }{ 190 CartCache: new(MockCartWithItemCache), 191 }, 192 ) 193 return result 194 }(), 195 ProductService: &MockProductService{}, 196 Logger: flamingo.NullLogger{}, 197 EventRouter: new(MockEventRouter), 198 EventPublisher: new(MockEventPublisher), 199 config: &struct { 200 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 201 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 202 }{ 203 DefaultDeliveryCode: "default_delivery_code", 204 DeleteEmptyDelivery: false, 205 }, 206 DeliveryInfoBuilder: new(MockDeliveryInfoBuilder), 207 CartCache: new(MockCartWithItemCache), 208 RestrictionService: func() *validation.RestrictionService { 209 rs := &validation.RestrictionService{} 210 rs.Inject( 211 []validation.MaxQuantityRestrictor{ 212 &MockRestrictor{IsRestricted: true, MaxQty: 10, DifferenceQty: 0}, 213 }, 214 ) 215 return rs 216 }(), 217 }, 218 args: args{ 219 ctx: context.Background(), 220 session: web.EmptySession().Store(cartApplication.GuestCartSessionKey, "some_guest_id"), 221 }, 222 want: cartApplication.QtyAdjustmentResults{}, 223 }, 224 { 225 name: "restrictors lower than qty reduce qty", 226 fields: fields{ 227 CartReceiverService: func() *cartApplication.CartReceiverService { 228 result := &cartApplication.CartReceiverService{} 229 result.Inject( 230 new(MockGuestCartServiceWithModifyBehaviour), 231 new(MockCustomerCartService), 232 func() *decorator.DecoratedCartFactory { 233 result := &decorator.DecoratedCartFactory{} 234 result.Inject( 235 &MockProductService{}, 236 flamingo.NullLogger{}, 237 ) 238 239 return result 240 }(), 241 nil, 242 flamingo.NullLogger{}, 243 new(MockEventRouter), 244 &struct { 245 CartCache cartApplication.CartCache `inject:",optional"` 246 }{ 247 CartCache: new(MockCartWithItemCache), 248 }, 249 ) 250 return result 251 }(), 252 ProductService: &MockProductService{}, 253 Logger: flamingo.NullLogger{}, 254 EventRouter: new(MockEventRouter), 255 EventPublisher: new(MockEventPublisher), 256 config: &struct { 257 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 258 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 259 }{ 260 DefaultDeliveryCode: "default_delivery_code", 261 DeleteEmptyDelivery: false, 262 }, 263 DeliveryInfoBuilder: new(MockDeliveryInfoBuilder), 264 CartCache: new(MockCartWithItemCache), 265 RestrictionService: func() *validation.RestrictionService { 266 rs := &validation.RestrictionService{} 267 rs.Inject( 268 []validation.MaxQuantityRestrictor{ 269 &MockRestrictor{IsRestricted: true, MaxQty: 5, DifferenceQty: -2}, 270 }, 271 ) 272 return rs 273 }(), 274 }, 275 args: args{ 276 ctx: context.Background(), 277 session: web.EmptySession().Store(cartApplication.GuestCartSessionKey, "some_guest_id"), 278 }, 279 want: cartApplication.QtyAdjustmentResults{ 280 cartApplication.QtyAdjustmentResult{ 281 OriginalItem: cartDomain.Item{ 282 ID: "mock_item", 283 Qty: 7, 284 }, 285 DeliveryCode: "default_delivery_code", 286 WasDeleted: false, 287 RestrictionResult: &validation.RestrictionResult{ 288 IsRestricted: true, 289 MaxAllowed: 5, 290 RemainingDifference: -2, 291 RestrictorName: "", 292 }, 293 NewQty: 5, 294 }, 295 }, 296 }, 297 { 298 name: "maxAllowed of 0 deletes item", 299 fields: fields{ 300 CartReceiverService: func() *cartApplication.CartReceiverService { 301 result := &cartApplication.CartReceiverService{} 302 result.Inject( 303 new(MockGuestCartServiceWithModifyBehaviour), 304 new(MockCustomerCartService), 305 func() *decorator.DecoratedCartFactory { 306 result := &decorator.DecoratedCartFactory{} 307 result.Inject( 308 &MockProductService{}, 309 flamingo.NullLogger{}, 310 ) 311 312 return result 313 }(), 314 nil, 315 flamingo.NullLogger{}, 316 new(MockEventRouter), 317 &struct { 318 CartCache cartApplication.CartCache `inject:",optional"` 319 }{ 320 CartCache: new(MockCartWithItemCache), 321 }, 322 ) 323 return result 324 }(), 325 ProductService: &MockProductService{}, 326 Logger: flamingo.NullLogger{}, 327 EventRouter: new(MockEventRouter), 328 EventPublisher: new(MockEventPublisher), 329 config: &struct { 330 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 331 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 332 }{ 333 DefaultDeliveryCode: "default_delivery_code", 334 DeleteEmptyDelivery: false, 335 }, 336 DeliveryInfoBuilder: new(MockDeliveryInfoBuilder), 337 CartCache: new(MockCartWithItemCache), 338 RestrictionService: func() *validation.RestrictionService { 339 rs := &validation.RestrictionService{} 340 rs.Inject( 341 []validation.MaxQuantityRestrictor{ 342 &MockRestrictor{IsRestricted: true, MaxQty: 0, DifferenceQty: -7}, 343 }, 344 ) 345 return rs 346 }(), 347 }, 348 args: args{ 349 ctx: context.Background(), 350 session: web.EmptySession().Store(cartApplication.GuestCartSessionKey, "some_guest_id"), 351 }, 352 want: cartApplication.QtyAdjustmentResults{ 353 cartApplication.QtyAdjustmentResult{ 354 OriginalItem: cartDomain.Item{ 355 ID: "mock_item", 356 Qty: 7, 357 }, 358 DeliveryCode: "default_delivery_code", 359 WasDeleted: true, 360 RestrictionResult: &validation.RestrictionResult{ 361 IsRestricted: true, 362 MaxAllowed: 0, 363 RemainingDifference: -7, 364 RestrictorName: "", 365 }, 366 NewQty: 0, 367 }, 368 }, 369 }, 370 } 371 372 for _, tt := range tests { 373 t.Run(tt.name, func(t *testing.T) { 374 cs := &cartApplication.CartService{} 375 cs.Inject( 376 tt.fields.CartReceiverService, 377 tt.fields.ProductService, 378 tt.fields.EventPublisher, 379 tt.fields.EventRouter, 380 tt.fields.DeliveryInfoBuilder, 381 tt.fields.RestrictionService, 382 nil, 383 tt.fields.Logger, 384 tt.fields.config, 385 nil, 386 ) 387 got, _ := cs.AdjustItemsToRestrictedQty(tt.args.ctx, tt.args.session) 388 389 if diff := deep.Equal(got, tt.want); diff != nil { 390 t.Errorf("CartService.AdjustItemsToRestrictedQty() got!=want, diff: %#v", diff) 391 } 392 393 }) 394 } 395 } 396 397 func TestCartService_ReserveOrderIDAndSave(t *testing.T) { 398 type fields struct { 399 CartReceiverService *cartApplication.CartReceiverService 400 ProductService productDomain.ProductService 401 Logger flamingo.Logger 402 EventPublisher events.EventPublisher 403 EventRouter flamingo.EventRouter 404 RestrictionService *validation.RestrictionService 405 config *struct { 406 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 407 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 408 } 409 DeliveryInfoBuilder cartDomain.DeliveryInfoBuilder 410 CartCache cartApplication.CartCache 411 PlaceOrderService placeorder.Service 412 } 413 414 type args struct { 415 ctx context.Context 416 session *web.Session 417 } 418 419 tests := []struct { 420 name string 421 fields fields 422 args args 423 want string 424 }{ 425 { 426 name: "reserve order id, reserved before", 427 fields: fields{ 428 CartReceiverService: func() *cartApplication.CartReceiverService { 429 result := &cartApplication.CartReceiverService{} 430 result.Inject( 431 new(MockGuestCartServiceWithModifyBehaviour), 432 new(MockCustomerCartService), 433 func() *decorator.DecoratedCartFactory { 434 result := &decorator.DecoratedCartFactory{} 435 result.Inject( 436 &MockProductService{}, 437 flamingo.NullLogger{}, 438 ) 439 440 return result 441 }(), 442 nil, 443 flamingo.NullLogger{}, 444 new(MockEventRouter), 445 &struct { 446 CartCache cartApplication.CartCache `inject:",optional"` 447 }{ 448 CartCache: new(MockCartWithItemCacheWithAdditionalData), 449 }, 450 ) 451 return result 452 }(), 453 ProductService: &MockProductService{}, 454 Logger: flamingo.NullLogger{}, 455 EventRouter: new(MockEventRouter), 456 EventPublisher: new(MockEventPublisher), 457 config: &struct { 458 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 459 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 460 }{ 461 DefaultDeliveryCode: "default_delivery_code", 462 DeleteEmptyDelivery: false, 463 }, 464 DeliveryInfoBuilder: new(MockDeliveryInfoBuilder), 465 CartCache: new(MockCartWithItemCacheWithAdditionalData), 466 RestrictionService: nil, 467 PlaceOrderService: &MockPlaceOrderService{}, 468 }, 469 args: args{ 470 ctx: context.Background(), 471 session: web.EmptySession().Store(cartApplication.GuestCartSessionKey, "some_guest_id"), 472 }, 473 want: "201910251128792ZM", 474 }, 475 { 476 name: "reserved order id, not reserved before", 477 fields: fields{ 478 CartReceiverService: func() *cartApplication.CartReceiverService { 479 result := &cartApplication.CartReceiverService{} 480 result.Inject( 481 new(MockGuestCartServiceWithModifyBehaviour), 482 new(MockCustomerCartService), 483 func() *decorator.DecoratedCartFactory { 484 result := &decorator.DecoratedCartFactory{} 485 result.Inject( 486 &MockProductService{}, 487 flamingo.NullLogger{}, 488 ) 489 490 return result 491 }(), 492 nil, 493 flamingo.NullLogger{}, 494 new(MockEventRouter), 495 &struct { 496 CartCache cartApplication.CartCache `inject:",optional"` 497 }{ 498 CartCache: new(MockCartWithItemCache), 499 }, 500 ) 501 return result 502 }(), 503 ProductService: &MockProductService{}, 504 Logger: flamingo.NullLogger{}, 505 EventPublisher: new(MockEventPublisher), 506 EventRouter: new(MockEventRouter), 507 config: &struct { 508 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 509 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 510 }{ 511 DefaultDeliveryCode: "default_delivery_code", 512 DeleteEmptyDelivery: false, 513 }, 514 DeliveryInfoBuilder: new(MockDeliveryInfoBuilder), 515 CartCache: new(MockCartWithItemCache), 516 RestrictionService: nil, 517 PlaceOrderService: &MockPlaceOrderService{}, 518 }, 519 args: args{ 520 ctx: context.Background(), 521 session: web.EmptySession().Store(cartApplication.GuestCartSessionKey, "some_guest_id"), 522 }, 523 want: "201910251128788TD", 524 }, 525 } 526 527 for _, tt := range tests { 528 t.Run(tt.name, func(t *testing.T) { 529 cs := &cartApplication.CartService{} 530 cs.Inject( 531 tt.fields.CartReceiverService, 532 tt.fields.ProductService, 533 tt.fields.EventPublisher, 534 tt.fields.EventRouter, 535 tt.fields.DeliveryInfoBuilder, 536 tt.fields.RestrictionService, 537 nil, 538 tt.fields.Logger, 539 tt.fields.config, 540 &struct { 541 CartValidator validation.Validator `inject:",optional"` 542 ItemValidator validation.ItemValidator `inject:",optional"` 543 CartCache cartApplication.CartCache `inject:",optional"` 544 PlaceOrderService placeorder.Service `inject:",optional"` 545 }{ 546 PlaceOrderService: tt.fields.PlaceOrderService, 547 }, 548 ) 549 550 got, _ := cs.ReserveOrderIDAndSave(tt.args.ctx, tt.args.session) 551 552 reservedOrderIDFromGot := got.AdditionalData.ReservedOrderID 553 if reservedOrderIDFromGot != tt.want { 554 t.Errorf("CartService.ReserveOrderIDAndSave() got!=want, got: %s, want: %s", reservedOrderIDFromGot, tt.want) 555 } 556 }) 557 } 558 } 559 560 func TestCartService_ForceReserveOrderIDAndSave(t *testing.T) { 561 type fields struct { 562 CartReceiverService *cartApplication.CartReceiverService 563 ProductService productDomain.ProductService 564 Logger flamingo.Logger 565 EventPublisher events.EventPublisher 566 EventRouter flamingo.EventRouter 567 RestrictionService *validation.RestrictionService 568 config *struct { 569 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 570 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 571 } 572 DeliveryInfoBuilder cartDomain.DeliveryInfoBuilder 573 CartCache cartApplication.CartCache 574 PlaceOrderService placeorder.Service 575 } 576 577 type args struct { 578 ctx context.Context 579 session *web.Session 580 } 581 582 tests := []struct { 583 name string 584 fields fields 585 args args 586 want string 587 }{ 588 { 589 name: "force reserved order id, reserved before", 590 fields: fields{ 591 CartReceiverService: func() *cartApplication.CartReceiverService { 592 result := &cartApplication.CartReceiverService{} 593 result.Inject( 594 new(MockGuestCartServiceWithModifyBehaviour), 595 new(MockCustomerCartService), 596 func() *decorator.DecoratedCartFactory { 597 result := &decorator.DecoratedCartFactory{} 598 result.Inject( 599 &MockProductService{}, 600 flamingo.NullLogger{}, 601 ) 602 603 return result 604 }(), 605 nil, 606 flamingo.NullLogger{}, 607 new(MockEventRouter), 608 &struct { 609 CartCache cartApplication.CartCache `inject:",optional"` 610 }{ 611 CartCache: new(MockCartWithItemCacheWithAdditionalData), 612 }, 613 ) 614 return result 615 }(), 616 ProductService: &MockProductService{}, 617 Logger: flamingo.NullLogger{}, 618 EventPublisher: new(MockEventPublisher), 619 EventRouter: new(MockEventRouter), 620 config: &struct { 621 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 622 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 623 }{ 624 DefaultDeliveryCode: "default_delivery_code", 625 DeleteEmptyDelivery: false, 626 }, 627 DeliveryInfoBuilder: new(MockDeliveryInfoBuilder), 628 CartCache: new(MockCartWithItemCacheWithAdditionalData), 629 RestrictionService: nil, 630 PlaceOrderService: &MockPlaceOrderService{}, 631 }, 632 args: args{ 633 ctx: context.Background(), 634 session: web.EmptySession().Store(cartApplication.GuestCartSessionKey, "some_guest_id"), 635 }, 636 want: "201910251128788TD", 637 }, 638 { 639 name: "force reserved order id, not reserved before", 640 fields: fields{ 641 CartReceiverService: func() *cartApplication.CartReceiverService { 642 result := &cartApplication.CartReceiverService{} 643 result.Inject( 644 new(MockGuestCartServiceWithModifyBehaviour), 645 new(MockCustomerCartService), 646 func() *decorator.DecoratedCartFactory { 647 result := &decorator.DecoratedCartFactory{} 648 result.Inject( 649 &MockProductService{}, 650 flamingo.NullLogger{}, 651 ) 652 653 return result 654 }(), 655 nil, 656 flamingo.NullLogger{}, 657 new(MockEventRouter), 658 &struct { 659 CartCache cartApplication.CartCache `inject:",optional"` 660 }{ 661 CartCache: new(MockCartWithItemCache), 662 }, 663 ) 664 return result 665 }(), 666 ProductService: &MockProductService{}, 667 Logger: flamingo.NullLogger{}, 668 EventPublisher: new(MockEventPublisher), 669 EventRouter: new(MockEventRouter), 670 config: &struct { 671 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 672 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 673 }{ 674 DefaultDeliveryCode: "default_delivery_code", 675 DeleteEmptyDelivery: false, 676 }, 677 DeliveryInfoBuilder: new(MockDeliveryInfoBuilder), 678 CartCache: new(MockCartWithItemCache), 679 RestrictionService: nil, 680 PlaceOrderService: &MockPlaceOrderService{}, 681 }, 682 args: args{ 683 ctx: context.Background(), 684 session: web.EmptySession().Store(cartApplication.GuestCartSessionKey, "some_guest_id"), 685 }, 686 want: "201910251128788TD", 687 }, 688 } 689 690 for _, tt := range tests { 691 t.Run(tt.name, func(t *testing.T) { 692 cs := &cartApplication.CartService{} 693 cs.Inject( 694 tt.fields.CartReceiverService, 695 tt.fields.ProductService, 696 tt.fields.EventPublisher, 697 tt.fields.EventRouter, 698 tt.fields.DeliveryInfoBuilder, 699 tt.fields.RestrictionService, 700 nil, 701 tt.fields.Logger, 702 tt.fields.config, 703 &struct { 704 CartValidator validation.Validator `inject:",optional"` 705 ItemValidator validation.ItemValidator `inject:",optional"` 706 CartCache cartApplication.CartCache `inject:",optional"` 707 PlaceOrderService placeorder.Service `inject:",optional"` 708 }{ 709 PlaceOrderService: tt.fields.PlaceOrderService, 710 }, 711 ) 712 713 got, _ := cs.ForceReserveOrderIDAndSave(tt.args.ctx, tt.args.session) 714 715 reservedOrderIDFromGot := got.AdditionalData.ReservedOrderID 716 if reservedOrderIDFromGot != tt.want { 717 t.Errorf("CartService.ReserveOrderIDAndSave() got!=want, got: %s, want: %s", reservedOrderIDFromGot, tt.want) 718 } 719 }) 720 } 721 } 722 723 type ( 724 MockGuestCartServiceWithModifyBehaviour struct { 725 cart *cartDomain.Cart 726 } 727 ) 728 729 func (m *MockGuestCartServiceWithModifyBehaviour) GetCart(ctx context.Context, cartID string) (*cartDomain.Cart, error) { 730 if m.cart != nil { 731 return m.cart, nil 732 } 733 734 return &cartDomain.Cart{ 735 ID: "mock_guest_cart", 736 }, nil 737 } 738 739 func (m *MockGuestCartServiceWithModifyBehaviour) GetNewCart(ctx context.Context) (*cartDomain.Cart, error) { 740 return &cartDomain.Cart{ 741 ID: "mock_guest_cart", 742 }, nil 743 } 744 745 func (m *MockGuestCartServiceWithModifyBehaviour) GetModifyBehaviour(context.Context) (cartDomain.ModifyBehaviour, error) { 746 cob := &infrastructure.DefaultCartBehaviour{} 747 748 storage := &infrastructure.InMemoryCartStorage{} 749 storage.Inject() 750 751 cart := cartDomain.Cart{ 752 ID: "mock_guest_cart", 753 Deliveries: []cartDomain.Delivery{ 754 { 755 DeliveryInfo: cartDomain.DeliveryInfo{Code: "default_delivery_code"}, 756 Cartitems: []cartDomain.Item{ 757 { 758 ID: "mock_item", 759 Qty: 7, 760 }, 761 }, 762 }, 763 }, 764 } 765 766 _ = storage.StoreCart(context.Background(), &cart) 767 768 cob.Inject( 769 storage, 770 &MockProductService{}, 771 flamingo.NullLogger{}, 772 nil, 773 nil, 774 nil, 775 ) 776 777 return cob, nil 778 } 779 780 func (m *MockGuestCartServiceWithModifyBehaviour) RestoreCart(ctx context.Context, cart cartDomain.Cart) (*cartDomain.Cart, error) { 781 return &cart, nil 782 } 783 784 type ( 785 MockCartWithItemCache struct { 786 CachedCart cartDomain.Cart 787 } 788 ) 789 790 func (m *MockCartWithItemCache) GetCart(context.Context, *web.Session, cartApplication.CartCacheIdentifier) (*cartDomain.Cart, error) { 791 m.CachedCart = cartDomain.Cart{ 792 ID: "mock_guest_cart", 793 Deliveries: []cartDomain.Delivery{ 794 { 795 DeliveryInfo: cartDomain.DeliveryInfo{Code: "default_delivery_code"}, 796 Cartitems: []cartDomain.Item{ 797 { 798 ID: "mock_item", 799 Qty: 7, 800 }, 801 }, 802 }, 803 }, 804 } 805 806 return &m.CachedCart, nil 807 } 808 809 func (m *MockCartWithItemCache) CacheCart(ctx context.Context, s *web.Session, cci cartApplication.CartCacheIdentifier, cart *cartDomain.Cart) error { 810 m.CachedCart = *cart 811 return nil 812 } 813 814 func (m *MockCartWithItemCache) Invalidate(context.Context, *web.Session, cartApplication.CartCacheIdentifier) error { 815 return nil 816 } 817 818 func (m *MockCartWithItemCache) Delete(context.Context, *web.Session, cartApplication.CartCacheIdentifier) error { 819 return nil 820 } 821 822 func (m *MockCartWithItemCache) DeleteAll(context.Context, *web.Session) error { 823 return nil 824 } 825 826 func (m *MockCartWithItemCache) BuildIdentifier(context.Context, *web.Session) (cartApplication.CartCacheIdentifier, error) { 827 return cartApplication.CartCacheIdentifier{}, nil 828 } 829 830 type ( 831 MockCartWithItemCacheWithAdditionalData struct { 832 CachedCart cartDomain.Cart 833 } 834 ) 835 836 func (m *MockCartWithItemCacheWithAdditionalData) GetCart(context.Context, *web.Session, cartApplication.CartCacheIdentifier) (*cartDomain.Cart, error) { 837 m.CachedCart = cartDomain.Cart{ 838 ID: "mock_guest_cart", 839 Deliveries: []cartDomain.Delivery{ 840 { 841 DeliveryInfo: cartDomain.DeliveryInfo{Code: "default_delivery_code"}, 842 Cartitems: []cartDomain.Item{ 843 { 844 ID: "mock_item", 845 Qty: 7, 846 }, 847 }, 848 }, 849 }, 850 AdditionalData: struct { 851 CustomAttributes map[string]string 852 ReservedOrderID string 853 }{CustomAttributes: nil, ReservedOrderID: "201910251128792ZM"}, 854 } 855 856 return &m.CachedCart, nil 857 } 858 859 func (m *MockCartWithItemCacheWithAdditionalData) CacheCart(ctx context.Context, s *web.Session, cci cartApplication.CartCacheIdentifier, cart *cartDomain.Cart) error { 860 m.CachedCart = *cart 861 return nil 862 } 863 864 func (m *MockCartWithItemCacheWithAdditionalData) Invalidate(context.Context, *web.Session, cartApplication.CartCacheIdentifier) error { 865 return nil 866 } 867 868 func (m *MockCartWithItemCacheWithAdditionalData) Delete(context.Context, *web.Session, cartApplication.CartCacheIdentifier) error { 869 return nil 870 } 871 872 func (m *MockCartWithItemCacheWithAdditionalData) DeleteAll(context.Context, *web.Session) error { 873 return nil 874 } 875 876 func (m *MockCartWithItemCacheWithAdditionalData) BuildIdentifier(context.Context, *web.Session) (cartApplication.CartCacheIdentifier, error) { 877 return cartApplication.CartCacheIdentifier{}, nil 878 } 879 880 type MockRestrictor struct { 881 IsRestricted bool 882 MaxQty int 883 DifferenceQty int 884 } 885 886 func (r *MockRestrictor) Name() string { 887 return "MockRestrictor" 888 } 889 890 func (r *MockRestrictor) Restrict(ctx context.Context, session *web.Session, product productDomain.BasicProduct, currentCart *cartDomain.Cart, deliveryCode string) *validation.RestrictionResult { 891 return &validation.RestrictionResult{ 892 IsRestricted: r.IsRestricted, 893 MaxAllowed: r.MaxQty, 894 RemainingDifference: r.DifferenceQty, 895 } 896 } 897 898 type ( 899 MockPlaceOrderService struct{} 900 ) 901 902 func (mpos *MockPlaceOrderService) PlaceGuestCart(ctx context.Context, cart *cartDomain.Cart, payment *placeorder.Payment) (placeorder.PlacedOrderInfos, error) { 903 return nil, nil 904 } 905 906 func (mpos *MockPlaceOrderService) PlaceCustomerCart(ctx context.Context, identity auth.Identity, cart *cartDomain.Cart, payment *placeorder.Payment) (placeorder.PlacedOrderInfos, error) { 907 return nil, nil 908 } 909 910 func (mpos *MockPlaceOrderService) ReserveOrderID(ctx context.Context, cart *cartDomain.Cart) (string, error) { 911 return "201910251128788TD", nil 912 } 913 914 func (mpos *MockPlaceOrderService) CancelGuestOrder(ctx context.Context, orderInfos placeorder.PlacedOrderInfos) error { 915 return nil 916 } 917 918 func (mpos *MockPlaceOrderService) CancelCustomerOrder(ctx context.Context, orderInfos placeorder.PlacedOrderInfos, identity auth.Identity) error { 919 return nil 920 } 921 922 func TestCartService_CartInEvent(t *testing.T) { 923 // bootstrap cart service 924 cartReceiverService := func() *cartApplication.CartReceiverService { 925 result := &cartApplication.CartReceiverService{} 926 result.Inject( 927 new(MockGuestCartServiceWithModifyBehaviour), 928 new(MockCustomerCartService), 929 func() *decorator.DecoratedCartFactory { 930 result := &decorator.DecoratedCartFactory{} 931 result.Inject( 932 &MockProductService{}, 933 flamingo.NullLogger{}, 934 ) 935 936 return result 937 }(), 938 nil, 939 flamingo.NullLogger{}, 940 new(MockEventRouter), 941 &struct { 942 CartCache cartApplication.CartCache `inject:",optional"` 943 }{ 944 CartCache: new(MockCartWithItemCacheWithAdditionalData), 945 }, 946 ) 947 return result 948 }() 949 productService := &MockProductService{} 950 logger := flamingo.NullLogger{} 951 eventPublisher := new(MockEventPublisher) 952 eventRouter := new(MockEventRouter) 953 eventRouter.On("Dispatch", mock.Anything, mock.Anything, mock.Anything).Return() 954 config := &struct { 955 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 956 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 957 }{ 958 DefaultDeliveryCode: "default_delivery_code", 959 DeleteEmptyDelivery: false, 960 } 961 deliveryInfoBuilder := new(MockDeliveryInfoBuilder) 962 restrictionService := func() *validation.RestrictionService { 963 rs := &validation.RestrictionService{} 964 rs.Inject( 965 []validation.MaxQuantityRestrictor{ 966 &MockRestrictor{}, 967 }, 968 ) 969 return rs 970 }() 971 972 // init cart service with dependencies 973 cartService := cartApplication.CartService{} 974 cartService.Inject( 975 cartReceiverService, 976 productService, 977 eventPublisher, 978 eventRouter, 979 deliveryInfoBuilder, 980 restrictionService, 981 nil, 982 logger, 983 config, 984 nil, 985 ) 986 987 // add product to cart, we expect event to be thrown with updated cart 988 addRequest := cartDomain.AddRequest{ 989 MarketplaceCode: "code-1", 990 Qty: 1, 991 } 992 ctx := context.Background() 993 session := web.EmptySession() 994 _, err := cartService.AddProduct(ctx, session, "default_delivery_code", addRequest) 995 assert.Nil(t, err) 996 // white box tests that event router has been called as expected (once) 997 eventRouter.AssertNumberOfCalls(t, "Dispatch", 1) 998 // white box test that ensures router has been called with expected parameter (add to cart event) 999 // with the expected marketplace code of the item 1000 eventRouter.AssertCalled(t, "Dispatch", mock.Anything, fmt.Sprintf("%T", new(events.AddToCartEvent)), addRequest.MarketplaceCode) 1001 } 1002 1003 func createCartServiceWithDependencies() *cartApplication.CartService { 1004 eventRouter := new(MockEventRouter) 1005 eventRouter.On("Dispatch", mock.Anything, mock.Anything, mock.Anything).Return() 1006 cartCache := new(MockCartCache) 1007 1008 crs := &cartApplication.CartReceiverService{} 1009 crs.Inject(new(MockGuestCartServiceWithModifyBehaviour), 1010 nil, 1011 func() *decorator.DecoratedCartFactory { 1012 result := &decorator.DecoratedCartFactory{} 1013 result.Inject( 1014 &MockProductService{}, 1015 flamingo.NullLogger{}, 1016 ) 1017 1018 return result 1019 }(), 1020 nil, 1021 flamingo.NullLogger{}, 1022 eventRouter, 1023 &struct { 1024 CartCache cartApplication.CartCache `inject:",optional"` 1025 }{ 1026 CartCache: cartCache, 1027 }) 1028 1029 cs := &cartApplication.CartService{} 1030 cs.Inject( 1031 crs, 1032 &MockProductService{}, 1033 new(MockEventPublisher), 1034 eventRouter, 1035 new(MockDeliveryInfoBuilder), 1036 func() *validation.RestrictionService { 1037 rs := &validation.RestrictionService{} 1038 rs.Inject( 1039 []validation.MaxQuantityRestrictor{ 1040 &MockRestrictor{}, 1041 }, 1042 ) 1043 return rs 1044 }(), 1045 nil, 1046 flamingo.NullLogger{}, 1047 &struct { 1048 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 1049 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 1050 }{ 1051 DefaultDeliveryCode: "default_delivery_code", 1052 DeleteEmptyDelivery: false, 1053 }, 1054 &struct { 1055 CartValidator validation.Validator `inject:",optional"` 1056 ItemValidator validation.ItemValidator `inject:",optional"` 1057 CartCache cartApplication.CartCache `inject:",optional"` 1058 PlaceOrderService placeorder.Service `inject:",optional"` 1059 }{ 1060 CartCache: cartCache, 1061 }, 1062 ) 1063 return cs 1064 } 1065 1066 func TestCartService_SetAdditionalData(t *testing.T) { 1067 cs := createCartServiceWithDependencies() 1068 1069 cart, err := cs.UpdateAdditionalData(context.Background(), web.EmptySession(), map[string]string{"test": "data", "foo": "bar"}) 1070 assert.NoError(t, err) 1071 assert.Equal(t, "data", cart.AdditionalData.CustomAttributes["test"]) 1072 assert.Equal(t, "bar", cart.AdditionalData.CustomAttributes["foo"]) 1073 } 1074 1075 func TestCartService_SetAdditionalDataForDelivery(t *testing.T) { 1076 cs := createCartServiceWithDependencies() 1077 1078 ctx := context.Background() 1079 session := web.EmptySession() 1080 addRequest := cartDomain.AddRequest{ 1081 MarketplaceCode: "code-1", 1082 Qty: 1, 1083 } 1084 _, err := cs.AddProduct(ctx, session, "default_delivery_code", addRequest) 1085 assert.Nil(t, err) 1086 cart, err := cs.UpdateDeliveryAdditionalData(ctx, session, "default_delivery_code", map[string]string{"test": "data", "foo": "bar"}) 1087 assert.NoError(t, err) 1088 var deliveryInfo *cartDomain.DeliveryInfo 1089 for _, delivery := range cart.Deliveries { 1090 if delivery.DeliveryInfo.Code == "default_delivery_code" { 1091 deliveryInfo = &delivery.DeliveryInfo 1092 } 1093 } 1094 1095 require.NotNil(t, deliveryInfo) 1096 assert.Equal(t, "data", deliveryInfo.AdditionalData["test"]) 1097 assert.Equal(t, "bar", deliveryInfo.AdditionalData["foo"]) 1098 } 1099 1100 func TestCartService_UpdateItemBundleConfig(t *testing.T) { 1101 t.Parallel() 1102 1103 eventRouter := new(MockEventRouter) 1104 eventRouter.On("Dispatch", mock.Anything, mock.Anything, mock.Anything).Return() 1105 1106 t.Run("error when bundle configuration not provided", func(t *testing.T) { 1107 t.Parallel() 1108 1109 behaviour := &mocks2.ModifyBehaviour{} 1110 behaviour.EXPECT().UpdateItem(mock.Anything, mock.Anything, mock.Anything) 1111 1112 cart := &cartDomain.Cart{ 1113 Deliveries: []cartDomain.Delivery{ 1114 { 1115 Cartitems: []cartDomain.Item{ 1116 { 1117 ID: "fakeID", 1118 MarketplaceCode: "fake", 1119 }, 1120 }, 1121 }, 1122 }, 1123 } 1124 1125 guestCartService := &mocks2.GuestCartService{} 1126 guestCartService.EXPECT().GetModifyBehaviour(mock.Anything).Return(behaviour, nil) 1127 1128 cartReceiverService, _ := getCartReceiverServiceForBundleUpdateTest(cart, guestCartService) 1129 1130 cartService := &cartApplication.CartService{} 1131 cartService.Inject( 1132 cartReceiverService, 1133 &mocks.ProductService{}, 1134 new(MockEventPublisher), 1135 eventRouter, 1136 new(MockDeliveryInfoBuilder), 1137 nil, 1138 nil, 1139 flamingo.NullLogger{}, 1140 &struct { 1141 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 1142 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 1143 }{}, 1144 &struct { 1145 CartValidator validation.Validator `inject:",optional"` 1146 ItemValidator validation.ItemValidator `inject:",optional"` 1147 CartCache cartApplication.CartCache `inject:",optional"` 1148 PlaceOrderService placeorder.Service `inject:",optional"` 1149 }{}, 1150 ) 1151 1152 session := web.EmptySession() 1153 session.Store(cartApplication.GuestCartSessionKey, "fakeCartSession") 1154 1155 updateCommand := cartDomain.ItemUpdateCommand{ItemID: "fakeID"} 1156 1157 err := cartService.UpdateItemBundleConfig(context.Background(), session, updateCommand) 1158 assert.ErrorIs(t, err, cartApplication.ErrBundleConfigNotProvided) 1159 }) 1160 1161 t.Run("error when trying to update item that is not a bundle", func(t *testing.T) { 1162 t.Parallel() 1163 1164 behaviour := &mocks2.ModifyBehaviour{} 1165 behaviour.EXPECT().UpdateItem(mock.Anything, mock.Anything, mock.Anything) 1166 1167 cart := &cartDomain.Cart{ 1168 Deliveries: []cartDomain.Delivery{ 1169 { 1170 Cartitems: []cartDomain.Item{ 1171 { 1172 ID: "fakeID", 1173 MarketplaceCode: "fake", 1174 }, 1175 }, 1176 }, 1177 }, 1178 } 1179 1180 guestCartService := &mocks2.GuestCartService{} 1181 guestCartService.EXPECT().GetModifyBehaviour(mock.Anything).Return(behaviour, nil) 1182 1183 cartReceiverService, _ := getCartReceiverServiceForBundleUpdateTest(cart, guestCartService) 1184 1185 product := productDomain.SimpleProduct{} 1186 1187 productService := &mocks.ProductService{} 1188 productService.EXPECT().Get(mock.Anything, mock.Anything).Return(product, nil) 1189 1190 cartService := &cartApplication.CartService{} 1191 cartService.Inject( 1192 cartReceiverService, 1193 productService, 1194 new(MockEventPublisher), 1195 eventRouter, 1196 new(MockDeliveryInfoBuilder), 1197 nil, 1198 nil, 1199 flamingo.NullLogger{}, 1200 &struct { 1201 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 1202 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 1203 }{}, 1204 &struct { 1205 CartValidator validation.Validator `inject:",optional"` 1206 ItemValidator validation.ItemValidator `inject:",optional"` 1207 CartCache cartApplication.CartCache `inject:",optional"` 1208 PlaceOrderService placeorder.Service `inject:",optional"` 1209 }{}, 1210 ) 1211 1212 session := web.EmptySession() 1213 session.Store(cartApplication.GuestCartSessionKey, "fakeCartSession") 1214 1215 updateCommand := cartDomain.ItemUpdateCommand{ 1216 ItemID: "fakeID", 1217 BundleConfiguration: productDomain.BundleConfiguration{ 1218 "choice1": { 1219 MarketplaceCode: "test", 1220 Qty: 1, 1221 }, 1222 }, 1223 } 1224 1225 err := cartService.UpdateItemBundleConfig(context.Background(), session, updateCommand) 1226 assert.ErrorIs(t, err, cartApplication.ErrProductNotTypeBundle) 1227 }) 1228 1229 t.Run("if item validator is not provided, call update item on cart behaviour", func(t *testing.T) { 1230 t.Parallel() 1231 1232 cart := &cartDomain.Cart{ 1233 Deliveries: []cartDomain.Delivery{ 1234 { 1235 Cartitems: []cartDomain.Item{ 1236 { 1237 ID: "fakeID", 1238 MarketplaceCode: "fake", 1239 }, 1240 }, 1241 }, 1242 }, 1243 } 1244 1245 behaviour := &mocks2.ModifyBehaviour{} 1246 behaviour.EXPECT().UpdateItem(mock.Anything, mock.Anything, mock.Anything).Return(cart, nil, nil) 1247 1248 guestCartService := &mocks2.GuestCartService{} 1249 guestCartService.EXPECT().GetModifyBehaviour(mock.Anything).Return(behaviour, nil) 1250 1251 cartReceiverService, _ := getCartReceiverServiceForBundleUpdateTest(cart, guestCartService) 1252 1253 product := productDomain.BundleProduct{} 1254 1255 productService := &mocks.ProductService{} 1256 productService.EXPECT().Get(mock.Anything, mock.Anything).Return(product, nil) 1257 1258 cartService := &cartApplication.CartService{} 1259 cartService.Inject( 1260 cartReceiverService, 1261 productService, 1262 new(MockEventPublisher), 1263 eventRouter, 1264 new(MockDeliveryInfoBuilder), 1265 nil, 1266 nil, 1267 flamingo.NullLogger{}, 1268 &struct { 1269 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 1270 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 1271 }{}, 1272 &struct { 1273 CartValidator validation.Validator `inject:",optional"` 1274 ItemValidator validation.ItemValidator `inject:",optional"` 1275 CartCache cartApplication.CartCache `inject:",optional"` 1276 PlaceOrderService placeorder.Service `inject:",optional"` 1277 }{}, 1278 ) 1279 1280 session := web.EmptySession() 1281 session.Store(cartApplication.GuestCartSessionKey, "fakeCartSession") 1282 1283 updateCommand := cartDomain.ItemUpdateCommand{ 1284 ItemID: "fakeID", 1285 BundleConfiguration: productDomain.BundleConfiguration{ 1286 "choice1": { 1287 MarketplaceCode: "test", 1288 Qty: 1, 1289 }, 1290 }, 1291 } 1292 1293 err := cartService.UpdateItemBundleConfig(context.Background(), session, updateCommand) 1294 assert.NoError(t, err) 1295 1296 behaviour.MethodCalled("UpdateItem") 1297 }) 1298 1299 t.Run("if item validator does not complain, call update item on cart behaviour", func(t *testing.T) { 1300 t.Parallel() 1301 1302 cart := &cartDomain.Cart{ 1303 Deliveries: []cartDomain.Delivery{ 1304 { 1305 Cartitems: []cartDomain.Item{ 1306 { 1307 ID: "fakeID", 1308 MarketplaceCode: "fake", 1309 }, 1310 }, 1311 }, 1312 }, 1313 } 1314 1315 behaviour := &mocks2.ModifyBehaviour{} 1316 behaviour.EXPECT().UpdateItem(mock.Anything, mock.Anything, mock.Anything).Return(cart, nil, nil) 1317 1318 guestCartService := &mocks2.GuestCartService{} 1319 guestCartService.EXPECT().GetModifyBehaviour(mock.Anything).Return(behaviour, nil) 1320 1321 cartReceiverService, _ := getCartReceiverServiceForBundleUpdateTest(cart, guestCartService) 1322 1323 product := productDomain.BundleProduct{} 1324 1325 productService := &mocks.ProductService{} 1326 productService.EXPECT().Get(mock.Anything, mock.Anything).Return(product, nil) 1327 1328 itemValidator := &mocks3.ItemValidator{} 1329 itemValidator.EXPECT().Validate(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). 1330 Return(nil) 1331 1332 cartService := &cartApplication.CartService{} 1333 cartService.Inject( 1334 cartReceiverService, 1335 productService, 1336 new(MockEventPublisher), 1337 eventRouter, 1338 new(MockDeliveryInfoBuilder), 1339 nil, 1340 nil, 1341 flamingo.NullLogger{}, 1342 &struct { 1343 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 1344 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 1345 }{}, 1346 &struct { 1347 CartValidator validation.Validator `inject:",optional"` 1348 ItemValidator validation.ItemValidator `inject:",optional"` 1349 CartCache cartApplication.CartCache `inject:",optional"` 1350 PlaceOrderService placeorder.Service `inject:",optional"` 1351 }{ 1352 ItemValidator: itemValidator, 1353 }, 1354 ) 1355 1356 session := web.EmptySession() 1357 session.Store(cartApplication.GuestCartSessionKey, "fakeCartSession") 1358 1359 updateCommand := cartDomain.ItemUpdateCommand{ 1360 ItemID: "fakeID", 1361 BundleConfiguration: productDomain.BundleConfiguration{ 1362 "choice1": { 1363 MarketplaceCode: "test", 1364 Qty: 1, 1365 }, 1366 }, 1367 } 1368 1369 err := cartService.UpdateItemBundleConfig(context.Background(), session, updateCommand) 1370 assert.NoError(t, err) 1371 1372 behaviour.MethodCalled("UpdateItem") 1373 }) 1374 1375 t.Run("if item validator fails, return an error and don't call update item on cart behaviour", func(t *testing.T) { 1376 t.Parallel() 1377 1378 validationError := errors.New("some error") 1379 1380 cart := &cartDomain.Cart{ 1381 Deliveries: []cartDomain.Delivery{ 1382 { 1383 Cartitems: []cartDomain.Item{ 1384 { 1385 ID: "fakeID", 1386 MarketplaceCode: "fake", 1387 }, 1388 }, 1389 }, 1390 }, 1391 } 1392 1393 behaviour := &mocks2.ModifyBehaviour{} 1394 behaviour.EXPECT().UpdateItem(mock.Anything, mock.Anything, mock.Anything).Return(cart, nil, nil) 1395 1396 guestCartService := &mocks2.GuestCartService{} 1397 guestCartService.EXPECT().GetModifyBehaviour(mock.Anything).Return(behaviour, nil) 1398 1399 cartReceiverService, _ := getCartReceiverServiceForBundleUpdateTest(cart, guestCartService) 1400 1401 product := productDomain.BundleProduct{} 1402 1403 productService := &mocks.ProductService{} 1404 productService.EXPECT().Get(mock.Anything, mock.Anything).Return(product, nil) 1405 1406 itemValidator := &mocks3.ItemValidator{} 1407 itemValidator.EXPECT().Validate(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). 1408 Return(validationError) 1409 1410 cartService := &cartApplication.CartService{} 1411 cartService.Inject( 1412 cartReceiverService, 1413 productService, 1414 new(MockEventPublisher), 1415 eventRouter, 1416 new(MockDeliveryInfoBuilder), 1417 nil, 1418 nil, 1419 flamingo.NullLogger{}, 1420 &struct { 1421 DefaultDeliveryCode string `inject:"config:commerce.cart.defaultDeliveryCode,optional"` 1422 DeleteEmptyDelivery bool `inject:"config:commerce.cart.deleteEmptyDelivery,optional"` 1423 }{}, 1424 &struct { 1425 CartValidator validation.Validator `inject:",optional"` 1426 ItemValidator validation.ItemValidator `inject:",optional"` 1427 CartCache cartApplication.CartCache `inject:",optional"` 1428 PlaceOrderService placeorder.Service `inject:",optional"` 1429 }{ 1430 ItemValidator: itemValidator, 1431 }, 1432 ) 1433 1434 session := web.EmptySession() 1435 session.Store(cartApplication.GuestCartSessionKey, "fakeCartSession") 1436 1437 updateCommand := cartDomain.ItemUpdateCommand{ 1438 ItemID: "fakeID", 1439 BundleConfiguration: productDomain.BundleConfiguration{ 1440 "choice1": { 1441 MarketplaceCode: "test", 1442 Qty: 1, 1443 }, 1444 }, 1445 } 1446 1447 err := cartService.UpdateItemBundleConfig(context.Background(), session, updateCommand) 1448 assert.ErrorIs(t, err, validationError) 1449 }) 1450 } 1451 1452 func getCartReceiverServiceForBundleUpdateTest(cart *cartDomain.Cart, guestCartService cartDomain.GuestCartService) (*cartApplication.CartReceiverService, *MockCartCache) { 1453 cartCache := new(MockCartCache) 1454 cartCache.CachedCart = cart 1455 1456 return func() (*cartApplication.CartReceiverService, *MockCartCache) { 1457 result := &cartApplication.CartReceiverService{} 1458 result.Inject( 1459 guestCartService, 1460 nil, 1461 func() *decorator.DecoratedCartFactory { 1462 result := &decorator.DecoratedCartFactory{} 1463 result.Inject( 1464 &MockProductService{}, 1465 flamingo.NullLogger{}, 1466 ) 1467 1468 return result 1469 }(), 1470 nil, 1471 flamingo.NullLogger{}, 1472 new(MockEventRouter), 1473 &struct { 1474 CartCache cartApplication.CartCache `inject:",optional"` 1475 }{ 1476 CartCache: cartCache, 1477 }, 1478 ) 1479 return result, cartCache 1480 }() 1481 }